summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2020-06-02 20:05:07 +0100
committerGitHub <noreply@github.com>2020-06-02 21:05:07 +0200
commit12ab8bc0056a0e77ccc0756955eb1621fd3b35db (patch)
treee9aaa11aae5896913e0276b74f8c3736d0a37247
parentef423d1e9c9e67a24db0e61b7b334983858fa581 (diff)
downloadcython-12ab8bc0056a0e77ccc0756955eb1621fd3b35db.tar.gz
classmethod() should fall back to calling PyClassMethod_New() instead of deciding for itself that the type is invalid. (GH-3660)
-rw-r--r--Cython/Utility/CythonFunction.c10
-rw-r--r--tests/run/classmethod.pyx15
2 files changed, 16 insertions, 9 deletions
diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c
index a74794172..4fb0f9cf9 100644
--- a/Cython/Utility/CythonFunction.c
+++ b/Cython/Utility/CythonFunction.c
@@ -1484,16 +1484,8 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
// python classes
return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
}
-#ifdef __Pyx_CyFunction_USED
- else if (__Pyx_IsCyOrPyCFunction(method))
-#else
- else if (PyCFunction_Check(method))
-#endif
+ else
{
return PyClassMethod_New(method);
}
- PyErr_SetString(PyExc_TypeError,
- "Class-level classmethod() can only be called on "
- "a method_descriptor or instance method.");
- return NULL;
}
diff --git a/tests/run/classmethod.pyx b/tests/run/classmethod.pyx
index 9b095c525..fdc03be7d 100644
--- a/tests/run/classmethod.pyx
+++ b/tests/run/classmethod.pyx
@@ -9,6 +9,10 @@ class1
class1
>>> class1().bview()
class1
+>>> class1().cview()
+class1
+>>> class1().cview("XX")
+class1XX
>>> class2.view()
class2
@@ -35,6 +39,12 @@ cimport cython
def f_plus(cls, a):
return cls.a + a
+def second_decorator(f):
+ # note - a class, not a function (didn't pass Cython's test in __Pyx_Method_ClassMethod)
+ class C:
+ def __call__(self, *args):
+ return f(*args)
+ return C()
class class1:
a = 5
@@ -48,6 +58,11 @@ class class1:
def bview(cls):
print cls.__name__
+ @classmethod
+ @second_decorator
+ def cview(cls, s=""):
+ print cls.__name__+s
+
class class2(object):
a = 6