Cython 3.2.0b1__cp39-abi3-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Cython/Build/BuildExecutable.py +169 -0
- Cython/Build/Cache.py +199 -0
- Cython/Build/Cythonize.py +350 -0
- Cython/Build/Dependencies.py +1311 -0
- Cython/Build/Distutils.py +1 -0
- Cython/Build/Inline.py +463 -0
- Cython/Build/IpythonMagic.py +560 -0
- Cython/Build/SharedModule.py +95 -0
- Cython/Build/Tests/TestCyCache.py +194 -0
- Cython/Build/Tests/TestCythonizeArgsParser.py +481 -0
- Cython/Build/Tests/TestDependencies.py +133 -0
- Cython/Build/Tests/TestInline.py +177 -0
- Cython/Build/Tests/TestIpythonMagic.py +287 -0
- Cython/Build/Tests/TestRecythonize.py +212 -0
- Cython/Build/Tests/TestStripLiterals.py +155 -0
- Cython/Build/Tests/__init__.py +1 -0
- Cython/Build/__init__.py +11 -0
- Cython/CodeWriter.py +815 -0
- Cython/Compiler/AnalysedTreeTransforms.py +97 -0
- Cython/Compiler/Annotate.py +328 -0
- Cython/Compiler/AutoDocTransforms.py +320 -0
- Cython/Compiler/Buffer.py +680 -0
- Cython/Compiler/Builtin.py +984 -0
- Cython/Compiler/CmdLine.py +263 -0
- Cython/Compiler/Code.pxd +149 -0
- Cython/Compiler/Code.py +3730 -0
- Cython/Compiler/Code.pyd +0 -0
- Cython/Compiler/CodeGeneration.py +33 -0
- Cython/Compiler/CythonScope.py +187 -0
- Cython/Compiler/Dataclass.py +864 -0
- Cython/Compiler/DebugFlags.py +24 -0
- Cython/Compiler/Errors.py +297 -0
- Cython/Compiler/ExprNodes.py +15559 -0
- Cython/Compiler/FlowControl.pxd +97 -0
- Cython/Compiler/FlowControl.py +1451 -0
- Cython/Compiler/FlowControl.pyd +0 -0
- Cython/Compiler/FusedNode.py +971 -0
- Cython/Compiler/FusedNode.pyd +0 -0
- Cython/Compiler/Future.py +16 -0
- Cython/Compiler/Interpreter.py +57 -0
- Cython/Compiler/Lexicon.py +421 -0
- Cython/Compiler/LineTable.py +114 -0
- Cython/Compiler/LineTable.pyd +0 -0
- Cython/Compiler/Main.py +857 -0
- Cython/Compiler/MatchCaseNodes.py +259 -0
- Cython/Compiler/MemoryView.py +905 -0
- Cython/Compiler/ModuleNode.py +4157 -0
- Cython/Compiler/Naming.py +363 -0
- Cython/Compiler/Nodes.py +10817 -0
- Cython/Compiler/Optimize.py +5293 -0
- Cython/Compiler/Options.py +843 -0
- Cython/Compiler/ParseTreeTransforms.pxd +78 -0
- Cython/Compiler/ParseTreeTransforms.py +4638 -0
- Cython/Compiler/Parsing.pxd +9 -0
- Cython/Compiler/Parsing.py +4775 -0
- Cython/Compiler/Parsing.pyd +0 -0
- Cython/Compiler/Pipeline.py +439 -0
- Cython/Compiler/PyrexTypes.py +5857 -0
- Cython/Compiler/Pythran.py +232 -0
- Cython/Compiler/Scanning.pxd +48 -0
- Cython/Compiler/Scanning.py +701 -0
- Cython/Compiler/Scanning.pyd +0 -0
- Cython/Compiler/StringEncoding.py +298 -0
- Cython/Compiler/Symtab.py +3070 -0
- Cython/Compiler/Tests/TestBuffer.py +105 -0
- Cython/Compiler/Tests/TestBuiltin.py +72 -0
- Cython/Compiler/Tests/TestCmdLine.py +586 -0
- Cython/Compiler/Tests/TestCode.py +144 -0
- Cython/Compiler/Tests/TestFlowControl.py +65 -0
- Cython/Compiler/Tests/TestGrammar.py +202 -0
- Cython/Compiler/Tests/TestMemView.py +71 -0
- Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
- Cython/Compiler/Tests/TestScanning.py +134 -0
- Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
- Cython/Compiler/Tests/TestStringEncoding.py +21 -0
- Cython/Compiler/Tests/TestTreeFragment.py +63 -0
- Cython/Compiler/Tests/TestTreePath.py +103 -0
- Cython/Compiler/Tests/TestTypes.py +75 -0
- Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
- Cython/Compiler/Tests/TestVisitor.py +61 -0
- Cython/Compiler/Tests/Utils.py +36 -0
- Cython/Compiler/Tests/__init__.py +1 -0
- Cython/Compiler/TreeFragment.py +278 -0
- Cython/Compiler/TreePath.py +303 -0
- Cython/Compiler/TypeInference.py +591 -0
- Cython/Compiler/TypeSlots.py +1174 -0
- Cython/Compiler/UFuncs.py +311 -0
- Cython/Compiler/UtilNodes.py +389 -0
- Cython/Compiler/UtilityCode.py +344 -0
- Cython/Compiler/Version.py +8 -0
- Cython/Compiler/Visitor.pxd +53 -0
- Cython/Compiler/Visitor.py +861 -0
- Cython/Compiler/Visitor.pyd +0 -0
- Cython/Compiler/__init__.py +1 -0
- Cython/Coverage.py +448 -0
- Cython/Debugger/Cygdb.py +175 -0
- Cython/Debugger/DebugWriter.py +82 -0
- Cython/Debugger/Tests/TestLibCython.py +275 -0
- Cython/Debugger/Tests/__init__.py +1 -0
- Cython/Debugger/Tests/cfuncs.c +8 -0
- Cython/Debugger/Tests/codefile +49 -0
- Cython/Debugger/Tests/test_libcython_in_gdb.py +578 -0
- Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
- Cython/Debugger/__init__.py +1 -0
- Cython/Debugger/libcython.py +1548 -0
- Cython/Debugger/libpython.py +2821 -0
- Cython/Debugging.py +20 -0
- Cython/Distutils/__init__.py +2 -0
- Cython/Distutils/build_ext.py +139 -0
- Cython/Distutils/extension.py +96 -0
- Cython/Distutils/old_build_ext.py +351 -0
- Cython/Includes/cpython/__init__.pxd +173 -0
- Cython/Includes/cpython/array.pxd +178 -0
- Cython/Includes/cpython/bool.pxd +37 -0
- Cython/Includes/cpython/buffer.pxd +112 -0
- Cython/Includes/cpython/bytearray.pxd +33 -0
- Cython/Includes/cpython/bytes.pxd +200 -0
- Cython/Includes/cpython/cellobject.pxd +35 -0
- Cython/Includes/cpython/ceval.pxd +8 -0
- Cython/Includes/cpython/codecs.pxd +121 -0
- Cython/Includes/cpython/complex.pxd +60 -0
- Cython/Includes/cpython/contextvars.pxd +145 -0
- Cython/Includes/cpython/conversion.pxd +36 -0
- Cython/Includes/cpython/datetime.pxd +395 -0
- Cython/Includes/cpython/descr.pxd +26 -0
- Cython/Includes/cpython/dict.pxd +187 -0
- Cython/Includes/cpython/exc.pxd +263 -0
- Cython/Includes/cpython/fileobject.pxd +57 -0
- Cython/Includes/cpython/float.pxd +47 -0
- Cython/Includes/cpython/function.pxd +65 -0
- Cython/Includes/cpython/genobject.pxd +25 -0
- Cython/Includes/cpython/getargs.pxd +12 -0
- Cython/Includes/cpython/instance.pxd +25 -0
- Cython/Includes/cpython/iterator.pxd +36 -0
- Cython/Includes/cpython/iterobject.pxd +24 -0
- Cython/Includes/cpython/list.pxd +92 -0
- Cython/Includes/cpython/long.pxd +149 -0
- Cython/Includes/cpython/longintrepr.pxd +14 -0
- Cython/Includes/cpython/mapping.pxd +63 -0
- Cython/Includes/cpython/marshal.pxd +66 -0
- Cython/Includes/cpython/mem.pxd +120 -0
- Cython/Includes/cpython/memoryview.pxd +50 -0
- Cython/Includes/cpython/method.pxd +49 -0
- Cython/Includes/cpython/module.pxd +208 -0
- Cython/Includes/cpython/number.pxd +258 -0
- Cython/Includes/cpython/object.pxd +433 -0
- Cython/Includes/cpython/pycapsule.pxd +143 -0
- Cython/Includes/cpython/pylifecycle.pxd +68 -0
- Cython/Includes/cpython/pyport.pxd +8 -0
- Cython/Includes/cpython/pystate.pxd +95 -0
- Cython/Includes/cpython/pythread.pxd +53 -0
- Cython/Includes/cpython/ref.pxd +141 -0
- Cython/Includes/cpython/sequence.pxd +134 -0
- Cython/Includes/cpython/set.pxd +119 -0
- Cython/Includes/cpython/slice.pxd +70 -0
- Cython/Includes/cpython/time.pxd +129 -0
- Cython/Includes/cpython/tuple.pxd +72 -0
- Cython/Includes/cpython/type.pxd +53 -0
- Cython/Includes/cpython/unicode.pxd +639 -0
- Cython/Includes/cpython/version.pxd +32 -0
- Cython/Includes/cpython/weakref.pxd +78 -0
- Cython/Includes/libc/__init__.pxd +1 -0
- Cython/Includes/libc/complex.pxd +35 -0
- Cython/Includes/libc/errno.pxd +127 -0
- Cython/Includes/libc/float.pxd +43 -0
- Cython/Includes/libc/limits.pxd +28 -0
- Cython/Includes/libc/locale.pxd +46 -0
- Cython/Includes/libc/math.pxd +209 -0
- Cython/Includes/libc/setjmp.pxd +10 -0
- Cython/Includes/libc/signal.pxd +64 -0
- Cython/Includes/libc/stddef.pxd +9 -0
- Cython/Includes/libc/stdint.pxd +105 -0
- Cython/Includes/libc/stdio.pxd +80 -0
- Cython/Includes/libc/stdlib.pxd +72 -0
- Cython/Includes/libc/string.pxd +50 -0
- Cython/Includes/libc/threads.pxd +234 -0
- Cython/Includes/libc/time.pxd +52 -0
- Cython/Includes/libcpp/__init__.pxd +4 -0
- Cython/Includes/libcpp/algorithm.pxd +320 -0
- Cython/Includes/libcpp/any.pxd +16 -0
- Cython/Includes/libcpp/atomic.pxd +59 -0
- Cython/Includes/libcpp/barrier.pxd +22 -0
- Cython/Includes/libcpp/bit.pxd +29 -0
- Cython/Includes/libcpp/cast.pxd +12 -0
- Cython/Includes/libcpp/cmath.pxd +518 -0
- Cython/Includes/libcpp/complex.pxd +106 -0
- Cython/Includes/libcpp/condition_variable.pxd +322 -0
- Cython/Includes/libcpp/deque.pxd +165 -0
- Cython/Includes/libcpp/exception.pxd +86 -0
- Cython/Includes/libcpp/execution.pxd +15 -0
- Cython/Includes/libcpp/forward_list.pxd +63 -0
- Cython/Includes/libcpp/functional.pxd +26 -0
- Cython/Includes/libcpp/future.pxd +103 -0
- Cython/Includes/libcpp/iterator.pxd +34 -0
- Cython/Includes/libcpp/latch.pxd +17 -0
- Cython/Includes/libcpp/limits.pxd +61 -0
- Cython/Includes/libcpp/list.pxd +117 -0
- Cython/Includes/libcpp/map.pxd +252 -0
- Cython/Includes/libcpp/memory.pxd +115 -0
- Cython/Includes/libcpp/mutex.pxd +387 -0
- Cython/Includes/libcpp/numbers.pxd +15 -0
- Cython/Includes/libcpp/numeric.pxd +131 -0
- Cython/Includes/libcpp/optional.pxd +34 -0
- Cython/Includes/libcpp/pair.pxd +1 -0
- Cython/Includes/libcpp/queue.pxd +25 -0
- Cython/Includes/libcpp/random.pxd +166 -0
- Cython/Includes/libcpp/semaphore.pxd +43 -0
- Cython/Includes/libcpp/set.pxd +228 -0
- Cython/Includes/libcpp/shared_mutex.pxd +96 -0
- Cython/Includes/libcpp/span.pxd +87 -0
- Cython/Includes/libcpp/stack.pxd +11 -0
- Cython/Includes/libcpp/stop_token.pxd +117 -0
- Cython/Includes/libcpp/string.pxd +355 -0
- Cython/Includes/libcpp/string_view.pxd +183 -0
- Cython/Includes/libcpp/typeindex.pxd +15 -0
- Cython/Includes/libcpp/typeinfo.pxd +10 -0
- Cython/Includes/libcpp/unordered_map.pxd +193 -0
- Cython/Includes/libcpp/unordered_set.pxd +152 -0
- Cython/Includes/libcpp/utility.pxd +30 -0
- Cython/Includes/libcpp/vector.pxd +186 -0
- Cython/Includes/numpy/math.pxd +150 -0
- Cython/Includes/openmp.pxd +50 -0
- Cython/Includes/posix/__init__.pxd +1 -0
- Cython/Includes/posix/dlfcn.pxd +14 -0
- Cython/Includes/posix/fcntl.pxd +86 -0
- Cython/Includes/posix/ioctl.pxd +4 -0
- Cython/Includes/posix/mman.pxd +101 -0
- Cython/Includes/posix/resource.pxd +57 -0
- Cython/Includes/posix/select.pxd +21 -0
- Cython/Includes/posix/signal.pxd +73 -0
- Cython/Includes/posix/stat.pxd +98 -0
- Cython/Includes/posix/stdio.pxd +37 -0
- Cython/Includes/posix/stdlib.pxd +29 -0
- Cython/Includes/posix/strings.pxd +9 -0
- Cython/Includes/posix/time.pxd +71 -0
- Cython/Includes/posix/types.pxd +30 -0
- Cython/Includes/posix/uio.pxd +26 -0
- Cython/Includes/posix/unistd.pxd +271 -0
- Cython/Includes/posix/wait.pxd +38 -0
- Cython/Plex/Actions.pxd +24 -0
- Cython/Plex/Actions.py +119 -0
- Cython/Plex/Actions.pyd +0 -0
- Cython/Plex/DFA.pxd +14 -0
- Cython/Plex/DFA.py +164 -0
- Cython/Plex/DFA.pyd +0 -0
- Cython/Plex/Errors.py +48 -0
- Cython/Plex/Lexicons.py +178 -0
- Cython/Plex/Machines.pxd +36 -0
- Cython/Plex/Machines.py +238 -0
- Cython/Plex/Machines.pyd +0 -0
- Cython/Plex/Regexps.py +535 -0
- Cython/Plex/Scanners.pxd +45 -0
- Cython/Plex/Scanners.py +328 -0
- Cython/Plex/Scanners.pyd +0 -0
- Cython/Plex/Transitions.pxd +14 -0
- Cython/Plex/Transitions.py +239 -0
- Cython/Plex/Transitions.pyd +0 -0
- Cython/Plex/__init__.py +34 -0
- Cython/Runtime/__init__.py +1 -0
- Cython/Runtime/refnanny.pyd +0 -0
- Cython/Runtime/refnanny.pyx +237 -0
- Cython/Shadow.py +690 -0
- Cython/Shadow.pyi +521 -0
- Cython/StringIOTree.py +170 -0
- Cython/StringIOTree.pyd +0 -0
- Cython/Tempita/__init__.py +4 -0
- Cython/Tempita/_looper.py +154 -0
- Cython/Tempita/_tempita.py +1091 -0
- Cython/Tempita/_tempita.pyd +0 -0
- Cython/TestUtils.py +422 -0
- Cython/Tests/TestCodeWriter.py +128 -0
- Cython/Tests/TestCythonUtils.py +202 -0
- Cython/Tests/TestJediTyper.py +223 -0
- Cython/Tests/TestShadow.py +114 -0
- Cython/Tests/TestStringIOTree.py +67 -0
- Cython/Tests/TestTestUtils.py +90 -0
- Cython/Tests/__init__.py +1 -0
- Cython/Tests/xmlrunner.py +390 -0
- Cython/Utility/AsyncGen.c +1039 -0
- Cython/Utility/Buffer.c +865 -0
- Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
- Cython/Utility/Builtins.c +810 -0
- Cython/Utility/CConvert.pyx +134 -0
- Cython/Utility/CMath.c +104 -0
- Cython/Utility/CommonStructures.c +210 -0
- Cython/Utility/Complex.c +378 -0
- Cython/Utility/Coroutine.c +2308 -0
- Cython/Utility/CpdefEnums.pyx +103 -0
- Cython/Utility/CppConvert.pyx +282 -0
- Cython/Utility/CppSupport.cpp +151 -0
- Cython/Utility/CythonFunction.c +1836 -0
- Cython/Utility/Dataclasses.c +101 -0
- Cython/Utility/Embed.c +121 -0
- Cython/Utility/Exceptions.c +1016 -0
- Cython/Utility/ExtensionTypes.c +996 -0
- Cython/Utility/FunctionArguments.c +1043 -0
- Cython/Utility/FusedFunction.pyx +44 -0
- Cython/Utility/ImportExport.c +926 -0
- Cython/Utility/MemoryView.pxd +188 -0
- Cython/Utility/MemoryView.pyx +1482 -0
- Cython/Utility/MemoryView_C.c +915 -0
- Cython/Utility/ModuleSetupCode.c +3145 -0
- Cython/Utility/NumpyImportArray.c +46 -0
- Cython/Utility/ObjectHandling.c +3273 -0
- Cython/Utility/Optimize.c +1612 -0
- Cython/Utility/Overflow.c +384 -0
- Cython/Utility/Printing.c +86 -0
- Cython/Utility/Profile.c +732 -0
- Cython/Utility/StringTools.c +1379 -0
- Cython/Utility/Synchronization.c +389 -0
- Cython/Utility/TString.c +356 -0
- Cython/Utility/TestCyUtilityLoader.pyx +8 -0
- Cython/Utility/TestCythonScope.pyx +75 -0
- Cython/Utility/TestUtilityLoader.c +12 -0
- Cython/Utility/TypeConversion.c +1385 -0
- Cython/Utility/UFuncs.pyx +50 -0
- Cython/Utility/UFuncs_C.c +89 -0
- Cython/Utility/__init__.py +28 -0
- Cython/Utility/arrayarray.h +167 -0
- Cython/Utils.py +687 -0
- Cython/Utils.pyd +0 -0
- Cython/__init__.py +10 -0
- Cython/__init__.pyi +7 -0
- Cython/py.typed +0 -0
- cython-3.2.0b1.dist-info/METADATA +292 -0
- cython-3.2.0b1.dist-info/RECORD +333 -0
- cython-3.2.0b1.dist-info/WHEEL +5 -0
- cython-3.2.0b1.dist-info/entry_points.txt +4 -0
- cython-3.2.0b1.dist-info/top_level.txt +3 -0
- cython.py +29 -0
- pyximport/__init__.py +4 -0
- pyximport/pyxbuild.py +160 -0
- pyximport/pyximport.py +482 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import concurrent.futures
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
import sys
|
|
5
|
+
import tempfile
|
|
6
|
+
from collections import defaultdict
|
|
7
|
+
from contextlib import contextmanager
|
|
8
|
+
|
|
9
|
+
from .Dependencies import cythonize, extended_iglob
|
|
10
|
+
from ..Utils import is_package_dir
|
|
11
|
+
from ..Compiler import Options
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
import multiprocessing
|
|
15
|
+
parallel_compiles = int(multiprocessing.cpu_count() * 1.5)
|
|
16
|
+
except ImportError:
|
|
17
|
+
multiprocessing = None
|
|
18
|
+
parallel_compiles = 0
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def find_package_base(path):
|
|
22
|
+
base_dir, package_path = os.path.split(path)
|
|
23
|
+
while is_package_dir(base_dir):
|
|
24
|
+
base_dir, parent = os.path.split(base_dir)
|
|
25
|
+
package_path = '%s/%s' % (parent, package_path)
|
|
26
|
+
return base_dir, package_path
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def cython_compile(path_pattern, options):
|
|
30
|
+
all_paths = map(os.path.abspath, extended_iglob(path_pattern))
|
|
31
|
+
ext_modules_by_basedir = _cython_compile_files(all_paths, options)
|
|
32
|
+
_build(list(ext_modules_by_basedir.items()), options.parallel)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _cython_compile_files(all_paths, options) -> dict:
|
|
36
|
+
ext_modules_to_build = defaultdict(list)
|
|
37
|
+
|
|
38
|
+
for path in all_paths:
|
|
39
|
+
if options.build_inplace:
|
|
40
|
+
base_dir = path
|
|
41
|
+
while not os.path.isdir(base_dir) or is_package_dir(base_dir):
|
|
42
|
+
base_dir = os.path.dirname(base_dir)
|
|
43
|
+
else:
|
|
44
|
+
base_dir = None
|
|
45
|
+
|
|
46
|
+
if os.path.isdir(path):
|
|
47
|
+
# recursively compiling a package
|
|
48
|
+
paths = [os.path.join(path, '**', '*.{py,pyx}')]
|
|
49
|
+
else:
|
|
50
|
+
# assume it's a file(-like thing)
|
|
51
|
+
paths = [path]
|
|
52
|
+
|
|
53
|
+
ext_modules = cythonize(
|
|
54
|
+
paths,
|
|
55
|
+
nthreads=options.parallel,
|
|
56
|
+
exclude_failures=options.keep_going,
|
|
57
|
+
exclude=options.excludes,
|
|
58
|
+
compiler_directives=options.directives,
|
|
59
|
+
compile_time_env=options.compile_time_env,
|
|
60
|
+
force=options.force,
|
|
61
|
+
quiet=options.quiet,
|
|
62
|
+
depfile=options.depfile,
|
|
63
|
+
language=options.language,
|
|
64
|
+
**options.options)
|
|
65
|
+
|
|
66
|
+
if ext_modules and options.build:
|
|
67
|
+
ext_modules_to_build[base_dir].extend(ext_modules)
|
|
68
|
+
|
|
69
|
+
return dict(ext_modules_to_build)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@contextmanager
|
|
73
|
+
def _interruptible_pool(pool_cm):
|
|
74
|
+
with pool_cm as proc_pool:
|
|
75
|
+
try:
|
|
76
|
+
yield proc_pool
|
|
77
|
+
except KeyboardInterrupt:
|
|
78
|
+
proc_pool.terminate_workers()
|
|
79
|
+
proc_pool.shutdown(cancel_futures=True)
|
|
80
|
+
raise
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _build(ext_modules, parallel):
|
|
84
|
+
modcount = sum(len(modules) for _, modules in ext_modules)
|
|
85
|
+
if not modcount:
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
serial_execution_mode = modcount == 1 or parallel < 2
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
pool_cm = (
|
|
92
|
+
None if serial_execution_mode
|
|
93
|
+
else concurrent.futures.ProcessPoolExecutor(max_workers=parallel)
|
|
94
|
+
)
|
|
95
|
+
except (OSError, ImportError):
|
|
96
|
+
# `OSError` is a historic exception in `multiprocessing`
|
|
97
|
+
# `ImportError` happens e.g. under pyodide (`ModuleNotFoundError`)
|
|
98
|
+
serial_execution_mode = True
|
|
99
|
+
|
|
100
|
+
if serial_execution_mode:
|
|
101
|
+
for ext in ext_modules:
|
|
102
|
+
run_distutils(ext)
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
with _interruptible_pool(pool_cm) as proc_pool:
|
|
106
|
+
compiler_tasks = [
|
|
107
|
+
proc_pool.submit(run_distutils, (base_dir, [ext]))
|
|
108
|
+
for base_dir, modules in ext_modules
|
|
109
|
+
for ext in modules
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
concurrent.futures.wait(compiler_tasks, return_when=concurrent.futures.FIRST_EXCEPTION)
|
|
113
|
+
|
|
114
|
+
worker_exceptions = []
|
|
115
|
+
for task in compiler_tasks: # discover any crashes
|
|
116
|
+
try:
|
|
117
|
+
task.result()
|
|
118
|
+
except BaseException as proc_err: # could be SystemExit
|
|
119
|
+
worker_exceptions.append(proc_err)
|
|
120
|
+
|
|
121
|
+
if worker_exceptions:
|
|
122
|
+
exc_msg = 'Compiling Cython modules failed with these errors:\n\n'
|
|
123
|
+
exc_msg += '\n\t* '.join(('', *map(str, worker_exceptions)))
|
|
124
|
+
exc_msg += '\n\n'
|
|
125
|
+
|
|
126
|
+
non_base_exceptions = [
|
|
127
|
+
exc for exc in worker_exceptions
|
|
128
|
+
if isinstance(exc, Exception)
|
|
129
|
+
]
|
|
130
|
+
if sys.version_info[:2] >= (3, 11) and non_base_exceptions:
|
|
131
|
+
raise ExceptionGroup(exc_msg, non_base_exceptions)
|
|
132
|
+
else:
|
|
133
|
+
raise RuntimeError(exc_msg) from worker_exceptions[0]
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def run_distutils(args):
|
|
137
|
+
try:
|
|
138
|
+
from distutils.core import setup
|
|
139
|
+
except ImportError:
|
|
140
|
+
try:
|
|
141
|
+
from setuptools import setup
|
|
142
|
+
except ImportError:
|
|
143
|
+
raise ImportError("'distutils' is not available. Please install 'setuptools' for binary builds.")
|
|
144
|
+
|
|
145
|
+
base_dir, ext_modules = args
|
|
146
|
+
script_args = ['build_ext', '-i']
|
|
147
|
+
cwd = os.getcwd()
|
|
148
|
+
temp_dir = None
|
|
149
|
+
try:
|
|
150
|
+
if base_dir:
|
|
151
|
+
os.chdir(base_dir)
|
|
152
|
+
temp_dir = tempfile.mkdtemp(dir=base_dir)
|
|
153
|
+
script_args.extend(['--build-temp', temp_dir])
|
|
154
|
+
setup(
|
|
155
|
+
script_name='setup.py',
|
|
156
|
+
script_args=script_args,
|
|
157
|
+
ext_modules=ext_modules,
|
|
158
|
+
)
|
|
159
|
+
finally:
|
|
160
|
+
if base_dir:
|
|
161
|
+
os.chdir(cwd)
|
|
162
|
+
if temp_dir and os.path.isdir(temp_dir):
|
|
163
|
+
shutil.rmtree(temp_dir)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def benchmark(code, setup_code=None, import_module=None, directives=None):
|
|
167
|
+
from Cython.Build.Inline import cymeit
|
|
168
|
+
|
|
169
|
+
timings, number = cymeit(code, setup_code, import_module, directives, repeat=9)
|
|
170
|
+
|
|
171
|
+
# Based on 'timeit.main()' in CPython 3.13.
|
|
172
|
+
units = {"nsec": 1e-9, "usec": 1e-6, "msec": 1e-3, "sec": 1.0}
|
|
173
|
+
scales = [(scale, unit) for unit, scale in reversed(units.items())] # biggest first
|
|
174
|
+
|
|
175
|
+
def format_time(t):
|
|
176
|
+
for scale, unit in scales:
|
|
177
|
+
if t >= scale:
|
|
178
|
+
break
|
|
179
|
+
else:
|
|
180
|
+
raise RuntimeError("Timing is below nanoseconds: {t:f}")
|
|
181
|
+
return f"{t / scale :.3f} {unit}"
|
|
182
|
+
|
|
183
|
+
timings.sort()
|
|
184
|
+
assert len(timings) & 1 == 1 # odd number of timings, for median position
|
|
185
|
+
fastest, median, slowest = timings[0], timings[len(timings) // 2], timings[-1]
|
|
186
|
+
|
|
187
|
+
print(f"{number} loops, best of {len(timings)}: {format_time(fastest)} per loop (median: {format_time(median)})")
|
|
188
|
+
|
|
189
|
+
if slowest > fastest * 4:
|
|
190
|
+
print(
|
|
191
|
+
"The timings are likely unreliable. "
|
|
192
|
+
f"The worst time ({format_time(slowest)}) was more than four times "
|
|
193
|
+
f"slower than the best time ({format_time(fastest)}).")
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def create_args_parser():
|
|
197
|
+
from argparse import ArgumentParser, RawDescriptionHelpFormatter
|
|
198
|
+
from ..Compiler.CmdLine import ParseDirectivesAction, ParseOptionsAction, ParseCompileTimeEnvAction
|
|
199
|
+
|
|
200
|
+
parser = ArgumentParser(
|
|
201
|
+
formatter_class=RawDescriptionHelpFormatter,
|
|
202
|
+
epilog="""\
|
|
203
|
+
Environment variables:
|
|
204
|
+
CYTHON_FORCE_REGEN: if set to 1, forces cythonize to regenerate the output files regardless
|
|
205
|
+
of modification times and changes.
|
|
206
|
+
CYTHON_CACHE_DIR: the base directory containing Cython's caches.
|
|
207
|
+
Environment variables accepted by setuptools are supported to configure the C compiler and build:
|
|
208
|
+
https://setuptools.pypa.io/en/latest/userguide/ext_modules.html#compiler-and-linker-options"""
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
parser.add_argument('-X', '--directive', metavar='NAME=VALUE,...',
|
|
212
|
+
dest='directives', default={}, type=str,
|
|
213
|
+
action=ParseDirectivesAction,
|
|
214
|
+
help='set a compiler directive')
|
|
215
|
+
parser.add_argument('-E', '--compile-time-env', metavar='NAME=VALUE,...',
|
|
216
|
+
dest='compile_time_env', default={}, type=str,
|
|
217
|
+
action=ParseCompileTimeEnvAction,
|
|
218
|
+
help='set a compile time environment variable')
|
|
219
|
+
parser.add_argument('-s', '--option', metavar='NAME=VALUE',
|
|
220
|
+
dest='options', default={}, type=str,
|
|
221
|
+
action=ParseOptionsAction,
|
|
222
|
+
help='set a cythonize option')
|
|
223
|
+
parser.add_argument('-2', dest='language_level', action='store_const', const=2, default=None,
|
|
224
|
+
help='use Python 2 syntax mode by default')
|
|
225
|
+
parser.add_argument('-3', dest='language_level', action='store_const', const=3,
|
|
226
|
+
help='use Python 3 syntax mode by default')
|
|
227
|
+
parser.add_argument('--3str', dest='language_level', action='store_const', const=3,
|
|
228
|
+
help='use Python 3 syntax mode by default (deprecated alias for -3)')
|
|
229
|
+
parser.add_argument('-+', '--cplus', dest='language', action='store_const', const='c++', default=None,
|
|
230
|
+
help='Compile as C++ rather than C')
|
|
231
|
+
parser.add_argument('-a', '--annotate', action='store_const', const='default', dest='annotate',
|
|
232
|
+
help='Produce a colorized HTML version of the source.')
|
|
233
|
+
parser.add_argument('--annotate-fullc', action='store_const', const='fullc', dest='annotate',
|
|
234
|
+
help='Produce a colorized HTML version of the source '
|
|
235
|
+
'which includes entire generated C/C++-code.')
|
|
236
|
+
parser.add_argument('-x', '--exclude', metavar='PATTERN', dest='excludes',
|
|
237
|
+
action='append', default=[],
|
|
238
|
+
help='exclude certain file patterns from the compilation')
|
|
239
|
+
|
|
240
|
+
parser.add_argument('-b', '--build', dest='build', action='store_true', default=None,
|
|
241
|
+
help='build extension modules using distutils/setuptools')
|
|
242
|
+
parser.add_argument('-i', '--inplace', dest='build_inplace', action='store_true', default=None,
|
|
243
|
+
help='build extension modules in place using distutils/setuptools (implies -b)')
|
|
244
|
+
|
|
245
|
+
parser.add_argument('--timeit', dest='benchmark', metavar="CODESTRING", type=str, default=None,
|
|
246
|
+
help="build in place, then compile+run CODESTRING as benchmark in first module's namespace (implies -i)")
|
|
247
|
+
parser.add_argument('--setup', dest='benchmark_setup', metavar="CODESTRING", type=str, default=None,
|
|
248
|
+
help="use CODESTRING as pre-benchmark setup code for --bench")
|
|
249
|
+
|
|
250
|
+
parser.add_argument('-j', '--parallel', dest='parallel', metavar='N',
|
|
251
|
+
type=int, default=parallel_compiles,
|
|
252
|
+
help=f'run builds in N parallel jobs (default: {parallel_compiles or 1})')
|
|
253
|
+
parser.add_argument('-f', '--force', dest='force', action='store_true', default=None,
|
|
254
|
+
help='force recompilation')
|
|
255
|
+
parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=None,
|
|
256
|
+
help='be less verbose during compilation')
|
|
257
|
+
|
|
258
|
+
parser.add_argument('--lenient', dest='lenient', action='store_true', default=None,
|
|
259
|
+
help='increase Python compatibility by ignoring some compile time errors')
|
|
260
|
+
parser.add_argument('-k', '--keep-going', dest='keep_going', action='store_true', default=None,
|
|
261
|
+
help='compile as much as possible, ignore compilation failures')
|
|
262
|
+
parser.add_argument('--no-docstrings', dest='no_docstrings', action='store_true', default=None,
|
|
263
|
+
help='strip docstrings')
|
|
264
|
+
parser.add_argument('-M', '--depfile', action='store_true', help='produce depfiles for the sources')
|
|
265
|
+
parser.add_argument('sources', nargs='*')
|
|
266
|
+
return parser
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def parse_args_raw(parser, args):
|
|
270
|
+
options, unknown = parser.parse_known_args(args)
|
|
271
|
+
sources = options.sources
|
|
272
|
+
# if positional arguments were interspersed
|
|
273
|
+
# some of them are in unknown
|
|
274
|
+
for option in unknown:
|
|
275
|
+
if option.startswith('-'):
|
|
276
|
+
parser.error("unknown option "+option)
|
|
277
|
+
else:
|
|
278
|
+
sources.append(option)
|
|
279
|
+
del options.sources
|
|
280
|
+
return (options, sources)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def parse_args(args):
|
|
284
|
+
parser = create_args_parser()
|
|
285
|
+
options, args = parse_args_raw(parser, args)
|
|
286
|
+
|
|
287
|
+
if options.benchmark is not None:
|
|
288
|
+
options.build_inplace = True
|
|
289
|
+
elif not args:
|
|
290
|
+
parser.error("no source files provided")
|
|
291
|
+
|
|
292
|
+
if options.build_inplace:
|
|
293
|
+
options.build = True
|
|
294
|
+
if multiprocessing is None:
|
|
295
|
+
options.parallel = 0
|
|
296
|
+
if options.language_level:
|
|
297
|
+
assert options.language_level in (2, 3, '3str')
|
|
298
|
+
options.options['language_level'] = options.language_level
|
|
299
|
+
|
|
300
|
+
if options.lenient:
|
|
301
|
+
# increase Python compatibility by ignoring compile time errors
|
|
302
|
+
Options.error_on_unknown_names = False
|
|
303
|
+
Options.error_on_uninitialized = False
|
|
304
|
+
|
|
305
|
+
if options.annotate:
|
|
306
|
+
Options.annotate = options.annotate
|
|
307
|
+
|
|
308
|
+
if options.no_docstrings:
|
|
309
|
+
Options.docstrings = False
|
|
310
|
+
|
|
311
|
+
return options, args
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def main(args=None):
|
|
315
|
+
options, paths = parse_args(args)
|
|
316
|
+
|
|
317
|
+
all_paths = []
|
|
318
|
+
for path in paths:
|
|
319
|
+
expanded_path = [os.path.abspath(p) for p in extended_iglob(path)]
|
|
320
|
+
if not expanded_path:
|
|
321
|
+
print("{}: No such file or directory: '{}'".format(sys.argv[0], path), file=sys.stderr)
|
|
322
|
+
sys.exit(1)
|
|
323
|
+
all_paths.extend(expanded_path)
|
|
324
|
+
|
|
325
|
+
ext_modules_by_basedir = _cython_compile_files(all_paths, options)
|
|
326
|
+
|
|
327
|
+
if ext_modules_by_basedir and options.build:
|
|
328
|
+
_build(list(ext_modules_by_basedir.items()), options.parallel)
|
|
329
|
+
|
|
330
|
+
if options.benchmark is not None:
|
|
331
|
+
base_dir = import_module = None
|
|
332
|
+
if ext_modules_by_basedir:
|
|
333
|
+
base_dir, first_extensions = ext_modules_by_basedir.popitem()
|
|
334
|
+
if first_extensions:
|
|
335
|
+
import_module = first_extensions[0].name
|
|
336
|
+
|
|
337
|
+
if base_dir is not None:
|
|
338
|
+
sys.path.insert(0, base_dir)
|
|
339
|
+
|
|
340
|
+
benchmark(
|
|
341
|
+
options.benchmark, options.benchmark_setup,
|
|
342
|
+
import_module=import_module,
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
if base_dir is not None:
|
|
346
|
+
sys.path.remove(base_dir)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
if __name__ == '__main__':
|
|
350
|
+
main()
|