From 3069c3e516fc7336b003861881623f30e168849e Mon Sep 17 00:00:00 2001 From: Haoyu Bai Date: Thu, 31 Mar 2011 04:19:14 +0800 Subject: [PATCH] fix T477 by refactor FuncDefNode, so cython decorators can applied to cdef function --- Cython/Compiler/Nodes.py | 33 ++++++++++++++---------- tests/run/cdef_locals_decorator_T477.pyx | 11 ++++++++ 2 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 tests/run/cdef_locals_decorator_T477.pyx diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 609489f1..476a8922 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1191,6 +1191,22 @@ class FuncDefNode(StatNode, BlockNode): elif default_seen: error(arg.pos, "Non-default argument following default argument") + def align_argument_type(self, env, arg): + directive_locals = self.directive_locals + type = arg.type + if arg.name in directive_locals: + type_node = directive_locals[arg.name] + other_type = type_node.analyse_as_type(env) + if other_type is None: + error(type_node.pos, "Not a type") + elif (type is not PyrexTypes.py_object_type + and not type.same_as(other_type)): + error(arg.base_type.pos, "Signature does not agree with previous declaration") + error(type_node.pos, "Previous declaration here") + else: + arg.type = other_type + return arg + def need_gil_acquisition(self, lenv): return 0 @@ -1646,6 +1662,7 @@ class CFuncDefNode(FuncDefNode): declarator = declarator.base self.args = declarator.args for formal_arg, type_arg in zip(self.args, type.args): + self.align_argument_type(env, type_arg) formal_arg.type = type_arg.type formal_arg.name = type_arg.name formal_arg.cname = type_arg.cname @@ -2017,28 +2034,18 @@ class DefNode(FuncDefNode): allow_none_for_extension_args = env.directives['allow_none_for_extension_args'] for arg in self.args: if hasattr(arg, 'name'): - type = arg.type name_declarator = None else: base_type = arg.base_type.analyse(env) name_declarator, type = \ arg.declarator.analyse(base_type, env) arg.name = name_declarator.name - if arg.name in directive_locals: - type_node = directive_locals[arg.name] - other_type = type_node.analyse_as_type(env) - if other_type is None: - error(type_node.pos, "Not a type") - elif (type is not PyrexTypes.py_object_type - and not type.same_as(other_type)): - error(arg.base_type.pos, "Signature does not agree with previous declaration") - error(type_node.pos, "Previous declaration here") - else: - type = other_type + arg.type = type + self.align_argument_type(env, arg) if name_declarator and name_declarator.cname: error(self.pos, "Python function argument cannot have C name specification") - arg.type = type.as_argument_type() + arg.type = arg.type.as_argument_type() arg.hdr_type = None arg.needs_conversion = 0 arg.needs_type_test = 0 diff --git a/tests/run/cdef_locals_decorator_T477.pyx b/tests/run/cdef_locals_decorator_T477.pyx new file mode 100644 index 00000000..35aae28b --- /dev/null +++ b/tests/run/cdef_locals_decorator_T477.pyx @@ -0,0 +1,11 @@ +import cython +@cython.locals(x=double) +cdef func(x): + return x**2 + +def test(): + """ + >>> isinstance(test(), float) + True + """ + return func(2) -- 2.26.2