Commit 27f8ddb6 authored by Stefan Behnel's avatar Stefan Behnel

fix #855: make "import *" include all necessary "from_py" coercion helper functions

parent 77bb90df
......@@ -8,6 +8,10 @@ Latest changes
Bugs fixed
----------
* Code that uses "from xyz import *" and global C struct/union/array
variables could fail to compile due to missing helper functions.
This fixes ticket 851.
* Misnamed PEP 492 coroutine property ``cr_yieldfrom`` renamed to
``cr_await`` to match CPython.
......
......@@ -102,6 +102,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.directives = self.directives
self.body.analyse_declarations(env)
def prepare_utility_code(self):
# prepare any utility code that must be created before code generation
# specifically: CythonUtilityCode
env = self.scope
if env.has_import_star:
self.create_import_star_conversion_utility_code(env)
def process_implementation(self, options, result):
env = self.scope
env.return_type = PyrexTypes.c_void_type
......@@ -1964,6 +1971,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"};")
def create_import_star_conversion_utility_code(self, env):
# Create all conversion helpers that are needed for "import *" assignments.
# Must be done before code generation to support CythonUtilityCode.
for name, entry in env.entries.items():
if entry.is_cglobal and entry.used:
if not entry.type.is_pyobject:
entry.type.create_from_py_utility_code(env)
def generate_import_star(self, env, code):
env.use_utility_code(UtilityCode.load_cached("CStringEquals", "StringTools.c"))
code.putln()
......@@ -2001,7 +2016,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("%s = %s;" % (
entry.cname,
PyrexTypes.typecast(entry.type, py_object_type, "o")))
elif entry.type.from_py_function:
elif entry.type.create_from_py_utility_code(env):
# if available, utility code was already created in self.prepare_utility_code()
rhs = "%s(o)" % entry.type.from_py_function
if entry.type.is_enum:
rhs = PyrexTypes.typecast(entry.type, PyrexTypes.c_long_type, rhs)
......
......@@ -80,6 +80,7 @@ def use_utility_code_definitions(scope, target, seen=None):
def inject_utility_code_stage_factory(context):
def inject_utility_code_stage(module_node):
module_node.prepare_utility_code()
use_utility_code_definitions(context.cython_scope, module_node.scope)
added = []
# Note: the list might be extended inside the loop (if some utility code
......
# mode: run
cdef object executable, version_info
cdef long hexversion
ctypedef struct MyStruct:
int x, y, z
# conversion code for this struct will be generated but not used
# (there used to be a problem getting Cython conversion code generated here)
cdef MyStruct _no_such_name_ = MyStruct(1, 2, 3)
from sys import *
def test_cdefed_objects():
"""
>>> ex, vi = test_cdefed_objects()
......@@ -12,6 +22,7 @@ def test_cdefed_objects():
"""
return executable, version_info
def test_cdefed_cvalues():
"""
>>> hexver = test_cdefed_cvalues()
......@@ -20,6 +31,7 @@ def test_cdefed_cvalues():
"""
return hexversion
def test_non_cdefed_names():
"""
>>> mod, pth = test_non_cdefed_names()
......
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