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,
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.
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,
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
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.
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"