[Python-checkins] bpo-40523: Add pass-throughs for hash() and reversed() to weakref.proxy objects (GH-19946)

Pablo Galindo webhook-mailer at python.org
Tue May 5 17:58:29 EDT 2020


https://github.com/python/cpython/commit/96074de573f82fc66a2bd73c36905141a3f1d5c1
commit: 96074de573f82fc66a2bd73c36905141a3f1d5c1
branch: master
author: Pablo Galindo <Pablogsal at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-05-05T22:58:19+01:00
summary:

bpo-40523: Add pass-throughs for hash() and reversed() to weakref.proxy objects (GH-19946)

files:
A Misc/NEWS.d/next/Core and Builtins/2020-05-05-20-36-15.bpo-40523.hKZVTB.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 563507fee3d7e..56a42f055d0b5 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -411,6 +411,26 @@ def __iter__(self):
             # can be killed in the middle of the call
             "blech" in p
 
+    def test_proxy_reversed(self):
+        class MyObj:
+            def __len__(self):
+                return 3
+            def __reversed__(self):
+                return iter('cba')
+
+        obj = MyObj()
+        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
+
+        obj = MyObj()
+        self.assertEqual(hash(weakref.proxy(obj)), cool_hash)
+
     def test_getweakrefcount(self):
         o = C()
         ref1 = weakref.ref(o)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-05-20-36-15.bpo-40523.hKZVTB.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-05-20-36-15.bpo-40523.hKZVTB.rst
new file mode 100644
index 0000000000000..14f05be59a1ed
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-05-20-36-15.bpo-40523.hKZVTB.rst	
@@ -0,0 +1,2 @@
+Add pass-throughs for :func:`hash` and :func:`reversed` to
+:class:`weakref.proxy` objects. Patch by Pablo Galindo.
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 9640d93aaf2da..313e8abab5a25 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -665,10 +665,12 @@ proxy_iternext(PyWeakReference *proxy)
 
 
 WRAP_METHOD(proxy_bytes, __bytes__)
+WRAP_METHOD(proxy_reversed, __reversed__)
 
 
 static PyMethodDef proxy_methods[] = {
         {"__bytes__", proxy_bytes, METH_NOARGS},
+        {"__reversed__", proxy_reversed, METH_NOARGS},
         {NULL, NULL}
 };
 
@@ -730,6 +732,21 @@ 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)
@@ -746,7 +763,7 @@ _PyWeakref_ProxyType = {
     &proxy_as_number,                   /* tp_as_number */
     &proxy_as_sequence,                 /* tp_as_sequence */
     &proxy_as_mapping,                  /* tp_as_mapping */
-    0,                                  /* tp_hash */
+    proxy_hash,                         /* tp_hash */
     0,                                  /* tp_call */
     proxy_str,                          /* tp_str */
     proxy_getattr,                      /* tp_getattro */



More information about the Python-checkins mailing list