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

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 @@
             # 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 @@
 
 
 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 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 @@
     &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 */