Skip to content

Commit

Permalink
bpo-44523: Remove the pass-through for hash() in weakref proxy objects (
Browse files Browse the repository at this point in the history
GH-26950) (GH-26960)

(cherry picked from commit e2fea10)

Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
  • Loading branch information
miss-islington and pablogsal committed Jun 29, 2021
1 parent 02859df commit f790bc8
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 20 deletions.
14 changes: 10 additions & 4 deletions Lib/test/test_weakref.py
Expand Up @@ -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()
Expand Down
@@ -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.
18 changes: 2 additions & 16 deletions Objects/weakrefobject.c
Expand Up @@ -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)
Expand All @@ -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 */
Expand Down

0 comments on commit f790bc8

Please sign in to comment.