Commit 3069c3e5 authored by Haoyu Bai's avatar Haoyu Bai

fix T477 by refactor FuncDefNode, so cython decorators can applied to cdef function

parent f7d7598f
...@@ -1191,6 +1191,22 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1191,6 +1191,22 @@ class FuncDefNode(StatNode, BlockNode):
elif default_seen: elif default_seen:
error(arg.pos, "Non-default argument following default argument") 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): def need_gil_acquisition(self, lenv):
return 0 return 0
...@@ -1646,6 +1662,7 @@ class CFuncDefNode(FuncDefNode): ...@@ -1646,6 +1662,7 @@ class CFuncDefNode(FuncDefNode):
declarator = declarator.base declarator = declarator.base
self.args = declarator.args self.args = declarator.args
for formal_arg, type_arg in zip(self.args, type.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.type = type_arg.type
formal_arg.name = type_arg.name formal_arg.name = type_arg.name
formal_arg.cname = type_arg.cname formal_arg.cname = type_arg.cname
...@@ -2017,28 +2034,18 @@ class DefNode(FuncDefNode): ...@@ -2017,28 +2034,18 @@ class DefNode(FuncDefNode):
allow_none_for_extension_args = env.directives['allow_none_for_extension_args'] allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
for arg in self.args: for arg in self.args:
if hasattr(arg, 'name'): if hasattr(arg, 'name'):
type = arg.type
name_declarator = None name_declarator = None
else: else:
base_type = arg.base_type.analyse(env) base_type = arg.base_type.analyse(env)
name_declarator, type = \ name_declarator, type = \
arg.declarator.analyse(base_type, env) arg.declarator.analyse(base_type, env)
arg.name = name_declarator.name arg.name = name_declarator.name
if arg.name in directive_locals: arg.type = type
type_node = directive_locals[arg.name] self.align_argument_type(env, arg)
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
if name_declarator and name_declarator.cname: if name_declarator and name_declarator.cname:
error(self.pos, error(self.pos,
"Python function argument cannot have C name specification") "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.hdr_type = None
arg.needs_conversion = 0 arg.needs_conversion = 0
arg.needs_type_test = 0 arg.needs_type_test = 0
......
import cython
@cython.locals(x=double)
cdef func(x):
return x**2
def test():
"""
>>> isinstance(test(), float)
True
"""
return func(2)
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