some new features
This commit is contained in:
255
.venv/lib/python3.12/site-packages/Cython/Build/Cythonize.py
Normal file
255
.venv/lib/python3.12/site-packages/Cython/Build/Cythonize.py
Normal file
@ -0,0 +1,255 @@
|
||||
from __future__ import absolute_import, print_function
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from .Dependencies import cythonize, extended_iglob
|
||||
from ..Utils import is_package_dir
|
||||
from ..Compiler import Options
|
||||
|
||||
try:
|
||||
import multiprocessing
|
||||
parallel_compiles = int(multiprocessing.cpu_count() * 1.5)
|
||||
except ImportError:
|
||||
multiprocessing = None
|
||||
parallel_compiles = 0
|
||||
|
||||
|
||||
class _FakePool(object):
|
||||
def map_async(self, func, args):
|
||||
try:
|
||||
from itertools import imap
|
||||
except ImportError:
|
||||
imap=map
|
||||
for _ in imap(func, args):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def terminate(self):
|
||||
pass
|
||||
|
||||
def join(self):
|
||||
pass
|
||||
|
||||
|
||||
def find_package_base(path):
|
||||
base_dir, package_path = os.path.split(path)
|
||||
while is_package_dir(base_dir):
|
||||
base_dir, parent = os.path.split(base_dir)
|
||||
package_path = '%s/%s' % (parent, package_path)
|
||||
return base_dir, package_path
|
||||
|
||||
def cython_compile(path_pattern, options):
|
||||
all_paths = map(os.path.abspath, extended_iglob(path_pattern))
|
||||
_cython_compile_files(all_paths, options)
|
||||
|
||||
def _cython_compile_files(all_paths, options):
|
||||
pool = None
|
||||
try:
|
||||
for path in all_paths:
|
||||
if options.build_inplace:
|
||||
base_dir = path
|
||||
while not os.path.isdir(base_dir) or is_package_dir(base_dir):
|
||||
base_dir = os.path.dirname(base_dir)
|
||||
else:
|
||||
base_dir = None
|
||||
|
||||
if os.path.isdir(path):
|
||||
# recursively compiling a package
|
||||
paths = [os.path.join(path, '**', '*.{py,pyx}')]
|
||||
else:
|
||||
# assume it's a file(-like thing)
|
||||
paths = [path]
|
||||
|
||||
ext_modules = cythonize(
|
||||
paths,
|
||||
nthreads=options.parallel,
|
||||
exclude_failures=options.keep_going,
|
||||
exclude=options.excludes,
|
||||
compiler_directives=options.directives,
|
||||
compile_time_env=options.compile_time_env,
|
||||
force=options.force,
|
||||
quiet=options.quiet,
|
||||
depfile=options.depfile,
|
||||
language=options.language,
|
||||
**options.options)
|
||||
|
||||
if ext_modules and options.build:
|
||||
if len(ext_modules) > 1 and options.parallel > 1:
|
||||
if pool is None:
|
||||
try:
|
||||
pool = multiprocessing.Pool(options.parallel)
|
||||
except OSError:
|
||||
pool = _FakePool()
|
||||
pool.map_async(run_distutils, [
|
||||
(base_dir, [ext]) for ext in ext_modules])
|
||||
else:
|
||||
run_distutils((base_dir, ext_modules))
|
||||
except:
|
||||
if pool is not None:
|
||||
pool.terminate()
|
||||
raise
|
||||
else:
|
||||
if pool is not None:
|
||||
pool.close()
|
||||
pool.join()
|
||||
|
||||
|
||||
def run_distutils(args):
|
||||
try:
|
||||
from distutils.core import setup
|
||||
except ImportError:
|
||||
try:
|
||||
from setuptools import setup
|
||||
except ImportError:
|
||||
raise ImportError("'distutils' is not available. Please install 'setuptools' for binary builds.")
|
||||
|
||||
base_dir, ext_modules = args
|
||||
script_args = ['build_ext', '-i']
|
||||
cwd = os.getcwd()
|
||||
temp_dir = None
|
||||
try:
|
||||
if base_dir:
|
||||
os.chdir(base_dir)
|
||||
temp_dir = tempfile.mkdtemp(dir=base_dir)
|
||||
script_args.extend(['--build-temp', temp_dir])
|
||||
setup(
|
||||
script_name='setup.py',
|
||||
script_args=script_args,
|
||||
ext_modules=ext_modules,
|
||||
)
|
||||
finally:
|
||||
if base_dir:
|
||||
os.chdir(cwd)
|
||||
if temp_dir and os.path.isdir(temp_dir):
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
|
||||
def create_args_parser():
|
||||
from argparse import ArgumentParser, RawDescriptionHelpFormatter
|
||||
from ..Compiler.CmdLine import ParseDirectivesAction, ParseOptionsAction, ParseCompileTimeEnvAction
|
||||
|
||||
parser = ArgumentParser(
|
||||
formatter_class=RawDescriptionHelpFormatter,
|
||||
epilog="""\
|
||||
Environment variables:
|
||||
CYTHON_FORCE_REGEN: if set to 1, forces cythonize to regenerate the output files regardless
|
||||
of modification times and changes.
|
||||
Environment variables accepted by setuptools are supported to configure the C compiler and build:
|
||||
https://setuptools.pypa.io/en/latest/userguide/ext_modules.html#compiler-and-linker-options"""
|
||||
)
|
||||
|
||||
parser.add_argument('-X', '--directive', metavar='NAME=VALUE,...',
|
||||
dest='directives', default={}, type=str,
|
||||
action=ParseDirectivesAction,
|
||||
help='set a compiler directive')
|
||||
parser.add_argument('-E', '--compile-time-env', metavar='NAME=VALUE,...',
|
||||
dest='compile_time_env', default={}, type=str,
|
||||
action=ParseCompileTimeEnvAction,
|
||||
help='set a compile time environment variable')
|
||||
parser.add_argument('-s', '--option', metavar='NAME=VALUE',
|
||||
dest='options', default={}, type=str,
|
||||
action=ParseOptionsAction,
|
||||
help='set a cythonize option')
|
||||
parser.add_argument('-2', dest='language_level', action='store_const', const=2, default=None,
|
||||
help='use Python 2 syntax mode by default')
|
||||
parser.add_argument('-3', dest='language_level', action='store_const', const=3,
|
||||
help='use Python 3 syntax mode by default')
|
||||
parser.add_argument('--3str', dest='language_level', action='store_const', const='3str',
|
||||
help='use Python 3 syntax mode by default')
|
||||
parser.add_argument('-+', '--cplus', dest='language', action='store_const', const='c++', default=None,
|
||||
help='Compile as C++ rather than C')
|
||||
parser.add_argument('-a', '--annotate', action='store_const', const='default', dest='annotate',
|
||||
help='Produce a colorized HTML version of the source.')
|
||||
parser.add_argument('--annotate-fullc', action='store_const', const='fullc', dest='annotate',
|
||||
help='Produce a colorized HTML version of the source '
|
||||
'which includes entire generated C/C++-code.')
|
||||
parser.add_argument('-x', '--exclude', metavar='PATTERN', dest='excludes',
|
||||
action='append', default=[],
|
||||
help='exclude certain file patterns from the compilation')
|
||||
|
||||
parser.add_argument('-b', '--build', dest='build', action='store_true', default=None,
|
||||
help='build extension modules using distutils/setuptools')
|
||||
parser.add_argument('-i', '--inplace', dest='build_inplace', action='store_true', default=None,
|
||||
help='build extension modules in place using distutils/setuptools (implies -b)')
|
||||
parser.add_argument('-j', '--parallel', dest='parallel', metavar='N',
|
||||
type=int, default=parallel_compiles,
|
||||
help=('run builds in N parallel jobs (default: %d)' %
|
||||
parallel_compiles or 1))
|
||||
parser.add_argument('-f', '--force', dest='force', action='store_true', default=None,
|
||||
help='force recompilation')
|
||||
parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=None,
|
||||
help='be less verbose during compilation')
|
||||
|
||||
parser.add_argument('--lenient', dest='lenient', action='store_true', default=None,
|
||||
help='increase Python compatibility by ignoring some compile time errors')
|
||||
parser.add_argument('-k', '--keep-going', dest='keep_going', action='store_true', default=None,
|
||||
help='compile as much as possible, ignore compilation failures')
|
||||
parser.add_argument('--no-docstrings', dest='no_docstrings', action='store_true', default=None,
|
||||
help='strip docstrings')
|
||||
parser.add_argument('-M', '--depfile', action='store_true', help='produce depfiles for the sources')
|
||||
parser.add_argument('sources', nargs='*')
|
||||
return parser
|
||||
|
||||
|
||||
def parse_args_raw(parser, args):
|
||||
options, unknown = parser.parse_known_args(args)
|
||||
sources = options.sources
|
||||
# if positional arguments were interspersed
|
||||
# some of them are in unknown
|
||||
for option in unknown:
|
||||
if option.startswith('-'):
|
||||
parser.error("unknown option "+option)
|
||||
else:
|
||||
sources.append(option)
|
||||
del options.sources
|
||||
return (options, sources)
|
||||
|
||||
|
||||
def parse_args(args):
|
||||
parser = create_args_parser()
|
||||
options, args = parse_args_raw(parser, args)
|
||||
|
||||
if not args:
|
||||
parser.error("no source files provided")
|
||||
if options.build_inplace:
|
||||
options.build = True
|
||||
if multiprocessing is None:
|
||||
options.parallel = 0
|
||||
if options.language_level:
|
||||
assert options.language_level in (2, 3, '3str')
|
||||
options.options['language_level'] = options.language_level
|
||||
|
||||
if options.lenient:
|
||||
# increase Python compatibility by ignoring compile time errors
|
||||
Options.error_on_unknown_names = False
|
||||
Options.error_on_uninitialized = False
|
||||
|
||||
if options.annotate:
|
||||
Options.annotate = options.annotate
|
||||
|
||||
if options.no_docstrings:
|
||||
Options.docstrings = False
|
||||
|
||||
return options, args
|
||||
|
||||
|
||||
def main(args=None):
|
||||
options, paths = parse_args(args)
|
||||
|
||||
all_paths = []
|
||||
for path in paths:
|
||||
expanded_path = [os.path.abspath(p) for p in extended_iglob(path)]
|
||||
if not expanded_path:
|
||||
import sys
|
||||
print("{}: No such file or directory: '{}'".format(sys.argv[0], path), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
all_paths.extend(expanded_path)
|
||||
_cython_compile_files(all_paths, options)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user