1 #include "Python.h" 2 3 4 #define GET_WEAKREFS_LISTPTR(o) \ 5 ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) 6 7 8 PyDoc_STRVAR(weakref_getweakrefcount__doc__, 9 "getweakrefcount(object) -- return the number of weak references\n" 10 "to 'object'."); 11 12 static PyObject * 13 weakref_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 29 PyDoc_STRVAR(weakref_getweakrefs__doc__, 30 "getweakrefs(object) -- return a list of all weak reference objects\n" 31 "that point to 'object'."); 32 33 static PyObject * 34 weakref_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 60 PyDoc_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 65 static PyObject * 66 weakref_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 79 static PyMethodDef 80 weakref_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 91 PyMODINIT_FUNC 92 init_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