Commit 2ddb5478 authored by Mark Florisson's avatar Mark Florisson

Fix staticmethods in cdef classes & fix fused function PyObject * XDECREF cast

parent 835010c7
...@@ -2840,6 +2840,15 @@ class DefNode(FuncDefNode): ...@@ -2840,6 +2840,15 @@ class DefNode(FuncDefNode):
self.self_in_stararg = 1 self.self_in_stararg = 1
nfixed = 0 nfixed = 0
if self.is_staticmethod and env.is_c_class_scope:
nfixed = 0
self.self_in_stararg = True
self.entry.signature = sig = copy.copy(sig)
sig.fixed_arg_format = "*"
sig.is_staticmethod = True
sig.has_generic_args = True
for i in range(min(nfixed, len(self.args))): for i in range(min(nfixed, len(self.args))):
arg = self.args[i] arg = self.args[i]
arg.is_generic = 0 arg.is_generic = 0
...@@ -2976,7 +2985,7 @@ class DefNode(FuncDefNode): ...@@ -2976,7 +2985,7 @@ class DefNode(FuncDefNode):
decorator.decorator.analyse_expressions(env) decorator.decorator.analyse_expressions(env)
def needs_assignment_synthesis(self, env, code=None): def needs_assignment_synthesis(self, env, code=None):
if self.specialized_cpdefs: if self.specialized_cpdefs or self.is_staticmethod:
return True return True
if self.no_assignment_synthesis: if self.no_assignment_synthesis:
return False return False
......
...@@ -68,6 +68,9 @@ class Signature(object): ...@@ -68,6 +68,9 @@ class Signature(object):
# and are not looked up in here # and are not looked up in here
} }
type_to_format_map = dict([(type_, format_)
for format_, type_ in format_map.iteritems()])
error_value_map = { error_value_map = {
'O': "NULL", 'O': "NULL",
'T': "NULL", 'T': "NULL",
...@@ -91,6 +94,7 @@ class Signature(object): ...@@ -91,6 +94,7 @@ class Signature(object):
self.fixed_arg_format = arg_format self.fixed_arg_format = arg_format
self.ret_format = ret_format self.ret_format = ret_format
self.error_value = self.error_value_map.get(ret_format, None) self.error_value = self.error_value_map.get(ret_format, None)
self.is_staticmethod = False
def num_fixed_args(self): def num_fixed_args(self):
return len(self.fixed_arg_format) return len(self.fixed_arg_format)
...@@ -109,6 +113,11 @@ class Signature(object): ...@@ -109,6 +113,11 @@ class Signature(object):
def return_type(self): def return_type(self):
return self.format_map[self.ret_format] return self.format_map[self.ret_format]
def format_from_type(self, arg_type):
if arg_type.is_pyobject:
arg_type = PyrexTypes.py_object_type
return self.type_to_format_map[arg_type]
def exception_value(self): def exception_value(self):
return self.error_value_map.get(self.ret_format) return self.error_value_map.get(self.ret_format)
...@@ -141,6 +150,9 @@ class Signature(object): ...@@ -141,6 +150,9 @@ class Signature(object):
return [method_noargs] return [method_noargs]
elif full_args in ["OO", "TO"] and not self.has_generic_args: elif full_args in ["OO", "TO"] and not self.has_generic_args:
return [method_onearg] return [method_onearg]
if self.is_staticmethod:
return [method_varargs, method_keywords]
return None return None
......
...@@ -657,7 +657,7 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw) ...@@ -657,7 +657,7 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
result = PyCFunction_Call(func, args, kw); result = PyCFunction_Call(func, args, kw);
__pyx_err: __pyx_err:
Py_XDECREF(new_args); Py_XDECREF(new_args);
Py_XDECREF(new_func); Py_XDECREF((PyObject *) new_func);
return result; return result;
} }
......
...@@ -152,7 +152,7 @@ class BaseClass(object): ...@@ -152,7 +152,7 @@ class BaseClass(object):
class SubClass(BaseClass): class SubClass(BaseClass):
@staticmethod @staticmethod
def mystaticmethod(cython.integral arg1): def mystaticmethod(self, cython.integral arg1):
print cython.typeof(arg1), arg1 print cython.typeof(arg1), arg1
super().mystaticmethod(arg1 + 1) super().mystaticmethod(arg1 + 1)
...@@ -171,6 +171,14 @@ class SubSubClass(SubClass): ...@@ -171,6 +171,14 @@ class SubSubClass(SubClass):
def test_fused_def_super(): def test_fused_def_super():
""" """
>>> test_fused_def_super() >>> test_fused_def_super()
long 10
long 11
long 11
long 12
short 12
long 13
short 13
long 14
<class 'fused_def.SubClass'> long 14 <class 'fused_def.SubClass'> long 14
<class 'fused_def.SubClass'> long 15 <class 'fused_def.SubClass'> long 15
<class 'fused_def.SubClass'> long 15 <class 'fused_def.SubClass'> long 15
...@@ -191,10 +199,10 @@ def test_fused_def_super(): ...@@ -191,10 +199,10 @@ def test_fused_def_super():
obj = SubClass() obj = SubClass()
cls = SubClass cls = SubClass
#obj.mystaticmethod(10) obj.mystaticmethod(obj, 10)
#cls.mystaticmethod(11) cls.mystaticmethod(obj, 11)
#obj.mystaticmethod[cy.short](12) obj.mystaticmethod[cy.short](obj, 12)
#cls.mystaticmethod[cy.short](13) cls.mystaticmethod[cy.short](obj, 13)
obj.myclassmethod(14) obj.myclassmethod(14)
cls.myclassmethod(15) cls.myclassmethod(15)
......
...@@ -43,3 +43,61 @@ def nested_class(): ...@@ -43,3 +43,61 @@ def nested_class():
def plus1(a): def plus1(a):
return a + 1 return a + 1
return class5 return class5
cdef class BaseClass(object):
"""
Test cdef static methods with super() and Python subclasses
>>> obj = BaseClass()
>>> obj.mystaticmethod(obj, 1)
1
>>> BaseClass.mystaticmethod(obj, 1)
1
>>> obj.mystaticmethod2(1, 2, 3)
1 2 3
>>> BaseClass.mystaticmethod2(1, 2, 3)
1 2 3
"""
@staticmethod
def mystaticmethod(self, arg1):
print arg1
@staticmethod
def mystaticmethod2(a, b, c):
print a, b, c
cdef class SubClass(BaseClass):
"""
>>> obj = SubClass()
>>> obj.mystaticmethod(obj, 1)
1
2
>>> SubClass.mystaticmethod(obj, 1)
1
2
"""
@staticmethod
def mystaticmethod(self, arg1):
print arg1
super().mystaticmethod(self, arg1 + 1)
class SubSubClass(SubClass):
"""
>>> obj = SubSubClass()
>>> obj.mystaticmethod(obj, 1)
1
2
3
>>> SubSubClass.mystaticmethod(obj, 1)
1
2
3
"""
@staticmethod
def mystaticmethod(self, arg1):
print arg1
super().mystaticmethod(self, arg1 + 1)
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