1#include "Python.h" 2 3 4#define GET_WEAKREFS_LISTPTR(o) \ 5 ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) 6 7 8PyDoc_STRVAR(weakref_getweakrefcount__doc__, 9"getweakrefcount(object) -- return the number of weak references\n" 10"to 'object'."); 11 12static PyObject * 13weakref_getweakrefcount(PyObject *self, PyObject *object) 14{ 15 PyObject *result = NULL; 16 17 if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { 18 PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); 19 20 result = PyInt_FromSsize_t(_PyWeakref_GetWeakrefCount(*list)); 21 } 22 else 23 result = PyInt_FromLong(0); 24 25 return result; 26} 27 28 29PyDoc_STRVAR(weakref_getweakrefs__doc__, 30"getweakrefs(object) -- return a list of all weak reference objects\n" 31"that point to 'object'."); 32 33static PyObject * 34weakref_getweakrefs(PyObject *self, PyObject *object) 35{ 36 PyObject *result = NULL; 37 38 if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { 39 PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); 40 Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); 41 42 result = PyList_New(count); 43 if (result != NULL) { 44 PyWeakReference *current = *list; 45 Py_ssize_t i; 46 for (i = 0; i < count; ++i) { 47 PyList_SET_ITEM(result, i, (PyObject *) current); 48 Py_INCREF(current); 49 current = current->wr_next; 50 } 51 } 52 } 53 else { 54 result = PyList_New(0); 55 } 56 return result; 57} 58 59 60PyDoc_STRVAR(weakref_proxy__doc__, 61"proxy(object[, callback]) -- create a proxy object that weakly\n" 62"references 'object'. 'callback', if given, is called with a\n" 63"reference to the proxy when 'object' is about to be finalized."); 64 65static PyObject * 66weakref_proxy(PyObject *self, PyObject *args) 67{ 68 PyObject *object; 69 PyObject *callback = NULL; 70 PyObject *result = NULL; 71 72 if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) { 73 result = PyWeakref_NewProxy(object, callback); 74 } 75 return result; 76} 77 78 79static PyMethodDef 80weakref_functions[] = { 81 {"getweakrefcount", weakref_getweakrefcount, METH_O, 82 weakref_getweakrefcount__doc__}, 83 {"getweakrefs", weakref_getweakrefs, METH_O, 84 weakref_getweakrefs__doc__}, 85 {"proxy", weakref_proxy, METH_VARARGS, 86 weakref_proxy__doc__}, 87 {NULL, NULL, 0, NULL} 88}; 89 90 91PyMODINIT_FUNC 92init_weakref(void) 93{ 94 PyObject *m; 95 96 m = Py_InitModule3("_weakref", weakref_functions, 97 "Weak-reference support module."); 98 if (m != NULL) { 99 Py_INCREF(&_PyWeakref_RefType); 100 PyModule_AddObject(m, "ref", 101 (PyObject *) &_PyWeakref_RefType); 102 Py_INCREF(&_PyWeakref_RefType); 103 PyModule_AddObject(m, "ReferenceType", 104 (PyObject *) &_PyWeakref_RefType); 105 Py_INCREF(&_PyWeakref_ProxyType); 106 PyModule_AddObject(m, "ProxyType", 107 (PyObject *) &_PyWeakref_ProxyType); 108 Py_INCREF(&_PyWeakref_CallableProxyType); 109 PyModule_AddObject(m, "CallableProxyType", 110 (PyObject *) &_PyWeakref_CallableProxyType); 111 } 112} 113