Commit 0c46b7d2 authored by Stefan Behnel's avatar Stefan Behnel

work around inability to detect existing Python globals (e.g. from imports)...

work around inability to detect existing Python globals (e.g. from imports) when cpdef-ing global functions
parent 8df921a6
...@@ -1997,6 +1997,7 @@ class AdjustDefByDirectives(CythonTransform, SkipDeclarations): ...@@ -1997,6 +1997,7 @@ class AdjustDefByDirectives(CythonTransform, SkipDeclarations):
self.in_py_class = old_in_pyclass self.in_py_class = old_in_pyclass
return node return node
class AlignFunctionDefinitions(CythonTransform): class AlignFunctionDefinitions(CythonTransform):
""" """
This class takes the signatures from a .pxd file and applies them to This class takes the signatures from a .pxd file and applies them to
...@@ -2006,6 +2007,7 @@ class AlignFunctionDefinitions(CythonTransform): ...@@ -2006,6 +2007,7 @@ class AlignFunctionDefinitions(CythonTransform):
def visit_ModuleNode(self, node): def visit_ModuleNode(self, node):
self.scope = node.scope self.scope = node.scope
self.directives = node.directives self.directives = node.directives
self.imported_names = set() # hack, see visit_FromImportStatNode()
self.visitchildren(node) self.visitchildren(node)
return node return node
...@@ -2042,12 +2044,23 @@ class AlignFunctionDefinitions(CythonTransform): ...@@ -2042,12 +2044,23 @@ class AlignFunctionDefinitions(CythonTransform):
return None return None
node = node.as_cfunction(pxd_def) node = node.as_cfunction(pxd_def)
elif (self.scope.is_module_scope and self.directives['auto_cpdef'] elif (self.scope.is_module_scope and self.directives['auto_cpdef']
and not node.name in self.imported_names
and node.is_cdef_func_compatible()): and node.is_cdef_func_compatible()):
# FIXME: cpdef-ing should be done in analyse_declarations()
node = node.as_cfunction(scope=self.scope) node = node.as_cfunction(scope=self.scope)
# Enable this when nested cdef functions are allowed. # Enable this when nested cdef functions are allowed.
# self.visitchildren(node) # self.visitchildren(node)
return node return node
def visit_FromImportStatNode(self, node):
# hack to prevent conditional import fallback functions from
# being cdpef-ed (global Python variables currently conflict
# with imports)
if self.scope.is_module_scope:
for name, _ in node.items:
self.imported_names.add(name)
return node
def visit_ExprNode(self, node): def visit_ExprNode(self, node):
# ignore lambdas and everything else that appears in expressions # ignore lambdas and everything else that appears in expressions
return node return node
......
...@@ -45,3 +45,32 @@ def test_lambda(): ...@@ -45,3 +45,32 @@ def test_lambda():
>>> l(1) >>> l(1)
1 1
""" """
# test classical import fallbacks
try:
from math import fabs
except ImportError:
def fabs(x):
if x < 0:
return -x
else:
return x
try:
from math import no_such_function
except ImportError:
def no_such_function(x):
return x + 1.0
def test_import_fallback():
"""
>>> fabs(1.0)
1.0
>>> no_such_function(1.0)
2.0
>>> test_import_fallback()
(1.0, 2.0)
"""
return fabs(1.0), no_such_function(1.0)
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