diff options
| author | thegeorg <[email protected]> | 2024-02-19 02:38:52 +0300 |
|---|---|---|
| committer | thegeorg <[email protected]> | 2024-02-19 02:50:43 +0300 |
| commit | d96fa07134c06472bfee6718b5cfd1679196fc99 (patch) | |
| tree | 31ec344fa9d3ff8dc038692516b6438dfbdb8a2d /contrib/tools/python3/Modules/_weakref.c | |
| parent | 452cf9e068aef7110e35e654c5d47eb80111ef89 (diff) | |
Sync contrib/tools/python3 layout with upstream
* Move src/ subdir contents to the top of the layout
* Rename self-written lib -> lib2 to avoid CaseFolding warning from the VCS
* Regenerate contrib/libs/python proxy-headers accordingly
4ccc62ac1511abcf0fed14ccade38e984e088f1e
Diffstat (limited to 'contrib/tools/python3/Modules/_weakref.c')
| -rw-r--r-- | contrib/tools/python3/Modules/_weakref.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/contrib/tools/python3/Modules/_weakref.c b/contrib/tools/python3/Modules/_weakref.c new file mode 100644 index 00000000000..387b8fa9d0a --- /dev/null +++ b/contrib/tools/python3/Modules/_weakref.c @@ -0,0 +1,197 @@ +#include "Python.h" +#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR + + +#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; +} + + +/*[clinic input] +_weakref.getweakrefs + object: object + / + +Return a list of all weak reference objects pointing to 'object'. +[clinic start generated code]*/ + +static PyObject * +_weakref_getweakrefs(PyObject *module, PyObject *object) +/*[clinic end generated code: output=25c7731d8e011824 input=00c6d0e5d3206693]*/ +{ + 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; +} + + +/*[clinic input] + +_weakref.proxy + object: object + callback: object(c_default="NULL") = None + / + +Create a proxy object that weakly references 'object'. + +'callback', if given, is called with a reference to the +proxy when 'object' is about to be finalized. +[clinic start generated code]*/ + +static PyObject * +_weakref_proxy_impl(PyObject *module, PyObject *object, PyObject *callback) +/*[clinic end generated code: output=d68fa4ad9ea40519 input=4808adf22fd137e7]*/ +{ + return PyWeakref_NewProxy(object, callback); +} + + +static PyMethodDef +weakref_functions[] = { + _WEAKREF_GETWEAKREFCOUNT_METHODDEF + _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF + _WEAKREF_GETWEAKREFS_METHODDEF + _WEAKREF_PROXY_METHODDEF + {NULL, NULL, 0, NULL} +}; + +static int +weakref_exec(PyObject *module) +{ + Py_INCREF(&_PyWeakref_RefType); + if (PyModule_AddObject(module, "ref", (PyObject *) &_PyWeakref_RefType) < 0) { + Py_DECREF(&_PyWeakref_RefType); + return -1; + } + Py_INCREF(&_PyWeakref_RefType); + if (PyModule_AddObject(module, "ReferenceType", + (PyObject *) &_PyWeakref_RefType) < 0) { + Py_DECREF(&_PyWeakref_RefType); + return -1; + } + Py_INCREF(&_PyWeakref_ProxyType); + if (PyModule_AddObject(module, "ProxyType", + (PyObject *) &_PyWeakref_ProxyType) < 0) { + Py_DECREF(&_PyWeakref_ProxyType); + return -1; + } + Py_INCREF(&_PyWeakref_CallableProxyType); + if (PyModule_AddObject(module, "CallableProxyType", + (PyObject *) &_PyWeakref_CallableProxyType) < 0) { + Py_DECREF(&_PyWeakref_CallableProxyType); + return -1; + } + + return 0; +} + +static struct PyModuleDef_Slot weakref_slots[] = { + {Py_mod_exec, weakref_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + +static struct PyModuleDef weakrefmodule = { + PyModuleDef_HEAD_INIT, + "_weakref", + "Weak-reference support module.", + 0, + weakref_functions, + weakref_slots, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__weakref(void) +{ + return PyModuleDef_Init(&weakrefmodule); +} |
