Commit f69d1c2a authored by Mark Florisson's avatar Mark Florisson

Add Cython.Compiler.Importer to import code which relies on functionality that...

Add Cython.Compiler.Importer to import code which relies on functionality that is not portable across python versions
parent 5e6496af
...@@ -1943,7 +1943,9 @@ class PyrexCodeWriter(object): ...@@ -1943,7 +1943,9 @@ class PyrexCodeWriter(object):
class PyxCodeWriter(object): class PyxCodeWriter(object):
""" """
Can be used for writing out some Cython code. Can be used for writing out some Cython code. To use the indenter
functionality, the Cython.Compiler.Importer module will have to be used
to load the code to support python 2.4
""" """
def __init__(self, buffer=None, indent_level=0, context=None): def __init__(self, buffer=None, indent_level=0, context=None):
......
This diff is collapsed.
"""
Transparently import a module from the compiler on which the compiler
does not depend for its bootstrapping. This way one can write code
that is not supported in certain Python versions but which is supported
by Cython.
"""
import sys
import imp
import pyximport
# set up the PyxArgs global variable in pyximport (why is that a global :)
importers = pyximport.install(pyimport=True)
pyximport.uninstall(*importers)
def _import_normal(modulename):
# __import__ does not take keyword arguments under 2.4
return __import__(modulename, None, None, [''])
def _import_compile(modulename):
if '.' in modulename:
packagename, modulename = modulename.rsplit('.', 1)
__path__ = _import_normal(packagename).__path__
else:
__path__ = None
file, filename, description = imp.find_module(modulename, __path__)
if file:
file.close()
else:
raise ImportError(modulename)
return pyximport.load_module(modulename, filename)
def importer(modulename, compile=False, version=None):
"""
Import a module. If compile is true, always try to compile the .py file.
Otherwise, try a regular import and if that fails (i.e. there is a
syntax error, try to compile it.
"""
if version is not None and sys.version_info[:2] >= version:
return _import_normal(modulename)
if compile:
return _import_compile(modulename)
else:
try:
return _import_normal(modulename)
except SyntaxError:
return _import_compile(modulename)
This diff is collapsed.
...@@ -18,6 +18,7 @@ from Cython.Compiler.TreeFragment import TreeFragment ...@@ -18,6 +18,7 @@ from Cython.Compiler.TreeFragment import TreeFragment
from Cython.Compiler.StringEncoding import EncodedString from Cython.Compiler.StringEncoding import EncodedString
from Cython.Compiler.Errors import error, warning, CompileError, InternalError from Cython.Compiler.Errors import error, warning, CompileError, InternalError
from Cython.Compiler.Code import UtilityCode from Cython.Compiler.Code import UtilityCode
from Cython.Compiler import Importer
import copy import copy
...@@ -1488,7 +1489,8 @@ if VALUE is not None: ...@@ -1488,7 +1489,8 @@ if VALUE is not None:
return node return node
node = Nodes.FusedCFuncDefNode(node, env) FusedNode = Importer.importer("Cython.Compiler.FusedNode", version=(2, 5))
node = FusedNode.FusedCFuncDefNode(node, env)
self.fused_function = node self.fused_function = node
self.visitchildren(node) self.visitchildren(node)
......
...@@ -782,10 +782,9 @@ class BufferType(BaseType): ...@@ -782,10 +782,9 @@ class BufferType(BaseType):
def __str__(self): def __str__(self):
# avoid ', ', as fused functions split the signature string on ', ' # avoid ', ', as fused functions split the signature string on ', '
cast_str = ''
if self.cast: if self.cast:
cast_str = ',cast=True' cast_str = ',cast=True'
else:
cast_str = ''
return "%s[%s,ndim=%d%s]" % (self.base, self.dtype, self.ndim, return "%s[%s,ndim=%d%s]" % (self.base, self.dtype, self.ndim,
cast_str) cast_str)
......
...@@ -417,7 +417,8 @@ class Scope(object): ...@@ -417,7 +417,8 @@ class Scope(object):
# Add an entry for a type definition. # Add an entry for a type definition.
if not cname: if not cname:
cname = name cname = name
entry = self.declare(name, cname, type, pos, visibility, shadow, True) entry = self.declare(name, cname, type, pos, visibility, shadow,
is_type=True)
entry.is_type = 1 entry.is_type = 1
entry.api = api entry.api = api
if defining: if defining:
......
...@@ -374,6 +374,18 @@ class PyxArgs(object): ...@@ -374,6 +374,18 @@ class PyxArgs(object):
##pyxargs=None ##pyxargs=None
def _have_importers():
has_py_importer = False
has_pyx_importer = False
for importer in sys.meta_path:
if isinstance(importer, PyxImporter):
if isinstance(importer, PyImporter):
has_py_importer = True
else:
has_pyx_importer = True
return has_py_importer, has_pyx_importer
def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True, def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True,
setup_args={}, reload_support=False, setup_args={}, reload_support=False,
load_py_module_on_import_failure=False): load_py_module_on_import_failure=False):
...@@ -426,23 +438,32 @@ def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True, ...@@ -426,23 +438,32 @@ def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True,
pyxargs.reload_support = reload_support pyxargs.reload_support = reload_support
pyxargs.load_py_module_on_import_failure = load_py_module_on_import_failure pyxargs.load_py_module_on_import_failure = load_py_module_on_import_failure
has_py_importer = False has_py_importer, has_pyx_importer = _have_importers()
has_pyx_importer = False py_importer, pyx_importer = None, None
for importer in sys.meta_path:
if isinstance(importer, PyxImporter):
if isinstance(importer, PyImporter):
has_py_importer = True
else:
has_pyx_importer = True
if pyimport and not has_py_importer: if pyimport and not has_py_importer:
importer = PyImporter(pyxbuild_dir=build_dir) py_importer = PyImporter(pyxbuild_dir=build_dir)
sys.meta_path.insert(0, importer) sys.meta_path.insert(0, py_importer)
if pyximport and not has_pyx_importer: if pyximport and not has_pyx_importer:
importer = PyxImporter(pyxbuild_dir=build_dir) pyx_importer = PyxImporter(pyxbuild_dir=build_dir)
sys.meta_path.append(importer) sys.meta_path.append(pyx_importer)
return py_importer, pyx_importer
def uninstall(py_importer, pyx_importer):
"""
Uninstall an import hook.
"""
try:
sys.meta_path.remove(py_importer)
except ValueError:
pass
try:
sys.meta_path.remove(pyx_importer)
except ValueError:
pass
# MAIN # MAIN
......
...@@ -112,6 +112,7 @@ def compile_cython_modules(profile=False, compile_more=False, cython_with_refnan ...@@ -112,6 +112,7 @@ def compile_cython_modules(profile=False, compile_more=False, cython_with_refnan
"Cython.Compiler.FlowControl", "Cython.Compiler.FlowControl",
"Cython.Compiler.Code", "Cython.Compiler.Code",
"Cython.Runtime.refnanny", "Cython.Runtime.refnanny",
"Cython.Compiler.FusedNode",
] ]
if compile_more: if compile_more:
compiled_modules.extend([ compiled_modules.extend([
......
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