diff -r 2bf154ca43c6 Doc/library/weakref.rst --- a/Doc/library/weakref.rst Sat Apr 06 01:15:30 2013 +0200 +++ b/Doc/library/weakref.rst Sat Apr 06 16:03:15 2013 +0100 @@ -111,6 +111,15 @@ This is a subclassable type rather than a factory function. + .. attribute:: __callback__ + + This read-only attribute returns the callback currently associated to the + weakref. If there is no callback or if the referent of the weakref is + no longer alive then this attribute will have value ``None``. + + .. versionadded:: 3.4 + Added the :attr:`__callback__` attribute. + .. function:: proxy(object[, callback]) @@ -261,8 +270,9 @@ Weak Reference Objects ---------------------- -Weak reference objects have no attributes or methods, but do allow the referent -to be obtained, if it still exists, by calling it: +Weak reference objects have no methods and no attributes besides +:attr:`ref.__callback__`. A weak reference object allows the referent to be +obtained, if it still exists, by calling it: >>> import weakref >>> class Object: diff -r 2bf154ca43c6 Lib/test/test_weakref.py --- a/Lib/test/test_weakref.py Sat Apr 06 01:15:30 2013 +0200 +++ b/Lib/test/test_weakref.py Sat Apr 06 16:03:15 2013 +0100 @@ -802,6 +802,29 @@ del root gc.collect() + def test_callback_attribute(self): + x = Object(1) + callback = lambda ref: None + ref1 = weakref.ref(x, callback) + self.assertIs(ref1.__callback__, callback) + + ref2 = weakref.ref(x) + self.assertIsNone(ref2.__callback__) + + def test_callback_attribute_after_deletion(self): + x = Object(1) + ref = weakref.ref(x, self.callback) + self.assertIsNotNone(ref.__callback__) + del x + self.assertIsNone(ref.__callback__) + + def test_set_callback_attribute(self): + x = Object(1) + callback = lambda ref: None + ref1 = weakref.ref(x, callback) + with self.assertRaises(AttributeError): + ref1.__callback__ = lambda ref: None + class SubclassableWeakrefTestCase(TestBase): diff -r 2bf154ca43c6 Misc/NEWS --- a/Misc/NEWS Sat Apr 06 01:15:30 2013 +0200 +++ b/Misc/NEWS Sat Apr 06 16:03:15 2013 +0100 @@ -10,6 +10,8 @@ Core and Builtins ----------------- +- Issue #17643: Add __callback__ attribute to weakref.ref. + - Issue #17469: Fix _Py_GetAllocatedBlocks() and sys.getallocatedblocks() when running on valgrind. diff -r 2bf154ca43c6 Objects/weakrefobject.c --- a/Objects/weakrefobject.c Sat Apr 06 01:15:30 2013 +0200 +++ b/Objects/weakrefobject.c Sat Apr 06 16:03:15 2013 +0100 @@ -338,6 +338,11 @@ } +static PyMemberDef weakref_members[] = { + {"__callback__", T_OBJECT, offsetof(PyWeakReference, wr_callback), READONLY}, + {NULL} /* Sentinel */ +}; + PyTypeObject _PyWeakref_RefType = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -369,7 +374,7 @@ 0, /*tp_iter*/ 0, /*tp_iternext*/ 0, /*tp_methods*/ - 0, /*tp_members*/ + weakref_members, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/