bpo-36922: implement PEP-590 Py_TPFLAGS_METHOD_DESCRIPTOR (GH-13338)

Co-authored-by: Mark Shannon <mark@hotpy.org>
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index a062a65..f3d41a2 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -27,6 +27,8 @@
 # Were we compiled --with-pydebug or with #define Py_DEBUG?
 Py_DEBUG = hasattr(sys, 'gettotalrefcount')
 
+Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17
+
 
 def testfunction(self):
     """some doc"""
@@ -456,6 +458,28 @@
         self.pendingcalls_wait(l, n)
 
 
+class TestPEP590(unittest.TestCase):
+
+    def test_method_descriptor_flag(self):
+        import functools
+        cached = functools.lru_cache(1)(testfunction)
+
+        self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+        self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+        self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+        self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+        self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+
+        self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+        self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+        self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+
+        # Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR
+        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
+            pass
+        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
+
+
 class SubinterpreterTest(unittest.TestCase):
 
     def test_subinterps(self):