Commit 148a8c6b authored by Lisandro Dalcin's avatar Lisandro Dalcin

Merge branch 'T477-fix' of https://github.com/bhy/cython into bhy-T477-fix

parents 4e6939e9 c08d22ce
......@@ -535,7 +535,7 @@ class CFuncDeclaratorNode(CDeclaratorNode):
overridable = 0
optional_arg_count = 0
def analyse(self, return_type, env, nonempty = 0):
def analyse(self, return_type, env, nonempty = 0, directive_locals = {}):
if nonempty:
nonempty -= 1
func_type_args = []
......@@ -543,6 +543,17 @@ class CFuncDeclaratorNode(CDeclaratorNode):
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 in directive_locals:
type_node = directive_locals[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(self.base.pos, "Signature does not agree with previous declaration")
error(type_node.pos, "Previous declaration here")
else:
type = other_type
if name_declarator.cname:
error(self.pos,
"Function argument cannot have C name specification")
......@@ -946,7 +957,10 @@ class CVarDefNode(StatNode):
visibility = self.visibility
for declarator in self.declarators:
name_declarator, type = declarator.analyse(base_type, env)
if isinstance(declarator, CFuncDeclaratorNode):
name_declarator, type = declarator.analyse(base_type, env, directive_locals=self.directive_locals)
else:
name_declarator, type = declarator.analyse(base_type, env)
if not type.is_complete():
if not (self.visibility == 'extern' and type.is_array):
error(declarator.pos,
......@@ -1659,7 +1673,12 @@ class CFuncDefNode(FuncDefNode):
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.
name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
if isinstance(self.declarator, CFuncDeclaratorNode):
name_declarator, type = self.declarator.analyse(base_type, env,
nonempty = 2 * (self.body is not None),
directive_locals = self.directive_locals)
else:
name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
if not type.is_cfunction:
error(self.pos,
"Suite attached to non-function declaration")
......
......@@ -5,6 +5,10 @@ import cython
cdef func(x):
return x**2
@cython.locals(x=double)
cdef func_defval(x=0):
return x**2
def test():
"""
>>> isinstance(test(), float)
......
cimport cython
@cython.locals(egg=double)
cdef foo(egg)
@cython.locals(egg=cython.double)
cdef foo_defval(egg=*)
@cython.locals(egg=cython.bint, v=cython.int)
cpdef cpfoo(egg=*)
import cython
def foo(egg):
if not cython.compiled:
egg = float(egg)
return egg
def foo_defval(egg=1):
if not cython.compiled:
egg = float(egg)
return egg**2
def cpfoo(egg=False):
if not cython.compiled:
egg = bool(egg)
v = int(not egg)
else:
v = not egg
return egg, v
def test_pxd_locals():
"""
>>> v1, v2, v3 = test_pxd_locals()
>>> isinstance(v1, float)
True
>>> isinstance(v2, float)
True
>>> v3
(True, 0)
"""
return foo(1), foo_defval(), cpfoo(1)
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