From 1e6272ac48351ce450b52c2cb1c893c738cb4507 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 23 May 2008 20:44:03 +0200 Subject: [PATCH] fix classmethod() calls --HG-- rename : tests/run/classmethod.pyx => tests/run/staticmethod.pyx --- Cython/Compiler/Symtab.py | 43 -------------------------------------- tests/run/classmethod.pyx | 25 ++++++++++++---------- tests/run/staticmethod.pyx | 20 ++++++++++++++++++ 3 files changed, 34 insertions(+), 54 deletions(-) create mode 100644 tests/run/staticmethod.pyx diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index ba2e9d8c..02ad826a 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -1120,24 +1120,6 @@ class ClassScope(Scope): def add_string_const(self, value): return self.outer_scope.add_string_const(value) - - def lookup(self, name): - if name == "classmethod": - # We don't want to use the builtin classmethod here 'cause it won't do the - # right thing in this scope (as the class memebers aren't still functions). - # Don't want to add a cfunction to this scope 'cause that would mess with - # the type definition, so we just return the right entry. - self.use_utility_code(classmethod_utility_code) - entry = Entry( - "classmethod", - "__Pyx_Method_ClassMethod", - PyrexTypes.CFuncType( - py_object_type, - [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0)) - entry.is_cfunction = 1 - return entry - else: - return Scope.lookup(self, name) class PyClassScope(ClassScope): @@ -1389,28 +1371,3 @@ class PropertyScope(Scope): error(pos, "Only __get__, __set__ and __del__ methods allowed " "in a property declaration") return None - - -# Should this go elsewhere (and then get imported)? -#------------------------------------------------------------------------------------ - -classmethod_utility_code = [ -""" -#include "descrobject.h" -static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/ -""",""" -static PyObject* __Pyx_Method_ClassMethod(PyObject *method) { - /* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */ - /* if (!PyObject_TypeCheck(method, &PyMethodDescr_Type)) { */ - if (strcmp(Py_TYPE(method)->tp_name, "method_descriptor") == 0) { /* cdef classes */ - PyMethodDescrObject *descr = (PyMethodDescrObject *)method; - return PyDescr_NewClassMethod(descr->d_type, descr->d_method); - } - else if (PyMethod_Check(method)) { /* python classes */ - return PyClassMethod_New(PyMethod_GET_FUNCTION(method)); - } - PyErr_Format(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 e8004b99..2577934e 100644 --- a/tests/run/classmethod.pyx +++ b/tests/run/classmethod.pyx @@ -1,20 +1,23 @@ __doc__ = u""" ->>> class1.plus1(1) -2 ->>> class2.plus1(1) -2 ->>> class3.plus1(1) -2 +>>> class1.plus(1) +6 +>>> class2.plus(1) +7 +>>> class3.plus(1) +8 """ -def f_plus(a): - return a + 1 +def f_plus(cls, a): + return cls.a + a class class1: - plus1 = f_plus + a = 5 + plus = classmethod(f_plus) class class2(object): - plus1 = f_plus + a = 6 + plus = classmethod(f_plus) cdef class class3: - plus1 = f_plus + a = 7 + plus = classmethod(f_plus) diff --git a/tests/run/staticmethod.pyx b/tests/run/staticmethod.pyx new file mode 100644 index 00000000..e8004b99 --- /dev/null +++ b/tests/run/staticmethod.pyx @@ -0,0 +1,20 @@ +__doc__ = u""" +>>> class1.plus1(1) +2 +>>> class2.plus1(1) +2 +>>> class3.plus1(1) +2 +""" + +def f_plus(a): + return a + 1 + +class class1: + plus1 = f_plus + +class class2(object): + plus1 = f_plus + +cdef class class3: + plus1 = f_plus -- 2.26.2