LCOV - code coverage report
Current view: | top level - Modules - _weakref.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 12 | 52 | 23.1 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 2 | 7 | 28.6 %
|  |  | Branches: | 4 | 26 | 15.4 %

               Branch data     Line data    Source code
           1                 :            : #include "Python.h"
           2                 :            : #include "pycore_object.h"   // _PyObject_GET_WEAKREFS_LISTPTR
           3                 :            :
           4                 :            :
           5                 :            : #define GET_WEAKREFS_LISTPTR(o) \
           6                 :            :         ((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o))
           7                 :            :
           8                 :            : /*[clinic input]
           9                 :            : module _weakref
          10                 :            : [clinic start generated code]*/
          11                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ffec73b85846596d]*/
          12                 :            :
          13                 :            : #include "clinic/_weakref.c.h"
          14                 :            :
          15                 :            : /*[clinic input]
          16                 :            :
          17                 :            : _weakref.getweakrefcount -> Py_ssize_t
          18                 :            :
          19                 :            :   object: object
          20                 :            :   /
          21                 :            :
          22                 :            : Return the number of weak references to 'object'.
          23                 :            : [clinic start generated code]*/
          24                 :            :
          25                 :            : static Py_ssize_t
          26                 :          0 : _weakref_getweakrefcount_impl(PyObject *module, PyObject *object)
          27                 :            : /*[clinic end generated code: output=301806d59558ff3e input=cedb69711b6a2507]*/
          28                 :            : {
          29                 :            :     PyWeakReference **list;
          30                 :            :
          31         [ #  # ]:          0 :     if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)))
          32                 :          0 :         return 0;
          33                 :            :
          34                 :          0 :     list = GET_WEAKREFS_LISTPTR(object);
          35                 :          0 :     return _PyWeakref_GetWeakrefCount(*list);
          36                 :            : }
          37                 :            :
          38                 :            :
          39                 :            : static int
          40                 :          0 : is_dead_weakref(PyObject *value)
          41                 :            : {
          42   [ #  #  #  #  :          0 :     if (!PyWeakref_Check(value)) {
                       #  # ]
          43                 :          0 :         PyErr_SetString(PyExc_TypeError, "not a weakref");
          44                 :          0 :         return -1;
          45                 :            :     }
          46                 :          0 :     return PyWeakref_GET_OBJECT(value) == Py_None;
          47                 :            : }
          48                 :            :
          49                 :            : /*[clinic input]
          50                 :            :
          51                 :            : _weakref._remove_dead_weakref -> object
          52                 :            :
          53                 :            :   dct: object(subclass_of='&PyDict_Type')
          54                 :            :   key: object
          55                 :            :   /
          56                 :            :
          57                 :            : Atomically remove key from dict if it points to a dead weakref.
          58                 :            : [clinic start generated code]*/
          59                 :            :
          60                 :            : static PyObject *
          61                 :          0 : _weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct,
          62                 :            :                                    PyObject *key)
          63                 :            : /*[clinic end generated code: output=d9ff53061fcb875c input=19fc91f257f96a1d]*/
          64                 :            : {
          65         [ #  # ]:          0 :     if (_PyDict_DelItemIf(dct, key, is_dead_weakref) < 0) {
          66         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_KeyError))
          67                 :            :             /* This function is meant to allow safe weak-value dicts
          68                 :            :                with GC in another thread (see issue #28427), so it's
          69                 :            :                ok if the key doesn't exist anymore.
          70                 :            :                */
          71                 :          0 :             PyErr_Clear();
          72                 :            :         else
          73                 :          0 :             return NULL;
          74                 :            :     }
          75                 :          0 :     Py_RETURN_NONE;
          76                 :            : }
          77                 :            :
          78                 :            :
          79                 :            : /*[clinic input]
          80                 :            : _weakref.getweakrefs
          81                 :            :     object: object
          82                 :            :     /
          83                 :            :
          84                 :            : Return a list of all weak reference objects pointing to 'object'.
          85                 :            : [clinic start generated code]*/
          86                 :            :
          87                 :            : static PyObject *
          88                 :          0 : _weakref_getweakrefs(PyObject *module, PyObject *object)
          89                 :            : /*[clinic end generated code: output=25c7731d8e011824 input=00c6d0e5d3206693]*/
          90                 :            : {
          91                 :          0 :     PyObject *result = NULL;
          92                 :            :
          93         [ #  # ]:          0 :     if (_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) {
          94                 :          0 :         PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
          95                 :          0 :         Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list);
          96                 :            :
          97                 :          0 :         result = PyList_New(count);
          98         [ #  # ]:          0 :         if (result != NULL) {
          99                 :          0 :             PyWeakReference *current = *list;
         100                 :            :             Py_ssize_t i;
         101         [ #  # ]:          0 :             for (i = 0; i < count; ++i) {
         102                 :          0 :                 PyList_SET_ITEM(result, i, (PyObject *) current);
         103                 :          0 :                 Py_INCREF(current);
         104                 :          0 :                 current = current->wr_next;
         105                 :            :             }
         106                 :            :         }
         107                 :            :     }
         108                 :            :     else {
         109                 :          0 :         result = PyList_New(0);
         110                 :            :     }
         111                 :          0 :     return result;
         112                 :            : }
         113                 :            :
         114                 :            :
         115                 :            : /*[clinic input]
         116                 :            :
         117                 :            : _weakref.proxy
         118                 :            :     object: object
         119                 :            :     callback: object(c_default="NULL") = None
         120                 :            :     /
         121                 :            :
         122                 :            : Create a proxy object that weakly references 'object'.
         123                 :            :
         124                 :            : 'callback', if given, is called with a reference to the
         125                 :            : proxy when 'object' is about to be finalized.
         126                 :            : [clinic start generated code]*/
         127                 :            :
         128                 :            : static PyObject *
         129                 :          0 : _weakref_proxy_impl(PyObject *module, PyObject *object, PyObject *callback)
         130                 :            : /*[clinic end generated code: output=d68fa4ad9ea40519 input=4808adf22fd137e7]*/
         131                 :            : {
         132                 :          0 :     return PyWeakref_NewProxy(object, callback);
         133                 :            : }
         134                 :            :
         135                 :            :
         136                 :            : static PyMethodDef
         137                 :            : weakref_functions[] =  {
         138                 :            :     _WEAKREF_GETWEAKREFCOUNT_METHODDEF
         139                 :            :     _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF
         140                 :            :     _WEAKREF_GETWEAKREFS_METHODDEF
         141                 :            :     _WEAKREF_PROXY_METHODDEF
         142                 :            :     {NULL, NULL, 0, NULL}
         143                 :            : };
         144                 :            :
         145                 :            : static int
         146                 :         26 : weakref_exec(PyObject *module)
         147                 :            : {
         148                 :         26 :     Py_INCREF(&_PyWeakref_RefType);
         149         [ -  + ]:         26 :     if (PyModule_AddObject(module, "ref", (PyObject *) &_PyWeakref_RefType) < 0) {
         150                 :          0 :         Py_DECREF(&_PyWeakref_RefType);
         151                 :          0 :         return -1;
         152                 :            :     }
         153                 :         26 :     Py_INCREF(&_PyWeakref_RefType);
         154         [ -  + ]:         26 :     if (PyModule_AddObject(module, "ReferenceType",
         155                 :            :                            (PyObject *) &_PyWeakref_RefType) < 0) {
         156                 :          0 :         Py_DECREF(&_PyWeakref_RefType);
         157                 :          0 :         return -1;
         158                 :            :     }
         159                 :         26 :     Py_INCREF(&_PyWeakref_ProxyType);
         160         [ -  + ]:         26 :     if (PyModule_AddObject(module, "ProxyType",
         161                 :            :                            (PyObject *) &_PyWeakref_ProxyType) < 0) {
         162                 :          0 :         Py_DECREF(&_PyWeakref_ProxyType);
         163                 :          0 :         return -1;
         164                 :            :     }
         165                 :         26 :     Py_INCREF(&_PyWeakref_CallableProxyType);
         166         [ -  + ]:         26 :     if (PyModule_AddObject(module, "CallableProxyType",
         167                 :            :                            (PyObject *) &_PyWeakref_CallableProxyType) < 0) {
         168                 :          0 :         Py_DECREF(&_PyWeakref_CallableProxyType);
         169                 :          0 :         return -1;
         170                 :            :     }
         171                 :            :
         172                 :         26 :     return 0;
         173                 :            : }
         174                 :            :
         175                 :            : static struct PyModuleDef_Slot weakref_slots[] = {
         176                 :            :     {Py_mod_exec, weakref_exec},
         177                 :            :     {0, NULL}
         178                 :            : };
         179                 :            :
         180                 :            : static struct PyModuleDef weakrefmodule = {
         181                 :            :     PyModuleDef_HEAD_INIT,
         182                 :            :     "_weakref",
         183                 :            :     "Weak-reference support module.",
         184                 :            :     0,
         185                 :            :     weakref_functions,
         186                 :            :     weakref_slots,
         187                 :            :     NULL,
         188                 :            :     NULL,
         189                 :            :     NULL
         190                 :            : };
         191                 :            :
         192                 :            : PyMODINIT_FUNC
         193                 :         26 : PyInit__weakref(void)
         194                 :            : {
         195                 :         26 :     return PyModuleDef_Init(&weakrefmodule);
         196                 :            : }

Generated by: LCOV version 1.14