| #include "Python.h" | 
 |  | 
 |  | 
 | #define GET_WEAKREFS_LISTPTR(o) \ | 
 |         ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) | 
 |  | 
 | /*[clinic input] | 
 | module _weakref | 
 | [clinic start generated code]*/ | 
 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ffec73b85846596d]*/ | 
 |  | 
 | #include "clinic/_weakref.c.h" | 
 |  | 
 | /*[clinic input] | 
 |  | 
 | _weakref.getweakrefcount -> Py_ssize_t | 
 |  | 
 |   object: object | 
 |   / | 
 |  | 
 | Return the number of weak references to 'object'. | 
 | [clinic start generated code]*/ | 
 |  | 
 | static Py_ssize_t | 
 | _weakref_getweakrefcount_impl(PyObject *module, PyObject *object) | 
 | /*[clinic end generated code: output=301806d59558ff3e input=cedb69711b6a2507]*/ | 
 | { | 
 |     PyWeakReference **list; | 
 |  | 
 |     if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) | 
 |         return 0; | 
 |  | 
 |     list = GET_WEAKREFS_LISTPTR(object); | 
 |     return _PyWeakref_GetWeakrefCount(*list); | 
 | } | 
 |  | 
 |  | 
 | static int | 
 | is_dead_weakref(PyObject *value) | 
 | { | 
 |     if (!PyWeakref_Check(value)) { | 
 |         PyErr_SetString(PyExc_TypeError, "not a weakref"); | 
 |         return -1; | 
 |     } | 
 |     return PyWeakref_GET_OBJECT(value) == Py_None; | 
 | } | 
 |  | 
 | /*[clinic input] | 
 |  | 
 | _weakref._remove_dead_weakref -> object | 
 |  | 
 |   dct: object(subclass_of='&PyDict_Type') | 
 |   key: object | 
 |   / | 
 |  | 
 | Atomically remove key from dict if it points to a dead weakref. | 
 | [clinic start generated code]*/ | 
 |  | 
 | static PyObject * | 
 | _weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, | 
 |                                    PyObject *key) | 
 | /*[clinic end generated code: output=d9ff53061fcb875c input=19fc91f257f96a1d]*/ | 
 | { | 
 |     if (_PyDict_DelItemIf(dct, key, is_dead_weakref) < 0) { | 
 |         if (PyErr_ExceptionMatches(PyExc_KeyError)) | 
 |             /* This function is meant to allow safe weak-value dicts | 
 |                with GC in another thread (see issue #28427), so it's | 
 |                ok if the key doesn't exist anymore. | 
 |                */ | 
 |             PyErr_Clear(); | 
 |         else | 
 |             return NULL; | 
 |     } | 
 |     Py_RETURN_NONE; | 
 | } | 
 |  | 
 |  | 
 | PyDoc_STRVAR(weakref_getweakrefs__doc__, | 
 | "getweakrefs(object) -- return a list of all weak reference objects\n" | 
 | "that point to 'object'."); | 
 |  | 
 | static PyObject * | 
 | weakref_getweakrefs(PyObject *self, PyObject *object) | 
 | { | 
 |     PyObject *result = NULL; | 
 |  | 
 |     if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { | 
 |         PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); | 
 |         Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); | 
 |  | 
 |         result = PyList_New(count); | 
 |         if (result != NULL) { | 
 |             PyWeakReference *current = *list; | 
 |             Py_ssize_t i; | 
 |             for (i = 0; i < count; ++i) { | 
 |                 PyList_SET_ITEM(result, i, (PyObject *) current); | 
 |                 Py_INCREF(current); | 
 |                 current = current->wr_next; | 
 |             } | 
 |         } | 
 |     } | 
 |     else { | 
 |         result = PyList_New(0); | 
 |     } | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyDoc_STRVAR(weakref_proxy__doc__, | 
 | "proxy(object[, callback]) -- create a proxy object that weakly\n" | 
 | "references 'object'.  'callback', if given, is called with a\n" | 
 | "reference to the proxy when 'object' is about to be finalized."); | 
 |  | 
 | static PyObject * | 
 | weakref_proxy(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *object; | 
 |     PyObject *callback = NULL; | 
 |     PyObject *result = NULL; | 
 |  | 
 |     if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) { | 
 |         result = PyWeakref_NewProxy(object, callback); | 
 |     } | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | static PyMethodDef | 
 | weakref_functions[] =  { | 
 |     _WEAKREF_GETWEAKREFCOUNT_METHODDEF | 
 |     _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF | 
 |     {"getweakrefs",     weakref_getweakrefs,            METH_O, | 
 |      weakref_getweakrefs__doc__}, | 
 |     {"proxy",           weakref_proxy,                  METH_VARARGS, | 
 |      weakref_proxy__doc__}, | 
 |     {NULL, NULL, 0, NULL} | 
 | }; | 
 |  | 
 |  | 
 | static struct PyModuleDef weakrefmodule = { | 
 |     PyModuleDef_HEAD_INIT, | 
 |     "_weakref", | 
 |     "Weak-reference support module.", | 
 |     -1, | 
 |     weakref_functions, | 
 |     NULL, | 
 |     NULL, | 
 |     NULL, | 
 |     NULL | 
 | }; | 
 |  | 
 | PyMODINIT_FUNC | 
 | PyInit__weakref(void) | 
 | { | 
 |     PyObject *m; | 
 |  | 
 |     m = PyModule_Create(&weakrefmodule); | 
 |  | 
 |     if (m != NULL) { | 
 |         Py_INCREF(&_PyWeakref_RefType); | 
 |         PyModule_AddObject(m, "ref", | 
 |                            (PyObject *) &_PyWeakref_RefType); | 
 |         Py_INCREF(&_PyWeakref_RefType); | 
 |         PyModule_AddObject(m, "ReferenceType", | 
 |                            (PyObject *) &_PyWeakref_RefType); | 
 |         Py_INCREF(&_PyWeakref_ProxyType); | 
 |         PyModule_AddObject(m, "ProxyType", | 
 |                            (PyObject *) &_PyWeakref_ProxyType); | 
 |         Py_INCREF(&_PyWeakref_CallableProxyType); | 
 |         PyModule_AddObject(m, "CallableProxyType", | 
 |                            (PyObject *) &_PyWeakref_CallableProxyType); | 
 |     } | 
 |     return m; | 
 | } |