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

This commit is contained in:
Pablo Galindo 2020-05-05 22:58:19 +01:00 committed by GitHub
parent 1253c3ef70
commit 96074de573
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 1 deletions

View file

@ -411,6 +411,26 @@ def __iter__(self):
# can be killed in the middle of the call # can be killed in the middle of the call
"blech" in p "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): def test_getweakrefcount(self):
o = C() o = C()
ref1 = weakref.ref(o) ref1 = weakref.ref(o)

View file

@ -0,0 +1,2 @@
Add pass-throughs for :func:`hash` and :func:`reversed` to
:class:`weakref.proxy` objects. Patch by Pablo Galindo.

View file

@ -665,10 +665,12 @@ proxy_iternext(PyWeakReference *proxy)
WRAP_METHOD(proxy_bytes, __bytes__) WRAP_METHOD(proxy_bytes, __bytes__)
WRAP_METHOD(proxy_reversed, __reversed__)
static PyMethodDef proxy_methods[] = { static PyMethodDef proxy_methods[] = {
{"__bytes__", proxy_bytes, METH_NOARGS}, {"__bytes__", proxy_bytes, METH_NOARGS},
{"__reversed__", proxy_reversed, METH_NOARGS},
{NULL, NULL} {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 PyTypeObject
_PyWeakref_ProxyType = { _PyWeakref_ProxyType = {
PyVarObject_HEAD_INIT(&PyType_Type, 0) PyVarObject_HEAD_INIT(&PyType_Type, 0)
@ -746,7 +763,7 @@ _PyWeakref_ProxyType = {
&proxy_as_number, /* tp_as_number */ &proxy_as_number, /* tp_as_number */
&proxy_as_sequence, /* tp_as_sequence */ &proxy_as_sequence, /* tp_as_sequence */
&proxy_as_mapping, /* tp_as_mapping */ &proxy_as_mapping, /* tp_as_mapping */
0, /* tp_hash */ proxy_hash, /* tp_hash */
0, /* tp_call */ 0, /* tp_call */
proxy_str, /* tp_str */ proxy_str, /* tp_str */
proxy_getattr, /* tp_getattro */ proxy_getattr, /* tp_getattro */