From a152462eba4463e4ab9292e76fb1a3e3b23aed64 Mon Sep 17 00:00:00 2001
From: Jeroen Demeyer <jdemeyer@cage.ugent.be>
Date: Thu, 15 Feb 2018 11:06:32 +0100
Subject: [PATCH] In Python 3, an unbound method is just the function

---
 Cython/Utility/ModuleSetupCode.c |  2 +-
 tests/run/cyfunction.pyx         | 19 +++++++++++++++++++
 tests/run/pure_py.py             | 12 ++++++++++++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c
index 1661f40be..2aeabd2fe 100644
--- a/Cython/Utility/ModuleSetupCode.c
+++ b/Cython/Utility/ModuleSetupCode.c
@@ -617,7 +617,7 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
 #endif
 
 #if PY_MAJOR_VERSION >= 3
-  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : (Py_INCREF(func), func))
 #else
   #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
 #endif
diff --git a/tests/run/cyfunction.pyx b/tests/run/cyfunction.pyx
index 2389a5a25..096855140 100644
--- a/tests/run/cyfunction.pyx
+++ b/tests/run/cyfunction.pyx
@@ -3,6 +3,7 @@
 # tag: cyfunction
 
 import sys
+IS_PY2 = sys.version_info[0] < 3
 IS_PY3 = sys.version_info[0] >= 3
 IS_PY34 = sys.version_info > (3, 4, 0, 'beta', 3)
 
@@ -348,3 +349,21 @@ cdef class TestDecoratedMethods:
         2
         """
         return x
+
+
+cdef class TestUnboundMethodCdef:
+    """
+    >>> C = TestUnboundMethodCdef
+    >>> IS_PY2 or (C.meth is C.__dict__["meth"])
+    True
+    """
+    def meth(self): pass
+
+
+class TestUnboundMethod:
+    """
+    >>> C = TestUnboundMethod
+    >>> IS_PY2 or (C.meth is C.__dict__["meth"])
+    True
+    """
+    def meth(self): pass
diff --git a/tests/run/pure_py.py b/tests/run/pure_py.py
index e15b7ba62..b52517a3a 100644
--- a/tests/run/pure_py.py
+++ b/tests/run/pure_py.py
@@ -1,3 +1,6 @@
+import sys
+IS_PY2 = sys.version_info[0] < 3
+
 import cython
 
 is_compiled = cython.compiled
@@ -360,3 +363,12 @@ class CClass(object):
     def get_attr(self):
         print(cython.typeof(self.attr))
         return self.attr
+
+
+class TestUnboundMethod:
+    """
+    >>> C = TestUnboundMethod
+    >>> IS_PY2 or (C.meth is C.__dict__["meth"])
+    True
+    """
+    def meth(self): pass
-- 
2.30.9