From 600d330273c9dbfd1110477708694bdf6b98a0db Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 27 Nov 2009 17:51:44 +0100 Subject: [PATCH] fix #454: type of first parameter in classmethods --- Cython/Compiler/Nodes.py | 30 ++++++++++++++++++++++++++---- tests/bugs.txt | 1 - 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 1f9f3aba..d779fd02 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -598,11 +598,13 @@ class CArgDeclNode(Node): # default ExprNode or None # default_value PyObjectConst constant for default value # is_self_arg boolean Is the "self" arg of an extension type method + # is_type_arg boolean Is the "class" arg of an extension type classmethod # is_kw_only boolean Is a keyword-only argument child_attrs = ["base_type", "declarator", "default"] is_self_arg = 0 + is_type_arg = 0 is_generic = 1 type = None name_declarator = None @@ -669,6 +671,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode): # longness integer # complex boolean # is_self_arg boolean Is self argument of C method + # is_type_arg boolean Is type argument of class method child_attrs = [] arg_name = None # in case the argument name was interpreted as a type @@ -1710,6 +1713,21 @@ class DefNode(FuncDefNode): self.create_local_scope(env) def analyse_signature(self, env): + self.is_classmethod = self.is_staticmethod = False + if self.decorators: + for decorator in self.decorators: + func = decorator.decorator + if func.is_name: + self.is_classmethod |= func.name == 'classmethod' + self.is_staticmethod |= func.name == 'staticmethod' + + if self.is_classmethod and env.lookup_here('classmethod'): + # classmethod() was overridden - not much we can do here ... + self.is_classmethod = False + if self.is_staticmethod and env.lookup_here('staticmethod'): + # staticmethod() was overridden - not much we can do here ... + self.is_staticmethod = False + any_type_tests_needed = 0 if self.entry.is_special: self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg) @@ -1733,9 +1751,13 @@ class DefNode(FuncDefNode): if i < len(self.args): arg = self.args[i] arg.is_generic = 0 - if sig.is_self_arg(i): - arg.is_self_arg = 1 - arg.hdr_type = arg.type = env.parent_type + if sig.is_self_arg(i) and not self.is_staticmethod: + if self.is_classmethod: + arg.is_type_arg = 1 + arg.hdr_type = arg.type = Builtin.type_type + else: + arg.is_self_arg = 1 + arg.hdr_type = arg.type = env.parent_type arg.needs_conversion = 0 else: arg.hdr_type = sig.fixed_arg_type(i) @@ -1762,7 +1784,7 @@ class DefNode(FuncDefNode): any_type_tests_needed = 1 if any_type_tests_needed: env.use_utility_code(arg_type_test_utility_code) - + def bad_signature(self): sig = self.entry.signature expected_str = "%d" % sig.num_fixed_args() diff --git a/tests/bugs.txt b/tests/bugs.txt index f0269ae5..55e7e2c3 100644 --- a/tests/bugs.txt +++ b/tests/bugs.txt @@ -6,5 +6,4 @@ class_attribute_init_values_T18 numpy_ValueError_T172 unsignedbehaviour_T184 missing_baseclass_in_predecl_T262 -tp_new_T454 cfunc_call_tuple_args_T408 -- 2.26.2