Skip to content

Commit e2fea10

Browse files
authored
bpo-44523: Remove the pass-through for hash() in weakref proxy objects (pythonGH-26950)
1 parent 12803c5 commit e2fea10

File tree

3 files changed

+15
-20
lines changed

3 files changed

+15
-20
lines changed

Lib/test/test_weakref.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -422,14 +422,20 @@ def __reversed__(self):
422422
self.assertEqual("".join(reversed(weakref.proxy(obj))), "cba")
423423

424424
def test_proxy_hash(self):
425-
cool_hash = 299_792_458
426-
427425
class MyObj:
428426
def __hash__(self):
429-
return cool_hash
427+
return 42
428+
429+
obj = MyObj()
430+
with self.assertRaises(TypeError):
431+
hash(weakref.proxy(obj))
432+
433+
class MyObj:
434+
__hash__ = None
430435

431436
obj = MyObj()
432-
self.assertEqual(hash(weakref.proxy(obj)), cool_hash)
437+
with self.assertRaises(TypeError):
438+
hash(weakref.proxy(obj))
433439

434440
def test_getweakrefcount(self):
435441
o = C()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Remove the pass-through for :func:`hash` of :class:`weakref.proxy` objects
2+
to prevent unintended consequences when the original referred object
3+
dies while the proxy is part of a hashable object. Patch by Pablo Galindo.

Objects/weakrefobject.c

+2-16
Original file line numberDiff line numberDiff line change
@@ -732,21 +732,6 @@ static PyMappingMethods proxy_as_mapping = {
732732
};
733733

734734

735-
static Py_hash_t
736-
proxy_hash(PyObject *self)
737-
{
738-
PyWeakReference *proxy = (PyWeakReference *)self;
739-
if (!proxy_checkref(proxy)) {
740-
return -1;
741-
}
742-
PyObject *obj = PyWeakref_GET_OBJECT(proxy);
743-
Py_INCREF(obj);
744-
Py_hash_t res = PyObject_Hash(obj);
745-
Py_DECREF(obj);
746-
return res;
747-
}
748-
749-
750735
PyTypeObject
751736
_PyWeakref_ProxyType = {
752737
PyVarObject_HEAD_INIT(&PyType_Type, 0)
@@ -763,7 +748,8 @@ _PyWeakref_ProxyType = {
763748
&proxy_as_number, /* tp_as_number */
764749
&proxy_as_sequence, /* tp_as_sequence */
765750
&proxy_as_mapping, /* tp_as_mapping */
766-
proxy_hash, /* tp_hash */
751+
// Notice that tp_hash is intentionally omitted as proxies are "mutable" (when the reference dies).
752+
0, /* tp_hash */
767753
0, /* tp_call */
768754
proxy_str, /* tp_str */
769755
proxy_getattr, /* tp_getattro */

0 commit comments

Comments
 (0)