bpo-36669: add matmul support to weakref.proxy (GH-12932)

diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst
index 7f3d267..80a908b 100644
--- a/Doc/library/weakref.rst
+++ b/Doc/library/weakref.rst
@@ -139,6 +139,10 @@
    prevent their use as dictionary keys.  *callback* is the same as the parameter
    of the same name to the :func:`ref` function.
 
+   .. versionchanged:: 3.8
+      Extended the operator support on proxy objects to include the matrix
+      multiplication operators ``@`` and ``@=``.
+
 
 .. function:: getweakrefcount(object)
 
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 2270334..4cb9c4f 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -450,6 +450,13 @@
   activating virtual environments under PowerShell Core 6.1.
   (Contributed by Brett Cannon in :issue:`32718`.)
 
+weakref
+-------
+
+* The proxy objects returned by :func:`weakref.proxy` now support the matrix
+  multiplication operators ``@`` and ``@=`` in addition to the other
+  numeric operators. (Contributed by Mark Dickinson in :issue:`36669`.)
+
 xml
 ---
 
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 50a46f8..6f15c03 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -285,6 +285,21 @@
         p //= 5
         self.assertEqual(p, 21)
 
+    def test_proxy_matmul(self):
+        class C:
+            def __matmul__(self, other):
+                return 1729
+            def __rmatmul__(self, other):
+                return -163
+            def __imatmul__(self, other):
+                return 561
+        o = C()
+        p = weakref.proxy(o)
+        self.assertEqual(p @ 5, 1729)
+        self.assertEqual(5 @ p, -163)
+        p @= 5
+        self.assertEqual(p, 561)
+
     # The PyWeakref_* C API is documented as allowing either NULL or
     # None as the value for the callback, where either means "no
     # callback".  The "no callback" ref and proxy objects are supposed
diff --git a/Misc/NEWS.d/next/Library/2019-04-24-17-08-45.bpo-36669.X4g0fu.rst b/Misc/NEWS.d/next/Library/2019-04-24-17-08-45.bpo-36669.X4g0fu.rst
new file mode 100644
index 0000000..53bdefe
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-04-24-17-08-45.bpo-36669.X4g0fu.rst
@@ -0,0 +1 @@
+Add missing matrix multiplication operator support to weakref.proxy.
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 9227aa6..ff6d922 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -525,6 +525,8 @@
 WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor)
 WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr)
 WRAP_UNARY(proxy_index, PyNumber_Index)
+WRAP_BINARY(proxy_matmul, PyNumber_MatrixMultiply)
+WRAP_BINARY(proxy_imatmul, PyNumber_InPlaceMatrixMultiply)
 
 static int
 proxy_bool(PyWeakReference *proxy)
@@ -642,6 +644,8 @@
     proxy_ifloor_div,       /*nb_inplace_floor_divide*/
     proxy_itrue_div,        /*nb_inplace_true_divide*/
     proxy_index,            /*nb_index*/
+    proxy_matmul,           /*nb_matrix_multiply*/
+    proxy_imatmul,          /*nb_inplace_matrix_multiply*/
 };
 
 static PySequenceMethods proxy_as_sequence = {