diff options
author | da-woods <dw-git@d-woods.co.uk> | 2020-06-02 20:05:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-02 21:05:07 +0200 |
commit | 12ab8bc0056a0e77ccc0756955eb1621fd3b35db (patch) | |
tree | e9aaa11aae5896913e0276b74f8c3736d0a37247 | |
parent | ef423d1e9c9e67a24db0e61b7b334983858fa581 (diff) | |
download | cython-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.c | 10 | ||||
-rw-r--r-- | tests/run/classmethod.pyx | 15 |
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 |