Spaces:
Runtime error
Runtime error
| """Cython.Distutils.old_build_ext | |
| Implements a version of the Distutils 'build_ext' command, for | |
| building Cython extension modules. | |
| Note that this module is deprecated. Use cythonize() instead. | |
| """ | |
| __revision__ = "$Id:$" | |
| import inspect | |
| import sys | |
| import os | |
| from distutils.errors import DistutilsPlatformError | |
| from distutils.dep_util import newer, newer_group | |
| from distutils import log | |
| from distutils.command import build_ext as _build_ext | |
| from distutils import sysconfig | |
| import warnings | |
| try: | |
| from __builtin__ import basestring | |
| except ImportError: | |
| basestring = str | |
| def _check_stack(path): | |
| try: | |
| for frame in inspect.getouterframes(inspect.currentframe(), 0): | |
| if path in frame[1].replace(os.sep, '/'): | |
| return True | |
| except Exception: | |
| pass | |
| return False | |
| if (not _check_stack('setuptools/extensions.py') | |
| and not _check_stack('pyximport/pyxbuild.py') | |
| and not _check_stack('Cython/Distutils/build_ext.py')): | |
| warnings.warn( | |
| "Cython.Distutils.old_build_ext does not properly handle dependencies " | |
| "and is deprecated.") | |
| extension_name_re = _build_ext.extension_name_re | |
| show_compilers = _build_ext.show_compilers | |
| class Optimization(object): | |
| def __init__(self): | |
| self.flags = ( | |
| 'OPT', | |
| 'CFLAGS', | |
| 'CPPFLAGS', | |
| 'EXTRA_CFLAGS', | |
| 'BASECFLAGS', | |
| 'PY_CFLAGS', | |
| ) | |
| self.state = sysconfig.get_config_vars(*self.flags) | |
| self.config_vars = sysconfig.get_config_vars() | |
| def disable_optimization(self): | |
| "disable optimization for the C or C++ compiler" | |
| badoptions = ('-O1', '-O2', '-O3') | |
| for flag, option in zip(self.flags, self.state): | |
| if option is not None: | |
| L = [opt for opt in option.split() if opt not in badoptions] | |
| self.config_vars[flag] = ' '.join(L) | |
| def restore_state(self): | |
| "restore the original state" | |
| for flag, option in zip(self.flags, self.state): | |
| if option is not None: | |
| self.config_vars[flag] = option | |
| optimization = Optimization() | |
| class old_build_ext(_build_ext.build_ext): | |
| description = "build C/C++ and Cython extensions (compile/link to build directory)" | |
| sep_by = _build_ext.build_ext.sep_by | |
| user_options = _build_ext.build_ext.user_options[:] | |
| boolean_options = _build_ext.build_ext.boolean_options[:] | |
| help_options = _build_ext.build_ext.help_options[:] | |
| # Add the pyrex specific data. | |
| user_options.extend([ | |
| ('cython-cplus', None, | |
| "generate C++ source files"), | |
| ('cython-create-listing', None, | |
| "write errors to a listing file"), | |
| ('cython-line-directives', None, | |
| "emit source line directives"), | |
| ('cython-include-dirs=', None, | |
| "path to the Cython include files" + sep_by), | |
| ('cython-c-in-temp', None, | |
| "put generated C files in temp directory"), | |
| ('cython-gen-pxi', None, | |
| "generate .pxi file for public declarations"), | |
| ('cython-directives=', None, | |
| "compiler directive overrides"), | |
| ('cython-gdb', None, | |
| "generate debug information for cygdb"), | |
| ('cython-compile-time-env', None, | |
| "cython compile time environment"), | |
| # For backwards compatibility. | |
| ('pyrex-cplus', None, | |
| "generate C++ source files"), | |
| ('pyrex-create-listing', None, | |
| "write errors to a listing file"), | |
| ('pyrex-line-directives', None, | |
| "emit source line directives"), | |
| ('pyrex-include-dirs=', None, | |
| "path to the Cython include files" + sep_by), | |
| ('pyrex-c-in-temp', None, | |
| "put generated C files in temp directory"), | |
| ('pyrex-gen-pxi', None, | |
| "generate .pxi file for public declarations"), | |
| ('pyrex-directives=', None, | |
| "compiler directive overrides"), | |
| ('pyrex-gdb', None, | |
| "generate debug information for cygdb"), | |
| ]) | |
| boolean_options.extend([ | |
| 'cython-cplus', 'cython-create-listing', 'cython-line-directives', | |
| 'cython-c-in-temp', 'cython-gdb', | |
| # For backwards compatibility. | |
| 'pyrex-cplus', 'pyrex-create-listing', 'pyrex-line-directives', | |
| 'pyrex-c-in-temp', 'pyrex-gdb', | |
| ]) | |
| def initialize_options(self): | |
| _build_ext.build_ext.initialize_options(self) | |
| self.cython_cplus = 0 | |
| self.cython_create_listing = 0 | |
| self.cython_line_directives = 0 | |
| self.cython_include_dirs = None | |
| self.cython_directives = None | |
| self.cython_c_in_temp = 0 | |
| self.cython_gen_pxi = 0 | |
| self.cython_gdb = False | |
| self.no_c_in_traceback = 0 | |
| self.cython_compile_time_env = None | |
| def __getattr__(self, name): | |
| if name[:6] == 'pyrex_': | |
| return getattr(self, 'cython_' + name[6:]) | |
| else: | |
| return _build_ext.build_ext.__getattr__(self, name) | |
| def __setattr__(self, name, value): | |
| if name[:6] == 'pyrex_': | |
| return setattr(self, 'cython_' + name[6:], value) | |
| else: | |
| # _build_ext.build_ext.__setattr__(self, name, value) | |
| self.__dict__[name] = value | |
| def finalize_options (self): | |
| _build_ext.build_ext.finalize_options(self) | |
| if self.cython_include_dirs is None: | |
| self.cython_include_dirs = [] | |
| elif isinstance(self.cython_include_dirs, basestring): | |
| self.cython_include_dirs = \ | |
| self.cython_include_dirs.split(os.pathsep) | |
| if self.cython_directives is None: | |
| self.cython_directives = {} | |
| # finalize_options () | |
| def run(self): | |
| # We have one shot at this before build_ext initializes the compiler. | |
| # If --pyrex-gdb is in effect as a command line option or as option | |
| # of any Extension module, disable optimization for the C or C++ | |
| # compiler. | |
| if self.cython_gdb or [1 for ext in self.extensions | |
| if getattr(ext, 'cython_gdb', False)]: | |
| optimization.disable_optimization() | |
| _build_ext.build_ext.run(self) | |
| def build_extensions(self): | |
| # First, sanity-check the 'extensions' list | |
| self.check_extensions_list(self.extensions) | |
| for ext in self.extensions: | |
| ext.sources = self.cython_sources(ext.sources, ext) | |
| # Call original build_extensions | |
| _build_ext.build_ext.build_extensions(self) | |
| def cython_sources(self, sources, extension): | |
| """ | |
| Walk the list of source files in 'sources', looking for Cython | |
| source files (.pyx and .py). Run Cython on all that are | |
| found, and return a modified 'sources' list with Cython source | |
| files replaced by the generated C (or C++) files. | |
| """ | |
| try: | |
| from Cython.Compiler.Main \ | |
| import CompilationOptions, \ | |
| default_options as cython_default_options, \ | |
| compile as cython_compile | |
| from Cython.Compiler.Errors import PyrexError | |
| except ImportError: | |
| e = sys.exc_info()[1] | |
| print("failed to import Cython: %s" % e) | |
| raise DistutilsPlatformError("Cython does not appear to be installed") | |
| new_sources = [] | |
| cython_sources = [] | |
| cython_targets = {} | |
| # Setup create_list and cplus from the extension options if | |
| # Cython.Distutils.extension.Extension is used, otherwise just | |
| # use what was parsed from the command-line or the configuration file. | |
| # cplus will also be set to true is extension.language is equal to | |
| # 'C++' or 'c++'. | |
| #try: | |
| # create_listing = self.cython_create_listing or \ | |
| # extension.cython_create_listing | |
| # cplus = self.cython_cplus or \ | |
| # extension.cython_cplus or \ | |
| # (extension.language != None and \ | |
| # extension.language.lower() == 'c++') | |
| #except AttributeError: | |
| # create_listing = self.cython_create_listing | |
| # cplus = self.cython_cplus or \ | |
| # (extension.language != None and \ | |
| # extension.language.lower() == 'c++') | |
| create_listing = self.cython_create_listing or \ | |
| getattr(extension, 'cython_create_listing', 0) | |
| line_directives = self.cython_line_directives or \ | |
| getattr(extension, 'cython_line_directives', 0) | |
| no_c_in_traceback = self.no_c_in_traceback or \ | |
| getattr(extension, 'no_c_in_traceback', 0) | |
| cplus = self.cython_cplus or getattr(extension, 'cython_cplus', 0) or \ | |
| (extension.language and extension.language.lower() == 'c++') | |
| cython_gen_pxi = self.cython_gen_pxi or getattr(extension, 'cython_gen_pxi', 0) | |
| cython_gdb = self.cython_gdb or getattr(extension, 'cython_gdb', False) | |
| cython_compile_time_env = self.cython_compile_time_env or \ | |
| getattr(extension, 'cython_compile_time_env', None) | |
| # Set up the include_path for the Cython compiler: | |
| # 1. Start with the command line option. | |
| # 2. Add in any (unique) paths from the extension | |
| # cython_include_dirs (if Cython.Distutils.extension is used). | |
| # 3. Add in any (unique) paths from the extension include_dirs | |
| includes = self.cython_include_dirs | |
| try: | |
| for i in extension.cython_include_dirs: | |
| if not i in includes: | |
| includes.append(i) | |
| except AttributeError: | |
| pass | |
| # In case extension.include_dirs is a generator, evaluate it and keep | |
| # result | |
| extension.include_dirs = list(extension.include_dirs) | |
| for i in extension.include_dirs: | |
| if not i in includes: | |
| includes.append(i) | |
| # Set up Cython compiler directives: | |
| # 1. Start with the command line option. | |
| # 2. Add in any (unique) entries from the extension | |
| # cython_directives (if Cython.Distutils.extension is used). | |
| directives = self.cython_directives | |
| if hasattr(extension, "cython_directives"): | |
| directives.update(extension.cython_directives) | |
| # Set the target_ext to '.c'. Cython will change this to '.cpp' if | |
| # needed. | |
| if cplus: | |
| target_ext = '.cpp' | |
| else: | |
| target_ext = '.c' | |
| # Decide whether to drop the generated C files into the temp dir | |
| # or the source tree. | |
| if not self.inplace and (self.cython_c_in_temp | |
| or getattr(extension, 'cython_c_in_temp', 0)): | |
| target_dir = os.path.join(self.build_temp, "pyrex") | |
| for package_name in extension.name.split('.')[:-1]: | |
| target_dir = os.path.join(target_dir, package_name) | |
| else: | |
| target_dir = None | |
| newest_dependency = None | |
| for source in sources: | |
| (base, ext) = os.path.splitext(os.path.basename(source)) | |
| if ext == ".py": | |
| # FIXME: we might want to special case this some more | |
| ext = '.pyx' | |
| if ext == ".pyx": # Cython source file | |
| output_dir = target_dir or os.path.dirname(source) | |
| new_sources.append(os.path.join(output_dir, base + target_ext)) | |
| cython_sources.append(source) | |
| cython_targets[source] = new_sources[-1] | |
| elif ext == '.pxi' or ext == '.pxd': | |
| if newest_dependency is None \ | |
| or newer(source, newest_dependency): | |
| newest_dependency = source | |
| else: | |
| new_sources.append(source) | |
| if not cython_sources: | |
| return new_sources | |
| module_name = extension.name | |
| for source in cython_sources: | |
| target = cython_targets[source] | |
| depends = [source] + list(extension.depends or ()) | |
| if(source[-4:].lower()==".pyx" and os.path.isfile(source[:-3]+"pxd")): | |
| depends += [source[:-3]+"pxd"] | |
| rebuild = self.force or newer_group(depends, target, 'newer') | |
| if not rebuild and newest_dependency is not None: | |
| rebuild = newer(newest_dependency, target) | |
| if rebuild: | |
| log.info("cythoning %s to %s", source, target) | |
| self.mkpath(os.path.dirname(target)) | |
| if self.inplace: | |
| output_dir = os.curdir | |
| else: | |
| output_dir = self.build_lib | |
| options = CompilationOptions(cython_default_options, | |
| use_listing_file = create_listing, | |
| include_path = includes, | |
| compiler_directives = directives, | |
| output_file = target, | |
| cplus = cplus, | |
| emit_linenums = line_directives, | |
| c_line_in_traceback = not no_c_in_traceback, | |
| generate_pxi = cython_gen_pxi, | |
| output_dir = output_dir, | |
| gdb_debug = cython_gdb, | |
| compile_time_env = cython_compile_time_env) | |
| result = cython_compile(source, options=options, | |
| full_module_name=module_name) | |
| else: | |
| log.info("skipping '%s' Cython extension (up-to-date)", target) | |
| return new_sources | |
| # cython_sources () | |
| # class build_ext | |