summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2020-05-05 21:58:19 (GMT)
committerGitHub <noreply@github.com>2020-05-05 21:58:19 (GMT)
commit96074de573f82fc66a2bd73c36905141a3f1d5c1 (patch)
tree7c0c6375b21b16ed77e6a3010a96fd9fbf43c4eb
parent1253c3ef70ea5632d32ae19579a14152db0d45c1 (diff)
downloadcpython-96074de573f82fc66a2bd73c36905141a3f1d5c1.zip
cpython-96074de573f82fc66a2bd73c36905141a3f1d5c1.tar.gz
cpython-96074de573f82fc66a2bd73c36905141a3f1d5c1.tar.bz2
bpo-40523: Add pass-throughs for hash() and reversed() to weakref.proxy objects (GH-19946)
-rw-r--r--Lib/test/test_weakref.py20
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2020-05-05-20-36-15.bpo-40523.hKZVTB.rst2
-rw-r--r--Objects/weakrefobject.c19
3 files changed, 40 insertions, 1 deletions
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 563507f..56a42f0 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -411,6 +411,26 @@ class ReferencesTestCase(TestBase):
# 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 0000000..14f05be
--- /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 9640d93..313e8ab 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 */