| Index: third_party/cython/src/Cython/Compiler/Main.py
|
| diff --git a/third_party/cython/src/Cython/Compiler/Main.py b/third_party/cython/src/Cython/Compiler/Main.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..727fe9bb521afa76df089405b2a159c3e733cd85
|
| --- /dev/null
|
| +++ b/third_party/cython/src/Cython/Compiler/Main.py
|
| @@ -0,0 +1,672 @@
|
| +#
|
| +# Cython Top Level
|
| +#
|
| +
|
| +import os, sys, re, codecs
|
| +if sys.version_info[:2] < (2, 4):
|
| + sys.stderr.write("Sorry, Cython requires Python 2.4 or later\n")
|
| + sys.exit(1)
|
| +
|
| +import Errors
|
| +# Do not import Parsing here, import it when needed, because Parsing imports
|
| +# Nodes, which globally needs debug command line options initialized to set a
|
| +# conditional metaclass. These options are processed by CmdLine called from
|
| +# main() in this file.
|
| +# import Parsing
|
| +import Version
|
| +from Scanning import PyrexScanner, FileSourceDescriptor
|
| +from Errors import PyrexError, CompileError, error, warning
|
| +from Symtab import ModuleScope
|
| +from Cython import Utils
|
| +import Options
|
| +
|
| +module_name_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$")
|
| +
|
| +verbose = 0
|
| +
|
| +class CompilationData(object):
|
| + # Bundles the information that is passed from transform to transform.
|
| + # (For now, this is only)
|
| +
|
| + # While Context contains every pxd ever loaded, path information etc.,
|
| + # this only contains the data related to a single compilation pass
|
| + #
|
| + # pyx ModuleNode Main code tree of this compilation.
|
| + # pxds {string : ModuleNode} Trees for the pxds used in the pyx.
|
| + # codewriter CCodeWriter Where to output final code.
|
| + # options CompilationOptions
|
| + # result CompilationResult
|
| + pass
|
| +
|
| +class Context(object):
|
| + # This class encapsulates the context needed for compiling
|
| + # one or more Cython implementation files along with their
|
| + # associated and imported declaration files. It includes
|
| + # the root of the module import namespace and the list
|
| + # of directories to search for include files.
|
| + #
|
| + # modules {string : ModuleScope}
|
| + # include_directories [string]
|
| + # future_directives [object]
|
| + # language_level int currently 2 or 3 for Python 2/3
|
| +
|
| + cython_scope = None
|
| +
|
| + def __init__(self, include_directories, compiler_directives, cpp=False,
|
| + language_level=2, options=None, create_testscope=True):
|
| + # cython_scope is a hack, set to False by subclasses, in order to break
|
| + # an infinite loop.
|
| + # Better code organization would fix it.
|
| +
|
| + import Builtin, CythonScope
|
| + self.modules = {"__builtin__" : Builtin.builtin_scope}
|
| + self.cython_scope = CythonScope.create_cython_scope(self)
|
| + self.modules["cython"] = self.cython_scope
|
| + self.include_directories = include_directories
|
| + self.future_directives = set()
|
| + self.compiler_directives = compiler_directives
|
| + self.cpp = cpp
|
| + self.options = options
|
| +
|
| + self.pxds = {} # full name -> node tree
|
| +
|
| + standard_include_path = os.path.abspath(os.path.normpath(
|
| + os.path.join(os.path.dirname(__file__), os.path.pardir, 'Includes')))
|
| + self.include_directories = include_directories + [standard_include_path]
|
| +
|
| + self.set_language_level(language_level)
|
| +
|
| + self.gdb_debug_outputwriter = None
|
| +
|
| + def set_language_level(self, level):
|
| + self.language_level = level
|
| + if level >= 3:
|
| + from Future import print_function, unicode_literals, absolute_import
|
| + self.future_directives.update([print_function, unicode_literals, absolute_import])
|
| + self.modules['builtins'] = self.modules['__builtin__']
|
| +
|
| + # pipeline creation functions can now be found in Pipeline.py
|
| +
|
| + def process_pxd(self, source_desc, scope, module_name):
|
| + import Pipeline
|
| + if isinstance(source_desc, FileSourceDescriptor) and source_desc._file_type == 'pyx':
|
| + source = CompilationSource(source_desc, module_name, os.getcwd())
|
| + result_sink = create_default_resultobj(source, self.options)
|
| + pipeline = Pipeline.create_pyx_as_pxd_pipeline(self, result_sink)
|
| + result = Pipeline.run_pipeline(pipeline, source)
|
| + else:
|
| + pipeline = Pipeline.create_pxd_pipeline(self, scope, module_name)
|
| + result = Pipeline.run_pipeline(pipeline, source_desc)
|
| + return result
|
| +
|
| + def nonfatal_error(self, exc):
|
| + return Errors.report_error(exc)
|
| +
|
| + def find_module(self, module_name,
|
| + relative_to = None, pos = None, need_pxd = 1, check_module_name = True):
|
| + # Finds and returns the module scope corresponding to
|
| + # the given relative or absolute module name. If this
|
| + # is the first time the module has been requested, finds
|
| + # the corresponding .pxd file and process it.
|
| + # If relative_to is not None, it must be a module scope,
|
| + # and the module will first be searched for relative to
|
| + # that module, provided its name is not a dotted name.
|
| + debug_find_module = 0
|
| + if debug_find_module:
|
| + print("Context.find_module: module_name = %s, relative_to = %s, pos = %s, need_pxd = %s" % (
|
| + module_name, relative_to, pos, need_pxd))
|
| +
|
| + scope = None
|
| + pxd_pathname = None
|
| + if check_module_name and not module_name_pattern.match(module_name):
|
| + if pos is None:
|
| + pos = (module_name, 0, 0)
|
| + raise CompileError(pos,
|
| + "'%s' is not a valid module name" % module_name)
|
| + if "." not in module_name and relative_to:
|
| + if debug_find_module:
|
| + print("...trying relative import")
|
| + scope = relative_to.lookup_submodule(module_name)
|
| + if not scope:
|
| + qualified_name = relative_to.qualify_name(module_name)
|
| + pxd_pathname = self.find_pxd_file(qualified_name, pos)
|
| + if pxd_pathname:
|
| + scope = relative_to.find_submodule(module_name)
|
| + if not scope:
|
| + if debug_find_module:
|
| + print("...trying absolute import")
|
| + scope = self
|
| + for name in module_name.split("."):
|
| + scope = scope.find_submodule(name)
|
| + if debug_find_module:
|
| + print("...scope =", scope)
|
| + if not scope.pxd_file_loaded:
|
| + if debug_find_module:
|
| + print("...pxd not loaded")
|
| + scope.pxd_file_loaded = 1
|
| + if not pxd_pathname:
|
| + if debug_find_module:
|
| + print("...looking for pxd file")
|
| + pxd_pathname = self.find_pxd_file(module_name, pos)
|
| + if debug_find_module:
|
| + print("......found ", pxd_pathname)
|
| + if not pxd_pathname and need_pxd:
|
| + package_pathname = self.search_include_directories(module_name, ".py", pos)
|
| + if package_pathname and package_pathname.endswith('__init__.py'):
|
| + pass
|
| + else:
|
| + error(pos, "'%s.pxd' not found" % module_name)
|
| + if pxd_pathname:
|
| + try:
|
| + if debug_find_module:
|
| + print("Context.find_module: Parsing %s" % pxd_pathname)
|
| + rel_path = module_name.replace('.', os.sep) + os.path.splitext(pxd_pathname)[1]
|
| + if not pxd_pathname.endswith(rel_path):
|
| + rel_path = pxd_pathname # safety measure to prevent printing incorrect paths
|
| + source_desc = FileSourceDescriptor(pxd_pathname, rel_path)
|
| + err, result = self.process_pxd(source_desc, scope, module_name)
|
| + if err:
|
| + raise err
|
| + (pxd_codenodes, pxd_scope) = result
|
| + self.pxds[module_name] = (pxd_codenodes, pxd_scope)
|
| + except CompileError:
|
| + pass
|
| + return scope
|
| +
|
| + def find_pxd_file(self, qualified_name, pos):
|
| + # Search include path for the .pxd file corresponding to the
|
| + # given fully-qualified module name.
|
| + # Will find either a dotted filename or a file in a
|
| + # package directory. If a source file position is given,
|
| + # the directory containing the source file is searched first
|
| + # for a dotted filename, and its containing package root
|
| + # directory is searched first for a non-dotted filename.
|
| + pxd = self.search_include_directories(qualified_name, ".pxd", pos, sys_path=True)
|
| + if pxd is None: # XXX Keep this until Includes/Deprecated is removed
|
| + if (qualified_name.startswith('python') or
|
| + qualified_name in ('stdlib', 'stdio', 'stl')):
|
| + standard_include_path = os.path.abspath(os.path.normpath(
|
| + os.path.join(os.path.dirname(__file__), os.path.pardir, 'Includes')))
|
| + deprecated_include_path = os.path.join(standard_include_path, 'Deprecated')
|
| + self.include_directories.append(deprecated_include_path)
|
| + try:
|
| + pxd = self.search_include_directories(qualified_name, ".pxd", pos)
|
| + finally:
|
| + self.include_directories.pop()
|
| + if pxd:
|
| + name = qualified_name
|
| + if name.startswith('python'):
|
| + warning(pos, "'%s' is deprecated, use 'cpython'" % name, 1)
|
| + elif name in ('stdlib', 'stdio'):
|
| + warning(pos, "'%s' is deprecated, use 'libc.%s'" % (name, name), 1)
|
| + elif name in ('stl'):
|
| + warning(pos, "'%s' is deprecated, use 'libcpp.*.*'" % name, 1)
|
| + if pxd is None and Options.cimport_from_pyx:
|
| + return self.find_pyx_file(qualified_name, pos)
|
| + return pxd
|
| +
|
| + def find_pyx_file(self, qualified_name, pos):
|
| + # Search include path for the .pyx file corresponding to the
|
| + # given fully-qualified module name, as for find_pxd_file().
|
| + return self.search_include_directories(qualified_name, ".pyx", pos)
|
| +
|
| + def find_include_file(self, filename, pos):
|
| + # Search list of include directories for filename.
|
| + # Reports an error and returns None if not found.
|
| + path = self.search_include_directories(filename, "", pos,
|
| + include=True)
|
| + if not path:
|
| + error(pos, "'%s' not found" % filename)
|
| + return path
|
| +
|
| + def search_include_directories(self, qualified_name, suffix, pos,
|
| + include=False, sys_path=False):
|
| + return Utils.search_include_directories(
|
| + tuple(self.include_directories), qualified_name, suffix, pos, include, sys_path)
|
| +
|
| + def find_root_package_dir(self, file_path):
|
| + return Utils.find_root_package_dir(file_path)
|
| +
|
| + def check_package_dir(self, dir, package_names):
|
| + return Utils.check_package_dir(dir, tuple(package_names))
|
| +
|
| + def c_file_out_of_date(self, source_path):
|
| + c_path = Utils.replace_suffix(source_path, ".c")
|
| + if not os.path.exists(c_path):
|
| + return 1
|
| + c_time = Utils.modification_time(c_path)
|
| + if Utils.file_newer_than(source_path, c_time):
|
| + return 1
|
| + pos = [source_path]
|
| + pxd_path = Utils.replace_suffix(source_path, ".pxd")
|
| + if os.path.exists(pxd_path) and Utils.file_newer_than(pxd_path, c_time):
|
| + return 1
|
| + for kind, name in self.read_dependency_file(source_path):
|
| + if kind == "cimport":
|
| + dep_path = self.find_pxd_file(name, pos)
|
| + elif kind == "include":
|
| + dep_path = self.search_include_directories(name, pos)
|
| + else:
|
| + continue
|
| + if dep_path and Utils.file_newer_than(dep_path, c_time):
|
| + return 1
|
| + return 0
|
| +
|
| + def find_cimported_module_names(self, source_path):
|
| + return [ name for kind, name in self.read_dependency_file(source_path)
|
| + if kind == "cimport" ]
|
| +
|
| + def is_package_dir(self, dir_path):
|
| + return Utils.is_package_dir(dir_path)
|
| +
|
| + def read_dependency_file(self, source_path):
|
| + dep_path = Utils.replace_suffix(source_path, ".dep")
|
| + if os.path.exists(dep_path):
|
| + f = open(dep_path, "rU")
|
| + chunks = [ line.strip().split(" ", 1)
|
| + for line in f.readlines()
|
| + if " " in line.strip() ]
|
| + f.close()
|
| + return chunks
|
| + else:
|
| + return ()
|
| +
|
| + def lookup_submodule(self, name):
|
| + # Look up a top-level module. Returns None if not found.
|
| + return self.modules.get(name, None)
|
| +
|
| + def find_submodule(self, name):
|
| + # Find a top-level module, creating a new one if needed.
|
| + scope = self.lookup_submodule(name)
|
| + if not scope:
|
| + scope = ModuleScope(name,
|
| + parent_module = None, context = self)
|
| + self.modules[name] = scope
|
| + return scope
|
| +
|
| + def parse(self, source_desc, scope, pxd, full_module_name):
|
| + if not isinstance(source_desc, FileSourceDescriptor):
|
| + raise RuntimeError("Only file sources for code supported")
|
| + source_filename = source_desc.filename
|
| + scope.cpp = self.cpp
|
| + # Parse the given source file and return a parse tree.
|
| + num_errors = Errors.num_errors
|
| + try:
|
| + f = Utils.open_source_file(source_filename, "rU")
|
| + try:
|
| + import Parsing
|
| + s = PyrexScanner(f, source_desc, source_encoding = f.encoding,
|
| + scope = scope, context = self)
|
| + tree = Parsing.p_module(s, pxd, full_module_name)
|
| + finally:
|
| + f.close()
|
| + except UnicodeDecodeError, e:
|
| + #import traceback
|
| + #traceback.print_exc()
|
| + line = 1
|
| + column = 0
|
| + msg = e.args[-1]
|
| + position = e.args[2]
|
| + encoding = e.args[0]
|
| +
|
| + f = open(source_filename, "rb")
|
| + try:
|
| + byte_data = f.read()
|
| + finally:
|
| + f.close()
|
| +
|
| + # FIXME: make this at least a little less inefficient
|
| + for idx, c in enumerate(byte_data):
|
| + if c in (ord('\n'), '\n'):
|
| + line += 1
|
| + column = 0
|
| + if idx == position:
|
| + break
|
| +
|
| + column += 1
|
| +
|
| + error((source_desc, line, column),
|
| + "Decoding error, missing or incorrect coding=<encoding-name> "
|
| + "at top of source (cannot decode with encoding %r: %s)" % (encoding, msg))
|
| +
|
| + if Errors.num_errors > num_errors:
|
| + raise CompileError()
|
| + return tree
|
| +
|
| + def extract_module_name(self, path, options):
|
| + # Find fully_qualified module name from the full pathname
|
| + # of a source file.
|
| + dir, filename = os.path.split(path)
|
| + module_name, _ = os.path.splitext(filename)
|
| + if "." in module_name:
|
| + return module_name
|
| + names = [module_name]
|
| + while self.is_package_dir(dir):
|
| + parent, package_name = os.path.split(dir)
|
| + if parent == dir:
|
| + break
|
| + names.append(package_name)
|
| + dir = parent
|
| + names.reverse()
|
| + return ".".join(names)
|
| +
|
| + def setup_errors(self, options, result):
|
| + Errors.reset() # clear any remaining error state
|
| + if options.use_listing_file:
|
| + result.listing_file = Utils.replace_suffix(source, ".lis")
|
| + path = result.listing_file
|
| + else:
|
| + path = None
|
| + Errors.open_listing_file(path=path,
|
| + echo_to_stderr=options.errors_to_stderr)
|
| +
|
| + def teardown_errors(self, err, options, result):
|
| + source_desc = result.compilation_source.source_desc
|
| + if not isinstance(source_desc, FileSourceDescriptor):
|
| + raise RuntimeError("Only file sources for code supported")
|
| + Errors.close_listing_file()
|
| + result.num_errors = Errors.num_errors
|
| + if result.num_errors > 0:
|
| + err = True
|
| + if err and result.c_file:
|
| + try:
|
| + Utils.castrate_file(result.c_file, os.stat(source_desc.filename))
|
| + except EnvironmentError:
|
| + pass
|
| + result.c_file = None
|
| +
|
| +def create_default_resultobj(compilation_source, options):
|
| + result = CompilationResult()
|
| + result.main_source_file = compilation_source.source_desc.filename
|
| + result.compilation_source = compilation_source
|
| + source_desc = compilation_source.source_desc
|
| + if options.output_file:
|
| + result.c_file = os.path.join(compilation_source.cwd, options.output_file)
|
| + else:
|
| + if options.cplus:
|
| + c_suffix = ".cpp"
|
| + else:
|
| + c_suffix = ".c"
|
| + result.c_file = Utils.replace_suffix(source_desc.filename, c_suffix)
|
| + return result
|
| +
|
| +def run_pipeline(source, options, full_module_name=None, context=None):
|
| + import Pipeline
|
| +
|
| + source_ext = os.path.splitext(source)[1]
|
| + options.configure_language_defaults(source_ext[1:]) # py/pyx
|
| + if context is None:
|
| + context = options.create_context()
|
| +
|
| + # Set up source object
|
| + cwd = os.getcwd()
|
| + abs_path = os.path.abspath(source)
|
| + full_module_name = full_module_name or context.extract_module_name(source, options)
|
| +
|
| + if options.relative_path_in_code_position_comments:
|
| + rel_path = full_module_name.replace('.', os.sep) + source_ext
|
| + if not abs_path.endswith(rel_path):
|
| + rel_path = source # safety measure to prevent printing incorrect paths
|
| + else:
|
| + rel_path = abs_path
|
| + source_desc = FileSourceDescriptor(abs_path, rel_path)
|
| + source = CompilationSource(source_desc, full_module_name, cwd)
|
| +
|
| + # Set up result object
|
| + result = create_default_resultobj(source, options)
|
| +
|
| + if options.annotate is None:
|
| + # By default, decide based on whether an html file already exists.
|
| + html_filename = os.path.splitext(result.c_file)[0] + ".html"
|
| + if os.path.exists(html_filename):
|
| + line = codecs.open(html_filename, "r", encoding="UTF-8").readline()
|
| + if line.startswith(u'<!-- Generated by Cython'):
|
| + options.annotate = True
|
| +
|
| + # Get pipeline
|
| + if source_ext.lower() == '.py' or not source_ext:
|
| + pipeline = Pipeline.create_py_pipeline(context, options, result)
|
| + else:
|
| + pipeline = Pipeline.create_pyx_pipeline(context, options, result)
|
| +
|
| + context.setup_errors(options, result)
|
| + err, enddata = Pipeline.run_pipeline(pipeline, source)
|
| + context.teardown_errors(err, options, result)
|
| + return result
|
| +
|
| +
|
| +#------------------------------------------------------------------------
|
| +#
|
| +# Main Python entry points
|
| +#
|
| +#------------------------------------------------------------------------
|
| +
|
| +class CompilationSource(object):
|
| + """
|
| + Contains the data necesarry to start up a compilation pipeline for
|
| + a single compilation unit.
|
| + """
|
| + def __init__(self, source_desc, full_module_name, cwd):
|
| + self.source_desc = source_desc
|
| + self.full_module_name = full_module_name
|
| + self.cwd = cwd
|
| +
|
| +class CompilationOptions(object):
|
| + """
|
| + Options to the Cython compiler:
|
| +
|
| + show_version boolean Display version number
|
| + use_listing_file boolean Generate a .lis file
|
| + errors_to_stderr boolean Echo errors to stderr when using .lis
|
| + include_path [string] Directories to search for include files
|
| + output_file string Name of generated .c file
|
| + generate_pxi boolean Generate .pxi file for public declarations
|
| + capi_reexport_cincludes
|
| + boolean Add cincluded headers to any auto-generated
|
| + header files.
|
| + timestamps boolean Only compile changed source files.
|
| + verbose boolean Always print source names being compiled
|
| + compiler_directives dict Overrides for pragma options (see Options.py)
|
| + evaluate_tree_assertions boolean Test support: evaluate parse tree assertions
|
| + language_level integer The Python language level: 2 or 3
|
| +
|
| + cplus boolean Compile as c++ code
|
| + """
|
| +
|
| + def __init__(self, defaults = None, **kw):
|
| + self.include_path = []
|
| + if defaults:
|
| + if isinstance(defaults, CompilationOptions):
|
| + defaults = defaults.__dict__
|
| + else:
|
| + defaults = default_options
|
| +
|
| + options = dict(defaults)
|
| + options.update(kw)
|
| +
|
| + directives = dict(options['compiler_directives']) # copy mutable field
|
| + options['compiler_directives'] = directives
|
| + if 'language_level' in directives and 'language_level' not in kw:
|
| + options['language_level'] = int(directives['language_level'])
|
| + if 'cache' in options:
|
| + if options['cache'] is True:
|
| + options['cache'] = os.path.expanduser("~/.cycache")
|
| + elif options['cache'] in (False, None):
|
| + del options['cache']
|
| +
|
| + self.__dict__.update(options)
|
| +
|
| + def configure_language_defaults(self, source_extension):
|
| + if source_extension == 'py':
|
| + if self.compiler_directives.get('binding') is None:
|
| + self.compiler_directives['binding'] = True
|
| +
|
| + def create_context(self):
|
| + return Context(self.include_path, self.compiler_directives,
|
| + self.cplus, self.language_level, options=self)
|
| +
|
| +
|
| +class CompilationResult(object):
|
| + """
|
| + Results from the Cython compiler:
|
| +
|
| + c_file string or None The generated C source file
|
| + h_file string or None The generated C header file
|
| + i_file string or None The generated .pxi file
|
| + api_file string or None The generated C API .h file
|
| + listing_file string or None File of error messages
|
| + object_file string or None Result of compiling the C file
|
| + extension_file string or None Result of linking the object file
|
| + num_errors integer Number of compilation errors
|
| + compilation_source CompilationSource
|
| + """
|
| +
|
| + def __init__(self):
|
| + self.c_file = None
|
| + self.h_file = None
|
| + self.i_file = None
|
| + self.api_file = None
|
| + self.listing_file = None
|
| + self.object_file = None
|
| + self.extension_file = None
|
| + self.main_source_file = None
|
| +
|
| +
|
| +class CompilationResultSet(dict):
|
| + """
|
| + Results from compiling multiple Pyrex source files. A mapping
|
| + from source file paths to CompilationResult instances. Also
|
| + has the following attributes:
|
| +
|
| + num_errors integer Total number of compilation errors
|
| + """
|
| +
|
| + num_errors = 0
|
| +
|
| + def add(self, source, result):
|
| + self[source] = result
|
| + self.num_errors += result.num_errors
|
| +
|
| +
|
| +def compile_single(source, options, full_module_name = None):
|
| + """
|
| + compile_single(source, options, full_module_name)
|
| +
|
| + Compile the given Pyrex implementation file and return a CompilationResult.
|
| + Always compiles a single file; does not perform timestamp checking or
|
| + recursion.
|
| + """
|
| + return run_pipeline(source, options, full_module_name)
|
| +
|
| +
|
| +def compile_multiple(sources, options):
|
| + """
|
| + compile_multiple(sources, options)
|
| +
|
| + Compiles the given sequence of Pyrex implementation files and returns
|
| + a CompilationResultSet. Performs timestamp checking and/or recursion
|
| + if these are specified in the options.
|
| + """
|
| + # run_pipeline creates the context
|
| + # context = options.create_context()
|
| + sources = [os.path.abspath(source) for source in sources]
|
| + processed = set()
|
| + results = CompilationResultSet()
|
| + timestamps = options.timestamps
|
| + verbose = options.verbose
|
| + context = None
|
| + for source in sources:
|
| + if source not in processed:
|
| + if context is None:
|
| + context = options.create_context()
|
| + if not timestamps or context.c_file_out_of_date(source):
|
| + if verbose:
|
| + sys.stderr.write("Compiling %s\n" % source)
|
| +
|
| + result = run_pipeline(source, options, context=context)
|
| + results.add(source, result)
|
| + # Compiling multiple sources in one context doesn't quite
|
| + # work properly yet.
|
| + context = None
|
| + processed.add(source)
|
| + return results
|
| +
|
| +def compile(source, options = None, full_module_name = None, **kwds):
|
| + """
|
| + compile(source [, options], [, <option> = <value>]...)
|
| +
|
| + Compile one or more Pyrex implementation files, with optional timestamp
|
| + checking and recursing on dependecies. The source argument may be a string
|
| + or a sequence of strings If it is a string and no recursion or timestamp
|
| + checking is requested, a CompilationResult is returned, otherwise a
|
| + CompilationResultSet is returned.
|
| + """
|
| + options = CompilationOptions(defaults = options, **kwds)
|
| + if isinstance(source, basestring) and not options.timestamps:
|
| + return compile_single(source, options, full_module_name)
|
| + else:
|
| + return compile_multiple(source, options)
|
| +
|
| +#------------------------------------------------------------------------
|
| +#
|
| +# Main command-line entry point
|
| +#
|
| +#------------------------------------------------------------------------
|
| +def setuptools_main():
|
| + return main(command_line = 1)
|
| +
|
| +def main(command_line = 0):
|
| + args = sys.argv[1:]
|
| + any_failures = 0
|
| + if command_line:
|
| + from CmdLine import parse_command_line
|
| + options, sources = parse_command_line(args)
|
| + else:
|
| + options = CompilationOptions(default_options)
|
| + sources = args
|
| +
|
| + if options.show_version:
|
| + sys.stderr.write("Cython version %s\n" % Version.version)
|
| + if options.working_path!="":
|
| + os.chdir(options.working_path)
|
| + try:
|
| + result = compile(sources, options)
|
| + if result.num_errors > 0:
|
| + any_failures = 1
|
| + except (EnvironmentError, PyrexError), e:
|
| + sys.stderr.write(str(e) + '\n')
|
| + any_failures = 1
|
| + if any_failures:
|
| + sys.exit(1)
|
| +
|
| +
|
| +
|
| +#------------------------------------------------------------------------
|
| +#
|
| +# Set the default options depending on the platform
|
| +#
|
| +#------------------------------------------------------------------------
|
| +
|
| +default_options = dict(
|
| + show_version = 0,
|
| + use_listing_file = 0,
|
| + errors_to_stderr = 1,
|
| + cplus = 0,
|
| + output_file = None,
|
| + annotate = None,
|
| + generate_pxi = 0,
|
| + capi_reexport_cincludes = 0,
|
| + working_path = "",
|
| + timestamps = None,
|
| + verbose = 0,
|
| + quiet = 0,
|
| + compiler_directives = {},
|
| + evaluate_tree_assertions = False,
|
| + emit_linenums = False,
|
| + relative_path_in_code_position_comments = True,
|
| + c_line_in_traceback = True,
|
| + language_level = 2,
|
| + gdb_debug = False,
|
| + compile_time_env = None,
|
| + common_utility_include_dir = None,
|
| +)
|
|
|