LCOV - code coverage report
Current view: top level - Include/cpython - weakrefobject.h (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 5 6 83.3 %
Date: 2023-03-20 08:15:36 Functions: 1 1 100.0 %
Branches: 1 2 50.0 %

           Branch data     Line data    Source code
       1                 :            : #ifndef Py_CPYTHON_WEAKREFOBJECT_H
       2                 :            : #  error "this header file must not be included directly"
       3                 :            : #endif
       4                 :            : 
       5                 :            : /* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
       6                 :            :  * and CallableProxyType.
       7                 :            :  */
       8                 :            : struct _PyWeakReference {
       9                 :            :     PyObject_HEAD
      10                 :            : 
      11                 :            :     /* The object to which this is a weak reference, or Py_None if none.
      12                 :            :      * Note that this is a stealth reference:  wr_object's refcount is
      13                 :            :      * not incremented to reflect this pointer.
      14                 :            :      */
      15                 :            :     PyObject *wr_object;
      16                 :            : 
      17                 :            :     /* A callable to invoke when wr_object dies, or NULL if none. */
      18                 :            :     PyObject *wr_callback;
      19                 :            : 
      20                 :            :     /* A cache for wr_object's hash code.  As usual for hashes, this is -1
      21                 :            :      * if the hash code isn't known yet.
      22                 :            :      */
      23                 :            :     Py_hash_t hash;
      24                 :            : 
      25                 :            :     /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
      26                 :            :      * terminated list of weak references to it.  These are the list pointers.
      27                 :            :      * If wr_object goes away, wr_object is set to Py_None, and these pointers
      28                 :            :      * have no meaning then.
      29                 :            :      */
      30                 :            :     PyWeakReference *wr_prev;
      31                 :            :     PyWeakReference *wr_next;
      32                 :            :     vectorcallfunc vectorcall;
      33                 :            : };
      34                 :            : 
      35                 :            : PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
      36                 :            : 
      37                 :            : PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
      38                 :            : 
      39                 :     286714 : static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) {
      40                 :            :     PyWeakReference *ref;
      41                 :            :     PyObject *obj;
      42                 :            :     assert(PyWeakref_Check(ref_obj));
      43                 :     286714 :     ref = _Py_CAST(PyWeakReference*, ref_obj);
      44                 :     286714 :     obj = ref->wr_object;
      45                 :            :     // Explanation for the Py_REFCNT() check: when a weakref's target is part
      46                 :            :     // of a long chain of deallocations which triggers the trashcan mechanism,
      47                 :            :     // clearing the weakrefs can be delayed long after the target's refcount
      48                 :            :     // has dropped to zero.  In the meantime, code accessing the weakref will
      49                 :            :     // be able to "see" the target object even though it is supposed to be
      50                 :            :     // unreachable.  See issue gh-60806.
      51         [ +  - ]:     286714 :     if (Py_REFCNT(obj) > 0) {
      52                 :     286714 :         return obj;
      53                 :            :     }
      54                 :          0 :     return Py_None;
      55                 :            : }
      56                 :            : #define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref))

Generated by: LCOV version 1.14