diff options
-rw-r--r-- | Lib/test/test_weakref.py | 14 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2021-06-29-11-49-29.bpo-44523.67-ZIP.rst | 3 | ||||
-rw-r--r-- | Objects/weakrefobject.c | 18 |
3 files changed, 15 insertions, 20 deletions
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 56a42f0..dd5a781 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -422,14 +422,20 @@ class ReferencesTestCase(TestBase): self.assertEqual("".join(reversed(weakref.proxy(obj))), "cba") def test_proxy_hash(self): - cool_hash = 299_792_458 - class MyObj: def __hash__(self): - return cool_hash + return 42 + + obj = MyObj() + with self.assertRaises(TypeError): + hash(weakref.proxy(obj)) + + class MyObj: + __hash__ = None obj = MyObj() - self.assertEqual(hash(weakref.proxy(obj)), cool_hash) + with self.assertRaises(TypeError): + hash(weakref.proxy(obj)) def test_getweakrefcount(self): o = C() diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-06-29-11-49-29.bpo-44523.67-ZIP.rst b/Misc/NEWS.d/next/Core and Builtins/2021-06-29-11-49-29.bpo-44523.67-ZIP.rst new file mode 100644 index 0000000..aa51a74 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-06-29-11-49-29.bpo-44523.67-ZIP.rst @@ -0,0 +1,3 @@ +Remove the pass-through for :func:`hash` of :class:`weakref.proxy` objects +to prevent unintended consequences when the original referred object +dies while the proxy is part of a hashable object. Patch by Pablo Galindo. diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 313e8ab..c36d239 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -732,21 +732,6 @@ static PyMappingMethods proxy_as_mapping = { }; -static Py_hash_t -proxy_hash(PyObject *self) -{ - PyWeakReference *proxy = (PyWeakReference *)self; - if (!proxy_checkref(proxy)) { - return -1; - } - PyObject *obj = PyWeakref_GET_OBJECT(proxy); - Py_INCREF(obj); - Py_hash_t res = PyObject_Hash(obj); - Py_DECREF(obj); - return res; -} - - PyTypeObject _PyWeakref_ProxyType = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -763,7 +748,8 @@ _PyWeakref_ProxyType = { &proxy_as_number, /* tp_as_number */ &proxy_as_sequence, /* tp_as_sequence */ &proxy_as_mapping, /* tp_as_mapping */ - proxy_hash, /* tp_hash */ +// Notice that tp_hash is intentionally omitted as proxies are "mutable" (when the reference dies). + 0, /* tp_hash */ 0, /* tp_call */ proxy_str, /* tp_str */ proxy_getattr, /* tp_getattro */ |