Commit e1a600b5 authored by Stefan Behnel's avatar Stefan Behnel

reverted last change, based on extended test case

parent 1e6272ac
...@@ -1120,6 +1120,24 @@ class ClassScope(Scope): ...@@ -1120,6 +1120,24 @@ class ClassScope(Scope):
def add_string_const(self, value): def add_string_const(self, value):
return self.outer_scope.add_string_const(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): class PyClassScope(ClassScope):
...@@ -1371,3 +1389,28 @@ class PropertyScope(Scope): ...@@ -1371,3 +1389,28 @@ class PropertyScope(Scope):
error(pos, "Only __get__, __set__ and __del__ methods allowed " error(pos, "Only __get__, __set__ and __del__ methods allowed "
"in a property declaration") "in a property declaration")
return None 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;
}
"""
]
__doc__ = u""" __doc__ = u"""
>>> class1.view()
class1
>>> class1.plus(1) >>> class1.plus(1)
6 6
>>> class2.view()
class2
>>> class2.plus(1) >>> class2.plus(1)
7 7
>>> class3.view()
class3
>>> class3.plus(1) >>> class3.plus(1)
8 8
""" """
...@@ -13,11 +19,20 @@ def f_plus(cls, a): ...@@ -13,11 +19,20 @@ def f_plus(cls, a):
class class1: class class1:
a = 5 a = 5
plus = classmethod(f_plus) plus = classmethod(f_plus)
def view(cls):
print cls.__name__
view = classmethod(view)
class class2(object): class class2(object):
a = 6 a = 6
plus = classmethod(f_plus) plus = classmethod(f_plus)
def view(cls):
print cls.__name__
view = classmethod(view)
cdef class class3: cdef class class3:
a = 7 a = 7
plus = classmethod(f_plus) plus = classmethod(f_plus)
def view(cls):
print cls.__name__
view = classmethod(view)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment