Skip to content

Commit 96074de

Browse files
authored
bpo-40523: Add pass-throughs for hash() and reversed() to weakref.proxy objects (pythonGH-19946)
1 parent 1253c3e commit 96074de

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

Lib/test/test_weakref.py

+20
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,26 @@ def __iter__(self):
411411
# can be killed in the middle of the call
412412
"blech" in p
413413

414+
def test_proxy_reversed(self):
415+
class MyObj:
416+
def __len__(self):
417+
return 3
418+
def __reversed__(self):
419+
return iter('cba')
420+
421+
obj = MyObj()
422+
self.assertEqual("".join(reversed(weakref.proxy(obj))), "cba")
423+
424+
def test_proxy_hash(self):
425+
cool_hash = 299_792_458
426+
427+
class MyObj:
428+
def __hash__(self):
429+
return cool_hash
430+
431+
obj = MyObj()
432+
self.assertEqual(hash(weakref.proxy(obj)), cool_hash)
433+
414434
def test_getweakrefcount(self):
415435
o = C()
416436
ref1 = weakref.ref(o)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add pass-throughs for :func:`hash` and :func:`reversed` to
2+
:class:`weakref.proxy` objects. Patch by Pablo Galindo.

Objects/weakrefobject.c

+18-1
Original file line numberDiff line numberDiff line change
@@ -665,10 +665,12 @@ proxy_iternext(PyWeakReference *proxy)
665665

666666

667667
WRAP_METHOD(proxy_bytes, __bytes__)
668+
WRAP_METHOD(proxy_reversed, __reversed__)
668669

669670

670671
static PyMethodDef proxy_methods[] = {
671672
{"__bytes__", proxy_bytes, METH_NOARGS},
673+
{"__reversed__", proxy_reversed, METH_NOARGS},
672674
{NULL, NULL}
673675
};
674676

@@ -730,6 +732,21 @@ static PyMappingMethods proxy_as_mapping = {
730732
};
731733

732734

735+
static Py_hash_t
736+
proxy_hash(PyObject *self)
737+
{
738+
PyWeakReference *proxy = (PyWeakReference *)self;
739+
if (!proxy_checkref(proxy)) {
740+
return -1;
741+
}
742+
PyObject *obj = PyWeakref_GET_OBJECT(proxy);
743+
Py_INCREF(obj);
744+
Py_hash_t res = PyObject_Hash(obj);
745+
Py_DECREF(obj);
746+
return res;
747+
}
748+
749+
733750
PyTypeObject
734751
_PyWeakref_ProxyType = {
735752
PyVarObject_HEAD_INIT(&PyType_Type, 0)
@@ -746,7 +763,7 @@ _PyWeakref_ProxyType = {
746763
&proxy_as_number, /* tp_as_number */
747764
&proxy_as_sequence, /* tp_as_sequence */
748765
&proxy_as_mapping, /* tp_as_mapping */
749-
0, /* tp_hash */
766+
proxy_hash, /* tp_hash */
750767
0, /* tp_call */
751768
proxy_str, /* tp_str */
752769
proxy_getattr, /* tp_getattro */

0 commit comments

Comments
 (0)