1
+ /* Weak references objects for Python. */
2
+
3
+ #ifndef Py_WEAKREFOBJECT_H
4
+ #define Py_WEAKREFOBJECT_H
5
+ #ifdef __cplusplus
6
+ extern "C" {
7
+ #endif
8
+
9
+
10
+ typedef struct _PyWeakReference PyWeakReference ;
11
+
12
+ /* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
13
+ * and CallableProxyType.
14
+ */
15
+ #ifndef Py_LIMITED_API
16
+ struct _PyWeakReference {
17
+ PyObject_HEAD
18
+
19
+ /* The object to which this is a weak reference, or Py_None if none.
20
+ * Note that this is a stealth reference: wr_object's refcount is
21
+ * not incremented to reflect this pointer.
22
+ */
23
+ PyObject * wr_object ;
24
+
25
+ /* A callable to invoke when wr_object dies, or NULL if none. */
26
+ PyObject * wr_callback ;
27
+
28
+ /* A cache for wr_object's hash code. As usual for hashes, this is -1
29
+ * if the hash code isn't known yet.
30
+ */
31
+ Py_hash_t hash ;
32
+
33
+ /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
34
+ * terminated list of weak references to it. These are the list pointers.
35
+ * If wr_object goes away, wr_object is set to Py_None, and these pointers
36
+ * have no meaning then.
37
+ */
38
+ PyWeakReference * wr_prev ;
39
+ PyWeakReference * wr_next ;
40
+ };
41
+ #endif
42
+
43
+ PyAPI_DATA (PyTypeObject ) _PyWeakref_RefType ;
44
+ PyAPI_DATA (PyTypeObject ) _PyWeakref_ProxyType ;
45
+ PyAPI_DATA (PyTypeObject ) _PyWeakref_CallableProxyType ;
46
+
47
+ #define PyWeakref_CheckRef (op ) PyObject_TypeCheck(op, &_PyWeakref_RefType)
48
+ #define PyWeakref_CheckRefExact (op ) \
49
+ (Py_TYPE(op) == &_PyWeakref_RefType)
50
+ #define PyWeakref_CheckProxy (op ) \
51
+ ((Py_TYPE(op) == &_PyWeakref_ProxyType) || \
52
+ (Py_TYPE(op) == &_PyWeakref_CallableProxyType))
53
+
54
+ #define PyWeakref_Check (op ) \
55
+ (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op))
56
+
57
+
58
+ PyAPI_FUNC (PyObject * ) PyWeakref_NewRef (PyObject * ob ,
59
+ PyObject * callback );
60
+ PyAPI_FUNC (PyObject * ) PyWeakref_NewProxy (PyObject * ob ,
61
+ PyObject * callback );
62
+ PyAPI_FUNC (PyObject * ) PyWeakref_GetObject (PyObject * ref );
63
+
64
+ #ifndef Py_LIMITED_API
65
+ PyAPI_FUNC (Py_ssize_t ) _PyWeakref_GetWeakrefCount (PyWeakReference * head );
66
+
67
+ PyAPI_FUNC (void ) _PyWeakref_ClearRef (PyWeakReference * self );
68
+ #endif
69
+
70
+ /* Explanation for the Py_REFCNT() check: when a weakref's target is part
71
+ of a long chain of deallocations which triggers the trashcan mechanism,
72
+ clearing the weakrefs can be delayed long after the target's refcount
73
+ has dropped to zero. In the meantime, code accessing the weakref will
74
+ be able to "see" the target object even though it is supposed to be
75
+ unreachable. See issue #16602. */
76
+
77
+ #define PyWeakref_GET_OBJECT (ref ) \
78
+ (Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \
79
+ ? ((PyWeakReference *)(ref))->wr_object \
80
+ : Py_None)
81
+
82
+
83
+ #ifdef __cplusplus
84
+ }
85
+ #endif
86
+ #endif /* !Py_WEAKREFOBJECT_H */
0 commit comments