diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2020-05-05 21:58:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-05 21:58:19 (GMT) |
commit | 96074de573f82fc66a2bd73c36905141a3f1d5c1 (patch) | |
tree | 7c0c6375b21b16ed77e6a3010a96fd9fbf43c4eb | |
parent | 1253c3ef70ea5632d32ae19579a14152db0d45c1 (diff) | |
download | cpython-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.py | 20 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2020-05-05-20-36-15.bpo-40523.hKZVTB.rst | 2 | ||||
-rw-r--r-- | Objects/weakrefobject.c | 19 |
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 */ |