summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2020-06-02 20:05:07 +0100
committerStefan Behnel <stefan_ml@behnel.de>2020-06-04 12:25:30 +0200
commit76048959bdb5ca053a6760b28fb33d2ec524ea24 (patch)
treead902ef292e4b58b0ad7821281f36cea87823d42
parent7a646983d5bfb1662501e389213d839fdd4917bd (diff)
downloadcython-76048959bdb5ca053a6760b28fb33d2ec524ea24.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.c11
-rw-r--r--tests/run/classmethod.pyx15
2 files changed, 16 insertions, 10 deletions
diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c
index 8f2349722..118333c03 100644
--- a/Cython/Utility/CythonFunction.c
+++ b/Cython/Utility/CythonFunction.c
@@ -1317,16 +1317,7 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
// python classes
return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
}
- else if (PyCFunction_Check(method)) {
- return PyClassMethod_New(method);
- }
-#ifdef __Pyx_CyFunction_USED
- else if (__Pyx_CyFunction_Check(method)) {
+ else {
return PyClassMethod_New(method);
}
-#endif
- 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