diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2013-04-13 14:45:44 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2013-04-13 14:45:44 (GMT) |
commit | 556e94b8fe068d1d58064fe84467e0620b87f9ed (patch) | |
tree | 8d6d21319dd056b30cb089d645ba8a0f729c39f7 | |
parent | 548677bb8ce759395e2512420c03ccb184a77bf5 (diff) | |
download | cpython-556e94b8fe068d1d58064fe84467e0620b87f9ed.zip cpython-556e94b8fe068d1d58064fe84467e0620b87f9ed.tar.gz cpython-556e94b8fe068d1d58064fe84467e0620b87f9ed.tar.bz2 |
Issue #17643: Add __callback__ attribute to weakref.ref.
-rw-r--r-- | Doc/library/weakref.rst | 14 | ||||
-rw-r--r-- | Lib/test/test_weakref.py | 24 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Objects/weakrefobject.c | 7 |
4 files changed, 44 insertions, 3 deletions
diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 1bf6b58..78ff21d0 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -111,6 +111,15 @@ Extension types can easily be made to support weak references; see 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 @@ These method have the same issues as the and :meth:`keyrefs` method of 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 --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index cdd26c7..e32e248 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -802,6 +802,30 @@ class ReferencesTestCase(TestBase): 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 + support.gc_collect() + 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): @@ -10,6 +10,8 @@ What's New in Python 3.4.0 Alpha 1? Core and Builtins ----------------- +- Issue #17643: Add __callback__ attribute to weakref.ref. + - Issue #16447: Fixed potential segmentation fault when setting __name__ on a class. diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index b49dcee..c083f8f 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -338,6 +338,11 @@ weakref___init__(PyObject *self, PyObject *args, PyObject *kwargs) } +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 @@ _PyWeakref_RefType = { 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*/ |