[Python-checkins] bpo-44523: Remove the pass-through for hash() in weakref proxy objects (GH-26950) (GH-26960)
pablogsal
webhook-mailer at python.org
Tue Jun 29 19:19:36 EDT 2021
https://github.com/python/cpython/commit/f790bc8084d3dfd723889740f9129ac8fcb2fa02
commit: f790bc8084d3dfd723889740f9129ac8fcb2fa02
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: pablogsal <Pablogsal at gmail.com>
date: 2021-06-30T00:19:32+01:00
summary:
bpo-44523: Remove the pass-through for hash() in weakref proxy objects (GH-26950) (GH-26960)
(cherry picked from commit e2fea101fd5517f33371b04432842b971021c3bf)
Co-authored-by: Pablo Galindo <Pablogsal at gmail.com>
files:
A Misc/NEWS.d/next/Core and Builtins/2021-06-29-11-49-29.bpo-44523.67-ZIP.rst
M Lib/test/test_weakref.py
M Objects/weakrefobject.c
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 56a42f055d0b54..dd5a781ed59d8b 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -422,14 +422,20 @@ def __reversed__(self):
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 00000000000000..aa51a7478583b1
--- /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 313e8abab5a25f..c36d2395cc8c53 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 */
More information about the Python-checkins
mailing list