Commit 78a87802 authored by Stefan Behnel's avatar Stefan Behnel

second try to fix ticket #583: method signatures of overridden C methods in pure mode

parent 7e54d9a4
......@@ -534,8 +534,9 @@ class CFuncDeclaratorNode(CDeclaratorNode):
if nonempty:
nonempty -= 1
func_type_args = []
for arg_node in self.args:
name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
for i, arg_node in enumerate(self.args):
name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
is_self_arg = (i == 0 and env.is_c_class_scope))
name = name_declarator.name
if name_declarator.cname:
error(self.pos,
......@@ -649,8 +650,9 @@ class CArgDeclNode(Node):
default_value = None
annotation = None
def analyse(self, env, nonempty = 0):
#print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
def analyse(self, env, nonempty = 0, is_self_arg = False):
if is_self_arg:
self.base_type.is_self_arg = self.is_self_arg = True
if self.type is None:
# The parser may missinterpret names as types...
# We fix that here.
......@@ -1600,7 +1602,7 @@ class CFuncDefNode(FuncDefNode):
def analyse_declarations(self, env):
self.directive_locals.update(env.directives['locals'])
base_type = self.base_type.analyse(env)
# The 2 here is because we need both function and argument names.
# The 2 here is because we need both function and argument names.
name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
if not type.is_cfunction:
error(self.pos,
......@@ -1907,12 +1909,15 @@ class DefNode(FuncDefNode):
is_overridable = True)
cfunc = CVarDefNode(self.pos, type=cfunc_type)
else:
if scope is None:
scope = cfunc.scope
cfunc_type = cfunc.type
if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
error(self.pos, "wrong number of arguments")
error(cfunc.pos, "previous declaration here")
for formal_arg, type_arg in zip(self.args, cfunc_type.args):
name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
name_declarator, type = formal_arg.analyse(scope, nonempty=1,
is_self_arg = (i == 0 and scope.is_c_class_scope))
if type is None or type is PyrexTypes.py_object_type:
formal_arg.type = type_arg.type
formal_arg.name_declarator = name_declarator
......
......@@ -1233,15 +1233,11 @@ class AlignFunctionDefinitions(CythonTransform):
def visit_DefNode(self, node):
pxd_def = self.scope.lookup(node.name)
if pxd_def:
if self.scope.is_c_class_scope and len(pxd_def.type.args) > 0:
# The self parameter type needs adjusting.
pxd_def.type.args[0].type = self.scope.parent_type
if pxd_def.is_cfunction:
node = node.as_cfunction(pxd_def)
else:
if not pxd_def.is_cfunction:
error(node.pos, "'%s' redeclared" % node.name)
error(pxd_def.pos, "previous declaration here")
return None
node = node.as_cfunction(pxd_def)
elif self.scope.is_module_scope and self.directives['auto_cpdef']:
node = node.as_cfunction(scope=self.scope)
# Enable this when internal def functions are allowed.
......
cdef class Base:
cpdef str method(self)
cpdef str noargs(self)
cpdef str int_arg(self, int i)
cpdef str _class(tp)
cdef class Derived(Base):
cpdef str method(self)
cpdef str noargs(self)
cpdef str int_arg(self, int i)
cpdef str _class(tp)
cdef class DerivedDerived(Derived):
cpdef str noargs(self)
cpdef str int_arg(self, int i)
cpdef str _class(tp)
cdef class Derived2(Base):
cpdef str noargs(self)
cpdef str int_arg(self, int i)
cpdef str _class(tp)
class Base(object):
'''
>>> base = Base()
>>> print(base.method())
>>> print(base.noargs())
Base
>>> print(base.int_arg(1))
Base
>>> print(base._class())
Base
'''
def method(self):
def noargs(self):
return "Base"
def int_arg(self, i):
return "Base"
@classmethod
def _class(tp):
return "Base"
class Derived(Base):
'''
>>> derived = Derived()
>>> print(derived.method())
>>> print(derived.noargs())
Derived
>>> print(derived.int_arg(1))
Derived
>>> print(derived._class())
Derived
'''
def method(self):
def noargs(self):
return "Derived"
def int_arg(self, i):
return "Derived"
@classmethod
def _class(tp):
return "Derived"
class DerivedDerived(Derived):
'''
>>> derived = DerivedDerived()
>>> print(derived.noargs())
DerivedDerived
>>> print(derived.int_arg(1))
DerivedDerived
>>> print(derived._class())
DerivedDerived
'''
def noargs(self):
return "DerivedDerived"
def int_arg(self, i):
return "DerivedDerived"
@classmethod
def _class(tp):
return "DerivedDerived"
class Derived2(Base):
'''
>>> derived = Derived2()
>>> print(derived.noargs())
Derived2
>>> print(derived.int_arg(1))
Derived2
>>> print(derived._class())
Derived2
'''
def noargs(self):
return "Derived2"
def int_arg(self, i):
return "Derived2"
@classmethod
def _class(tp):
return "Derived2"
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