Skip to content

Commit

Permalink
classmethod() should fall back to calling PyClassMethod_New() instead…
Browse files Browse the repository at this point in the history
… of deciding for itself that the type is invalid. (GH-3660)
  • Loading branch information
da-woods authored and scoder committed Jun 4, 2020
1 parent 7a64698 commit 7604895
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 10 deletions.
11 changes: 1 addition & 10 deletions Cython/Utility/CythonFunction.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
15 changes: 15 additions & 0 deletions tests/run/classmethod.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ class1
class1
>>> class1().bview()
class1
>>> class1().cview()
class1
>>> class1().cview("XX")
class1XX
>>> class2.view()
class2
Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 7604895

Please sign in to comment.