2 #include "structmember.h"
5 typedef struct _PyWeakReference PyWeakReference
;
7 struct _PyWeakReference
{
10 PyObject
*wr_callback
;
12 PyWeakReference
*wr_prev
;
13 PyWeakReference
*wr_next
;
17 #define GET_WEAKREFS_LISTPTR(o) \
18 ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
23 static PyWeakReference
*
26 staticforward PyTypeObject
29 static PyWeakReference
*
32 PyWeakReference
*result
;
34 if (free_list
!= NULL
) {
36 free_list
= result
->wr_next
;
37 result
->ob_type
= &PyWeakReference_Type
;
38 _Py_NewReference((PyObject
*)result
);
41 result
= PyObject_GC_New(PyWeakReference
, &PyWeakReference_Type
);
49 /* This function clears the passed-in reference and removes it from the
50 * list of weak references for the referent. This is the only code that
51 * removes an item from the doubly-linked list of weak references for an
52 * object; it is also responsible for clearing the callback slot.
55 clear_weakref(PyWeakReference
*self
)
57 PyObject
*callback
= self
->wr_callback
;
59 if (self
->wr_object
!= Py_None
) {
60 PyWeakReference
**list
= GET_WEAKREFS_LISTPTR(self
->wr_object
);
63 *list
= self
->wr_next
;
64 self
->wr_object
= Py_None
;
65 self
->wr_callback
= NULL
;
66 if (self
->wr_prev
!= NULL
)
67 self
->wr_prev
->wr_next
= self
->wr_next
;
68 if (self
->wr_next
!= NULL
)
69 self
->wr_next
->wr_prev
= self
->wr_prev
;
78 weakref_dealloc(PyWeakReference
*self
)
80 PyObject_GC_UnTrack((PyObject
*)self
);
82 self
->wr_next
= free_list
;
88 gc_traverse(PyWeakReference
*self
, visitproc visit
, void *arg
)
90 if (self
->wr_callback
!= NULL
)
91 return visit(self
->wr_callback
, arg
);
97 gc_clear(PyWeakReference
*self
)
105 weakref_call(PyWeakReference
*self
, PyObject
*args
, PyObject
*kw
)
107 static char *argnames
[] = {NULL
};
109 if (PyArg_ParseTupleAndKeywords(args
, kw
, ":__call__", argnames
)) {
110 PyObject
*object
= self
->wr_object
;
119 weakref_hash(PyWeakReference
*self
)
121 if (self
->hash
!= -1)
123 if (self
->wr_object
== Py_None
) {
124 PyErr_SetString(PyExc_TypeError
, "weak object has gone away");
127 self
->hash
= PyObject_Hash(self
->wr_object
);
133 weakref_repr(PyWeakReference
*self
)
136 if (self
->wr_object
== Py_None
) {
137 sprintf(buffer
, "<weakref at %lx; dead>",
141 sprintf(buffer
, "<weakref at %#lx; to '%s' at %#lx>",
142 (long)(self
), self
->wr_object
->ob_type
->tp_name
,
143 (long)(self
->wr_object
));
145 return PyString_FromString(buffer
);
148 /* Weak references only support equality, not ordering. Two weak references
149 are equal if the underlying objects are equal. If the underlying object has
150 gone away, they are equal if they are identical. */
153 weakref_richcompare(PyWeakReference
* self
, PyWeakReference
* other
, int op
)
155 if (op
!= Py_EQ
|| self
->ob_type
!= other
->ob_type
) {
156 Py_INCREF(Py_NotImplemented
);
157 return Py_NotImplemented
;
159 if (self
->wr_object
== Py_None
|| other
->wr_object
== Py_None
) {
160 PyObject
*res
= self
==other
? Py_True
: Py_False
;
164 return PyObject_RichCompare(self
->wr_object
, other
->wr_object
, op
);
168 statichere PyTypeObject
169 PyWeakReference_Type
= {
170 PyObject_HEAD_INIT(NULL
)
173 sizeof(PyWeakReference
),
175 (destructor
)weakref_dealloc
,/*tp_dealloc*/
180 (reprfunc
)weakref_repr
, /*tp_repr*/
182 0, /*tp_as_sequence*/
184 (hashfunc
)weakref_hash
, /*tp_hash*/
185 (ternaryfunc
)weakref_call
, /*tp_call*/
190 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_HAVE_RICHCOMPARE
,
192 (traverseproc
)gc_traverse
, /*tp_traverse*/
193 (inquiry
)gc_clear
, /*tp_clear*/
194 (richcmpfunc
)weakref_richcompare
, /*tp_richcompare*/
195 0, /*tp_weaklistoffset*/
200 proxy_checkref(PyWeakReference
*proxy
)
202 if (proxy
->wr_object
== Py_None
) {
203 PyErr_SetString(ReferenceError
,
204 "weakly-referenced object no longer exists");
211 #define WRAP_UNARY(method, generic) \
213 method(PyWeakReference *proxy) { \
214 if (!proxy_checkref(proxy)) { \
217 return generic(proxy->wr_object); \
220 #define WRAP_BINARY(method, generic) \
222 method(PyWeakReference *proxy, PyObject *v) { \
223 if (!proxy_checkref(proxy)) { \
226 return generic(proxy->wr_object, v); \
229 #define WRAP_TERNARY(method, generic) \
231 method(PyWeakReference *proxy, PyObject *v, PyObject *w) { \
232 if (!proxy_checkref(proxy)) { \
235 return generic(proxy->wr_object, v, w); \
241 WRAP_BINARY(proxy_getattr
, PyObject_GetAttr
)
242 WRAP_UNARY(proxy_str
, PyObject_Str
)
243 WRAP_TERNARY(proxy_call
, PyEval_CallObjectWithKeywords
)
246 proxy_print(PyWeakReference
*proxy
, FILE *fp
, int flags
)
248 if (!proxy_checkref(proxy
))
250 return PyObject_Print(proxy
->wr_object
, fp
, flags
);
254 proxy_repr(PyWeakReference
*proxy
)
257 sprintf(buf
, "<weakref at %p to %.100s at %p>", proxy
,
258 proxy
->wr_object
->ob_type
->tp_name
, proxy
->wr_object
);
259 return PyString_FromString(buf
);
264 proxy_setattr(PyWeakReference
*proxy
, PyObject
*name
, PyObject
*value
)
266 if (!proxy_checkref(proxy
))
268 return PyObject_SetAttr(proxy
->wr_object
, name
, value
);
272 proxy_compare(PyWeakReference
*proxy
, PyObject
*v
)
274 if (!proxy_checkref(proxy
))
276 return PyObject_Compare(proxy
->wr_object
, v
);
280 WRAP_BINARY(proxy_add
, PyNumber_Add
)
281 WRAP_BINARY(proxy_sub
, PyNumber_Subtract
)
282 WRAP_BINARY(proxy_mul
, PyNumber_Multiply
)
283 WRAP_BINARY(proxy_div
, PyNumber_Divide
)
284 WRAP_BINARY(proxy_mod
, PyNumber_Remainder
)
285 WRAP_BINARY(proxy_divmod
, PyNumber_Divmod
)
286 WRAP_TERNARY(proxy_pow
, PyNumber_Power
)
287 WRAP_UNARY(proxy_neg
, PyNumber_Negative
)
288 WRAP_UNARY(proxy_pos
, PyNumber_Positive
)
289 WRAP_UNARY(proxy_abs
, PyNumber_Absolute
)
290 WRAP_UNARY(proxy_invert
, PyNumber_Invert
)
291 WRAP_BINARY(proxy_lshift
, PyNumber_Lshift
)
292 WRAP_BINARY(proxy_rshift
, PyNumber_Rshift
)
293 WRAP_BINARY(proxy_and
, PyNumber_And
)
294 WRAP_BINARY(proxy_xor
, PyNumber_Xor
)
295 WRAP_BINARY(proxy_or
, PyNumber_Or
)
296 WRAP_UNARY(proxy_int
, PyNumber_Int
)
297 WRAP_UNARY(proxy_long
, PyNumber_Long
)
298 WRAP_UNARY(proxy_float
, PyNumber_Float
)
299 WRAP_BINARY(proxy_iadd
, PyNumber_InPlaceAdd
)
300 WRAP_BINARY(proxy_isub
, PyNumber_InPlaceSubtract
)
301 WRAP_BINARY(proxy_imul
, PyNumber_InPlaceMultiply
)
302 WRAP_BINARY(proxy_idiv
, PyNumber_InPlaceDivide
)
303 WRAP_BINARY(proxy_imod
, PyNumber_InPlaceRemainder
)
304 WRAP_TERNARY(proxy_ipow
, PyNumber_InPlacePower
)
305 WRAP_BINARY(proxy_ilshift
, PyNumber_InPlaceLshift
)
306 WRAP_BINARY(proxy_irshift
, PyNumber_InPlaceRshift
)
307 WRAP_BINARY(proxy_iand
, PyNumber_InPlaceAnd
)
308 WRAP_BINARY(proxy_ixor
, PyNumber_InPlaceXor
)
309 WRAP_BINARY(proxy_ior
, PyNumber_InPlaceOr
)
312 proxy_nonzero(PyWeakReference
*proxy
)
314 PyObject
*o
= proxy
->wr_object
;
315 if (!proxy_checkref(proxy
))
317 if (o
->ob_type
->tp_as_number
&&
318 o
->ob_type
->tp_as_number
->nb_nonzero
)
319 return (*o
->ob_type
->tp_as_number
->nb_nonzero
)(o
);
327 proxy_slice(PyWeakReference
*proxy
, int i
, int j
)
329 if (!proxy_checkref(proxy
))
331 return PySequence_GetSlice(proxy
->wr_object
, i
, j
);
335 proxy_ass_slice(PyWeakReference
*proxy
, int i
, int j
, PyObject
*value
)
337 if (!proxy_checkref(proxy
))
339 return PySequence_SetSlice(proxy
->wr_object
, i
, j
, value
);
343 proxy_contains(PyWeakReference
*proxy
, PyObject
*value
)
345 if (!proxy_checkref(proxy
))
347 return PySequence_Contains(proxy
->wr_object
, value
);
354 proxy_length(PyWeakReference
*proxy
)
356 if (!proxy_checkref(proxy
))
358 return PyObject_Length(proxy
->wr_object
);
361 WRAP_BINARY(proxy_getitem
, PyObject_GetItem
)
364 proxy_setitem(PyWeakReference
*proxy
, PyObject
*key
, PyObject
*value
)
366 if (!proxy_checkref(proxy
))
368 return PyObject_SetItem(proxy
->wr_object
, key
, value
);
372 static PyNumberMethods proxy_as_number
= {
373 (binaryfunc
)proxy_add
, /*nb_add*/
374 (binaryfunc
)proxy_sub
, /*nb_subtract*/
375 (binaryfunc
)proxy_mul
, /*nb_multiply*/
376 (binaryfunc
)proxy_div
, /*nb_divide*/
377 (binaryfunc
)proxy_mod
, /*nb_remainder*/
378 (binaryfunc
)proxy_divmod
, /*nb_divmod*/
379 (ternaryfunc
)proxy_pow
, /*nb_power*/
380 (unaryfunc
)proxy_neg
, /*nb_negative*/
381 (unaryfunc
)proxy_pos
, /*nb_positive*/
382 (unaryfunc
)proxy_abs
, /*nb_absolute*/
383 (inquiry
)proxy_nonzero
, /*nb_nonzero*/
384 (unaryfunc
)proxy_invert
, /*nb_invert*/
385 (binaryfunc
)proxy_lshift
, /*nb_lshift*/
386 (binaryfunc
)proxy_rshift
, /*nb_rshift*/
387 (binaryfunc
)proxy_and
, /*nb_and*/
388 (binaryfunc
)proxy_xor
, /*nb_xor*/
389 (binaryfunc
)proxy_or
, /*nb_or*/
390 (coercion
)0, /*nb_coerce*/
391 (unaryfunc
)proxy_int
, /*nb_int*/
392 (unaryfunc
)proxy_long
, /*nb_long*/
393 (unaryfunc
)proxy_float
, /*nb_float*/
394 (unaryfunc
)0, /*nb_oct*/
395 (unaryfunc
)0, /*nb_hex*/
396 (binaryfunc
)proxy_iadd
, /*nb_inplace_add*/
397 (binaryfunc
)proxy_isub
, /*nb_inplace_subtract*/
398 (binaryfunc
)proxy_imul
, /*nb_inplace_multiply*/
399 (binaryfunc
)proxy_idiv
, /*nb_inplace_divide*/
400 (binaryfunc
)proxy_imod
, /*nb_inplace_remainder*/
401 (ternaryfunc
)proxy_ipow
, /*nb_inplace_power*/
402 (binaryfunc
)proxy_ilshift
, /*nb_inplace_lshift*/
403 (binaryfunc
)proxy_irshift
, /*nb_inplace_rshift*/
404 (binaryfunc
)proxy_iand
, /*nb_inplace_and*/
405 (binaryfunc
)proxy_ixor
, /*nb_inplace_xor*/
406 (binaryfunc
)proxy_ior
, /*nb_inplace_or*/
409 static PySequenceMethods proxy_as_sequence
= {
410 (inquiry
)proxy_length
, /*sq_length*/
414 (intintargfunc
)proxy_slice
, /*sq_slice*/
416 (intintobjargproc
)proxy_ass_slice
, /*sq_ass_slice*/
417 (objobjproc
)proxy_contains
, /* sq_contains */
420 static PyMappingMethods proxy_as_mapping
= {
421 (inquiry
)proxy_length
, /*mp_length*/
422 (binaryfunc
)proxy_getitem
, /*mp_subscript*/
423 (objobjargproc
)proxy_setitem
, /*mp_ass_subscript*/
429 PyObject_HEAD_INIT(NULL
)
432 sizeof(PyWeakReference
),
435 (destructor
)weakref_dealloc
,/*tp_dealloc*/
436 (printfunc
)proxy_print
, /*tp_print*/
439 (cmpfunc
)proxy_compare
, /*tp_compare*/
440 (unaryfunc
)proxy_repr
, /*tp_repr*/
441 &proxy_as_number
, /*tp_as_number*/
442 &proxy_as_sequence
, /*tp_as_sequence*/
443 &proxy_as_mapping
, /*tp_as_mapping*/
445 (ternaryfunc
)0, /*tp_call*/
446 (unaryfunc
)proxy_str
, /*tp_str*/
447 (getattrofunc
)proxy_getattr
,/*tp_getattro*/
448 (setattrofunc
)proxy_setattr
,/*tp_setattro*/
450 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
451 |Py_TPFLAGS_CHECKTYPES
, /*tp_flags*/
453 (traverseproc
)gc_traverse
, /*tp_traverse*/
454 (inquiry
)gc_clear
, /*tp_clear*/
459 PyWeakCallableProxy_Type
= {
460 PyObject_HEAD_INIT(NULL
)
463 sizeof(PyWeakReference
),
466 (destructor
)weakref_dealloc
,/*tp_dealloc*/
467 (printfunc
)proxy_print
, /*tp_print*/
470 (cmpfunc
)proxy_compare
, /*tp_compare*/
471 (unaryfunc
)proxy_repr
, /*tp_repr*/
472 &proxy_as_number
, /*tp_as_number*/
473 &proxy_as_sequence
, /*tp_as_sequence*/
474 &proxy_as_mapping
, /*tp_as_mapping*/
476 (ternaryfunc
)proxy_call
, /*tp_call*/
477 (unaryfunc
)proxy_str
, /*tp_str*/
478 (getattrofunc
)proxy_getattr
,/*tp_getattro*/
479 (setattrofunc
)proxy_setattr
,/*tp_setattro*/
481 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
482 |Py_TPFLAGS_CHECKTYPES
, /*tp_flags*/
484 (traverseproc
)gc_traverse
, /*tp_traverse*/
485 (inquiry
)gc_clear
, /*tp_clear*/
490 getweakrefcount(PyWeakReference
*head
)
494 while (head
!= NULL
) {
496 head
= head
->wr_next
;
502 static char weakref_getweakrefcount__doc__
[] =
503 "getweakrefcount(object) -- return the number of weak references\n"
507 weakref_getweakrefcount(PyObject
*self
, PyObject
*object
)
509 PyObject
*result
= NULL
;
511 if (PyType_SUPPORTS_WEAKREFS(object
->ob_type
)) {
512 PyWeakReference
**list
= GET_WEAKREFS_LISTPTR(object
);
514 result
= PyInt_FromLong(getweakrefcount(*list
));
517 result
= PyInt_FromLong(0);
523 static char weakref_getweakrefs__doc__
[] =
524 "getweakrefs(object) -- return a list of all weak reference objects\n"
525 "that point to 'object'.";
528 weakref_getweakrefs(PyObject
*self
, PyObject
*object
)
530 PyObject
*result
= NULL
;
532 if (PyType_SUPPORTS_WEAKREFS(object
->ob_type
)) {
533 PyWeakReference
**list
= GET_WEAKREFS_LISTPTR(object
);
534 long count
= getweakrefcount(*list
);
536 result
= PyList_New(count
);
537 if (result
!= NULL
) {
538 PyWeakReference
*current
= *list
;
540 for (i
= 0; i
< count
; ++i
) {
541 PyList_SET_ITEM(result
, i
, (PyObject
*) current
);
543 current
= current
->wr_next
;
548 result
= PyList_New(0);
554 /* Given the head of an object's list of weak references, extract the
555 * two callback-less refs (ref and proxy). Used to determine if the
556 * shared references exist and to determine the back link for newly
557 * inserted references.
560 get_basic_refs(PyWeakReference
*head
,
561 PyWeakReference
**refp
, PyWeakReference
**proxyp
)
566 if (head
!= NULL
&& head
->wr_callback
== NULL
) {
567 if (head
->ob_type
== &PyWeakReference_Type
) {
569 head
= head
->wr_next
;
571 if (head
!= NULL
&& head
->wr_callback
== NULL
) {
573 head
= head
->wr_next
;
578 /* Insert 'newref' in the list after 'prev'. Both must be non-NULL. */
580 insert_after(PyWeakReference
*newref
, PyWeakReference
*prev
)
582 newref
->wr_prev
= prev
;
583 newref
->wr_next
= prev
->wr_next
;
584 if (prev
->wr_next
!= NULL
)
585 prev
->wr_next
->wr_prev
= newref
;
586 prev
->wr_next
= newref
;
589 /* Insert 'newref' at the head of the list; 'list' points to the variable
590 * that stores the head.
593 insert_head(PyWeakReference
*newref
, PyWeakReference
**list
)
595 PyWeakReference
*next
= *list
;
597 newref
->wr_prev
= NULL
;
598 newref
->wr_next
= next
;
600 next
->wr_prev
= newref
;
605 static char weakref_ref__doc__
[] =
606 "new(object[, callback]) -- create a weak reference to 'object';\n"
607 "when 'object' is finalized, 'callback' will be called and passed\n"
608 "a reference to 'object'.";
611 weakref_ref(PyObject
*self
, PyObject
*args
)
614 PyObject
*callback
= NULL
;
615 PyWeakReference
*result
= NULL
;
617 if (PyArg_ParseTuple(args
, "O|O:new", &object
, &callback
)) {
618 PyWeakReference
**list
;
619 PyWeakReference
*ref
, *proxy
;
621 if (!PyType_SUPPORTS_WEAKREFS(object
->ob_type
)) {
622 PyErr_Format(PyExc_TypeError
,
623 "'%s' objects are not weakly referencable",
624 object
->ob_type
->tp_name
);
627 list
= GET_WEAKREFS_LISTPTR(object
);
628 get_basic_refs(*list
, &ref
, &proxy
);
629 if (callback
== NULL
) {
630 /* return existing weak reference if it exists */
634 if (result
== NULL
) {
635 result
= new_weakref();
636 if (result
!= NULL
) {
637 Py_XINCREF(callback
);
638 result
->wr_callback
= callback
;
639 result
->wr_object
= object
;
640 if (callback
== NULL
) {
641 insert_head(result
, list
);
644 PyWeakReference
*prev
= (proxy
== NULL
) ? ref
: proxy
;
647 insert_head(result
, list
);
649 insert_after(result
, prev
);
651 PyObject_GC_Track(result
);
655 return (PyObject
*) result
;
659 static char weakref_proxy__doc__
[] =
660 "proxy(object[, callback]) -- create a proxy object that weakly\n"
661 "references 'object'. 'callback', if given, is called with a\n"
662 "reference to the proxy when it is about to be finalized.";
665 weakref_proxy(PyObject
*self
, PyObject
*args
)
668 PyObject
*callback
= NULL
;
669 PyWeakReference
*result
= NULL
;
671 if (PyArg_ParseTuple(args
, "O|O:new", &object
, &callback
)) {
672 PyWeakReference
**list
;
673 PyWeakReference
*ref
, *proxy
;
675 if (!PyType_SUPPORTS_WEAKREFS(object
->ob_type
)) {
676 PyErr_Format(PyExc_TypeError
,
677 "'%s' objects are not weakly referencable",
678 object
->ob_type
->tp_name
);
681 list
= GET_WEAKREFS_LISTPTR(object
);
682 get_basic_refs(*list
, &ref
, &proxy
);
683 if (callback
== NULL
) {
684 /* attempt to return an existing weak reference if it exists */
688 if (result
== NULL
) {
689 result
= new_weakref();
690 if (result
!= NULL
) {
691 PyWeakReference
*prev
;
693 if (PyCallable_Check(object
))
694 result
->ob_type
= &PyWeakCallableProxy_Type
;
696 result
->ob_type
= &PyWeakProxy_Type
;
697 result
->wr_object
= object
;
698 Py_XINCREF(callback
);
699 result
->wr_callback
= callback
;
700 if (callback
== NULL
)
703 prev
= (proxy
== NULL
) ? ref
: proxy
;
706 insert_head(result
, list
);
708 insert_after(result
, prev
);
709 PyObject_GC_Track(result
);
713 return (PyObject
*) result
;
717 /* This is the implementation of the PyObject_ClearWeakRefs() function; it
718 * is installed in the init_weakref() function. It is called by the
719 * tp_dealloc handler to clear weak references.
721 * This iterates through the weak references for 'object' and calls callbacks
722 * for those references which have one. It returns when all callbacks have
726 cleanup_helper(PyObject
*object
)
728 PyWeakReference
**list
;
731 || !PyType_SUPPORTS_WEAKREFS(object
->ob_type
)
732 || object
->ob_refcnt
!= 0) {
733 PyErr_BadInternalCall();
736 list
= GET_WEAKREFS_LISTPTR(object
);
737 /* Remove the callback-less basic and proxy references */
738 if (*list
!= NULL
&& (*list
)->wr_callback
== NULL
) {
739 clear_weakref(*list
);
740 if (*list
!= NULL
&& (*list
)->wr_callback
== NULL
)
741 clear_weakref(*list
);
744 int count
= getweakrefcount(*list
);
747 PyWeakReference
*current
= *list
;
748 PyObject
*callback
= current
->wr_callback
;
752 clear_weakref(current
);
753 cbresult
= PyObject_CallFunction(callback
, "O", current
);
754 if (cbresult
== NULL
)
755 PyErr_WriteUnraisable(callback
);
761 PyObject
*tuple
= PyTuple_New(count
* 2);
762 PyWeakReference
*current
= *list
;
765 for (i
= 0; i
< count
; ++i
) {
766 PyWeakReference
*next
= current
->wr_next
;
769 PyTuple_SET_ITEM(tuple
, i
* 2, (PyObject
*) current
);
770 PyTuple_SET_ITEM(tuple
, i
* 2 + 1, current
->wr_callback
);
771 current
->wr_callback
= NULL
;
772 next
= current
->wr_next
;
773 clear_weakref(current
);
776 for (i
= 0; i
< count
; ++i
) {
777 PyObject
*current
= PyTuple_GET_ITEM(tuple
, i
* 2);
778 PyObject
*callback
= PyTuple_GET_ITEM(tuple
, i
* 2 + 1);
779 PyObject
*cbresult
= PyObject_CallFunction(callback
, "O",
781 if (cbresult
== NULL
)
782 PyErr_WriteUnraisable(callback
);
793 weakref_functions
[] = {
794 {"getweakrefcount", weakref_getweakrefcount
, METH_O
,
795 weakref_getweakrefcount__doc__
},
796 {"getweakrefs", weakref_getweakrefs
, METH_O
,
797 weakref_getweakrefs__doc__
},
798 {"proxy", weakref_proxy
, METH_VARARGS
,
799 weakref_proxy__doc__
},
800 {"ref", weakref_ref
, METH_VARARGS
,
802 {NULL
, NULL
, 0, NULL
}
811 PyWeakReference_Type
.ob_type
= &PyType_Type
;
812 PyWeakProxy_Type
.ob_type
= &PyType_Type
;
813 PyWeakCallableProxy_Type
.ob_type
= &PyType_Type
;
814 m
= Py_InitModule3("_weakref", weakref_functions
,
815 "Weak-reference support module.");
817 PyObject_ClearWeakRefs
= cleanup_helper
;
818 Py_INCREF(&PyWeakReference_Type
);
819 PyModule_AddObject(m
, "ReferenceType",
820 (PyObject
*) &PyWeakReference_Type
);
821 Py_INCREF(&PyWeakProxy_Type
);
822 PyModule_AddObject(m
, "ProxyType",
823 (PyObject
*) &PyWeakProxy_Type
);
824 Py_INCREF(&PyWeakCallableProxy_Type
);
825 PyModule_AddObject(m
, "CallableProxyType",
826 (PyObject
*) &PyWeakCallableProxy_Type
);
827 ReferenceError
= PyErr_NewException("weakref.ReferenceError",
828 PyExc_RuntimeError
, NULL
);
829 if (ReferenceError
!= NULL
)
830 PyModule_AddObject(m
, "ReferenceError", ReferenceError
);