Cython 3.2.0__cp39-abi3-win_arm64.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 +1314 -0
- Cython/Build/Distutils.py +1 -0
- Cython/Build/Inline.py +463 -0
- Cython/Build/IpythonMagic.py +560 -0
- Cython/Build/SharedModule.py +94 -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 +3746 -0
- Cython/Compiler/Code.pyd +0 -0
- Cython/Compiler/CodeGeneration.py +33 -0
- Cython/Compiler/CythonScope.py +191 -0
- Cython/Compiler/Dataclass.py +864 -0
- Cython/Compiler/DebugFlags.py +24 -0
- Cython/Compiler/Errors.py +297 -0
- Cython/Compiler/ExprNodes.py +15562 -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 +4235 -0
- Cython/Compiler/Naming.py +363 -0
- Cython/Compiler/Nodes.py +10831 -0
- Cython/Compiler/Optimize.py +5288 -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 +5870 -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 +3073 -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 +177 -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 +1031 -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 +226 -0
- Cython/Utility/Complex.c +378 -0
- Cython/Utility/Coroutine.c +2300 -0
- Cython/Utility/CpdefEnums.pyx +103 -0
- Cython/Utility/CppConvert.pyx +282 -0
- Cython/Utility/CppSupport.cpp +151 -0
- Cython/Utility/CythonFunction.c +1832 -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 +907 -0
- Cython/Utility/MemoryView.pxd +188 -0
- Cython/Utility/MemoryView.pyx +1482 -0
- Cython/Utility/MemoryView_C.c +927 -0
- Cython/Utility/ModuleSetupCode.c +3203 -0
- Cython/Utility/NumpyImportArray.c +46 -0
- Cython/Utility/ObjectHandling.c +3273 -0
- Cython/Utility/Optimize.c +1603 -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 +399 -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.0.dist-info/METADATA +85 -0
- cython-3.2.0.dist-info/RECORD +333 -0
- cython-3.2.0.dist-info/WHEEL +5 -0
- cython-3.2.0.dist-info/entry_points.txt +4 -0
- cython-3.2.0.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,133 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
import os.path
|
|
3
|
+
import tempfile
|
|
4
|
+
import unittest
|
|
5
|
+
from os.path import join as pjoin
|
|
6
|
+
|
|
7
|
+
from ..Dependencies import extended_iglob
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@contextlib.contextmanager
|
|
11
|
+
def writable_file(dir_path, filename):
|
|
12
|
+
with open(pjoin(dir_path, filename), "w", encoding="utf8") as f:
|
|
13
|
+
yield f
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestGlobbing(unittest.TestCase):
|
|
17
|
+
@classmethod
|
|
18
|
+
def setUpClass(cls):
|
|
19
|
+
cls._orig_dir = os.getcwd()
|
|
20
|
+
cls._tmpdir = tempfile.TemporaryDirectory()
|
|
21
|
+
temp_path = cls._tmpdir.name
|
|
22
|
+
os.chdir(temp_path)
|
|
23
|
+
|
|
24
|
+
for dir1 in "abcd":
|
|
25
|
+
for dir1x in [dir1, dir1 + 'x']:
|
|
26
|
+
for dir2 in "xyz":
|
|
27
|
+
dir_path = pjoin(dir1x, dir2)
|
|
28
|
+
os.makedirs(dir_path)
|
|
29
|
+
with writable_file(dir_path, "file2_pyx.pyx") as f:
|
|
30
|
+
f.write('""" PYX """')
|
|
31
|
+
with writable_file(dir_path, "file2_py.py") as f:
|
|
32
|
+
f.write('""" PY """')
|
|
33
|
+
|
|
34
|
+
with writable_file(dir1x, "file1_pyx.pyx") as f:
|
|
35
|
+
f.write('""" PYX """')
|
|
36
|
+
with writable_file(dir1x, "file1_py.py") as f:
|
|
37
|
+
f.write('""" PY """')
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def tearDownClass(cls):
|
|
41
|
+
os.chdir(cls._orig_dir)
|
|
42
|
+
cls._tmpdir.cleanup()
|
|
43
|
+
|
|
44
|
+
def files_equal(self, pattern, expected_files):
|
|
45
|
+
expected_files = sorted(expected_files)
|
|
46
|
+
# It's the users's choice whether '/' will appear on Windows.
|
|
47
|
+
matched_files = sorted(path.replace('/', os.sep) for path in extended_iglob(pattern))
|
|
48
|
+
self.assertListEqual(matched_files, expected_files) # /
|
|
49
|
+
|
|
50
|
+
# Special case for Windows: also support '\' in patterns.
|
|
51
|
+
if os.sep == '\\' and '/' in pattern:
|
|
52
|
+
matched_files = sorted(extended_iglob(pattern.replace('/', '\\')))
|
|
53
|
+
self.assertListEqual(matched_files, expected_files) # \
|
|
54
|
+
|
|
55
|
+
def test_extended_iglob_simple(self):
|
|
56
|
+
ax_files = [pjoin("a", "x", "file2_pyx.pyx"), pjoin("a", "x", "file2_py.py")]
|
|
57
|
+
self.files_equal("a/x/*", ax_files)
|
|
58
|
+
self.files_equal("a/x/*.c12", [])
|
|
59
|
+
self.files_equal("a/x/*.{py,pyx,c12}", ax_files)
|
|
60
|
+
self.files_equal("a/x/*.{py,pyx}", ax_files)
|
|
61
|
+
self.files_equal("a/x/*.{pyx}", ax_files[:1])
|
|
62
|
+
self.files_equal("a/x/*.pyx", ax_files[:1])
|
|
63
|
+
self.files_equal("a/x/*.{py}", ax_files[1:])
|
|
64
|
+
self.files_equal("a/x/*.py", ax_files[1:])
|
|
65
|
+
|
|
66
|
+
def test_extended_iglob_simple_star(self):
|
|
67
|
+
for basedir in "ad":
|
|
68
|
+
files = [
|
|
69
|
+
pjoin(basedir, dirname, filename)
|
|
70
|
+
for dirname in "xyz"
|
|
71
|
+
for filename in ["file2_pyx.pyx", "file2_py.py"]
|
|
72
|
+
]
|
|
73
|
+
self.files_equal(basedir + "/*/*", files)
|
|
74
|
+
self.files_equal(basedir + "/*/*.c12", [])
|
|
75
|
+
self.files_equal(basedir + "/*/*.{py,pyx,c12}", files)
|
|
76
|
+
self.files_equal(basedir + "/*/*.{py,pyx}", files)
|
|
77
|
+
self.files_equal(basedir + "/*/*.{pyx}", files[::2])
|
|
78
|
+
self.files_equal(basedir + "/*/*.pyx", files[::2])
|
|
79
|
+
self.files_equal(basedir + "/*/*.{py}", files[1::2])
|
|
80
|
+
self.files_equal(basedir + "/*/*.py", files[1::2])
|
|
81
|
+
|
|
82
|
+
for subdir in "xy*":
|
|
83
|
+
files = [
|
|
84
|
+
pjoin(basedir, dirname, filename)
|
|
85
|
+
for dirname in "xyz"
|
|
86
|
+
if subdir in ('*', dirname)
|
|
87
|
+
for filename in ["file2_pyx.pyx", "file2_py.py"]
|
|
88
|
+
]
|
|
89
|
+
path = basedir + '/' + subdir + '/'
|
|
90
|
+
self.files_equal(path + "*", files)
|
|
91
|
+
self.files_equal(path + "*.{py,pyx}", files)
|
|
92
|
+
self.files_equal(path + "*.{pyx}", files[::2])
|
|
93
|
+
self.files_equal(path + "*.pyx", files[::2])
|
|
94
|
+
self.files_equal(path + "*.{py}", files[1::2])
|
|
95
|
+
self.files_equal(path + "*.py", files[1::2])
|
|
96
|
+
|
|
97
|
+
def test_extended_iglob_double_star(self):
|
|
98
|
+
basedirs = os.listdir(".")
|
|
99
|
+
files = [
|
|
100
|
+
pjoin(basedir, dirname, filename)
|
|
101
|
+
for basedir in basedirs
|
|
102
|
+
for dirname in "xyz"
|
|
103
|
+
for filename in ["file2_pyx.pyx", "file2_py.py"]
|
|
104
|
+
]
|
|
105
|
+
all_files = [
|
|
106
|
+
pjoin(basedir, filename)
|
|
107
|
+
for basedir in basedirs
|
|
108
|
+
for filename in ["file1_pyx.pyx", "file1_py.py"]
|
|
109
|
+
] + files
|
|
110
|
+
self.files_equal("*/*/*", files)
|
|
111
|
+
self.files_equal("*/*/**/*", files)
|
|
112
|
+
self.files_equal("*/**/*.*", all_files)
|
|
113
|
+
self.files_equal("**/*.*", all_files)
|
|
114
|
+
self.files_equal("*/**/*.c12", [])
|
|
115
|
+
self.files_equal("**/*.c12", [])
|
|
116
|
+
self.files_equal("*/*/*.{py,pyx,c12}", files)
|
|
117
|
+
self.files_equal("*/*/**/*.{py,pyx,c12}", files)
|
|
118
|
+
self.files_equal("*/**/*/*.{py,pyx,c12}", files)
|
|
119
|
+
self.files_equal("**/*/*/*.{py,pyx,c12}", files)
|
|
120
|
+
self.files_equal("**/*.{py,pyx,c12}", all_files)
|
|
121
|
+
self.files_equal("*/*/*.{py,pyx}", files)
|
|
122
|
+
self.files_equal("**/*/*/*.{py,pyx}", files)
|
|
123
|
+
self.files_equal("*/**/*/*.{py,pyx}", files)
|
|
124
|
+
self.files_equal("**/*.{py,pyx}", all_files)
|
|
125
|
+
self.files_equal("*/*/*.{pyx}", files[::2])
|
|
126
|
+
self.files_equal("**/*.{pyx}", all_files[::2])
|
|
127
|
+
self.files_equal("*/**/*/*.pyx", files[::2])
|
|
128
|
+
self.files_equal("*/*/*.pyx", files[::2])
|
|
129
|
+
self.files_equal("**/*.pyx", all_files[::2])
|
|
130
|
+
self.files_equal("*/*/*.{py}", files[1::2])
|
|
131
|
+
self.files_equal("**/*.{py}", all_files[1::2])
|
|
132
|
+
self.files_equal("*/*/*.py", files[1::2])
|
|
133
|
+
self.files_equal("**/*.py", all_files[1::2])
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import tempfile
|
|
3
|
+
import unittest
|
|
4
|
+
from Cython.Shadow import inline
|
|
5
|
+
from Cython.Build.Inline import safe_type, cymeit
|
|
6
|
+
from Cython.TestUtils import CythonTest
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import numpy
|
|
10
|
+
has_numpy = True
|
|
11
|
+
except:
|
|
12
|
+
has_numpy = False
|
|
13
|
+
|
|
14
|
+
test_kwds = dict(force=True, quiet=True)
|
|
15
|
+
|
|
16
|
+
global_value = 100
|
|
17
|
+
|
|
18
|
+
class TestInline(CythonTest):
|
|
19
|
+
def setUp(self):
|
|
20
|
+
CythonTest.setUp(self)
|
|
21
|
+
self._call_kwds = dict(test_kwds)
|
|
22
|
+
if os.path.isdir('TEST_TMP'):
|
|
23
|
+
lib_dir = os.path.join('TEST_TMP','inline')
|
|
24
|
+
else:
|
|
25
|
+
lib_dir = tempfile.mkdtemp(prefix='cython_inline_')
|
|
26
|
+
self._call_kwds['lib_dir'] = lib_dir
|
|
27
|
+
|
|
28
|
+
def test_simple(self):
|
|
29
|
+
self.assertEqual(inline("return 1+2", **self._call_kwds), 3)
|
|
30
|
+
|
|
31
|
+
def test_types(self):
|
|
32
|
+
self.assertEqual(inline("""
|
|
33
|
+
cimport cython
|
|
34
|
+
return cython.typeof(a), cython.typeof(b)
|
|
35
|
+
""", a=1.0, b=[], **self._call_kwds), ('double', 'list object'))
|
|
36
|
+
|
|
37
|
+
def test_locals(self):
|
|
38
|
+
a = 1
|
|
39
|
+
b = 2
|
|
40
|
+
self.assertEqual(inline("return a+b", **self._call_kwds), 3)
|
|
41
|
+
|
|
42
|
+
def test_globals(self):
|
|
43
|
+
self.assertEqual(inline("return global_value + 1", **self._call_kwds), global_value + 1)
|
|
44
|
+
|
|
45
|
+
def test_no_return(self):
|
|
46
|
+
self.assertEqual(inline("""
|
|
47
|
+
a = 1
|
|
48
|
+
cdef double b = 2
|
|
49
|
+
cdef c = []
|
|
50
|
+
""", **self._call_kwds), dict(a=1, b=2.0, c=[]))
|
|
51
|
+
|
|
52
|
+
def test_def_node(self):
|
|
53
|
+
foo = inline("def foo(x): return x * x", **self._call_kwds)['foo']
|
|
54
|
+
self.assertEqual(foo(7), 49)
|
|
55
|
+
|
|
56
|
+
def test_class_ref(self):
|
|
57
|
+
class Type:
|
|
58
|
+
pass
|
|
59
|
+
tp = inline("Type")['Type']
|
|
60
|
+
self.assertEqual(tp, Type)
|
|
61
|
+
|
|
62
|
+
def test_pure(self):
|
|
63
|
+
import cython as cy
|
|
64
|
+
b = inline("""
|
|
65
|
+
b = cy.declare(float, a)
|
|
66
|
+
c = cy.declare(cy.pointer(cy.float), &b)
|
|
67
|
+
return b
|
|
68
|
+
""", a=3, **self._call_kwds)
|
|
69
|
+
self.assertEqual(type(b), float)
|
|
70
|
+
|
|
71
|
+
def test_compiler_directives(self):
|
|
72
|
+
self.assertEqual(
|
|
73
|
+
inline('return sum(x)',
|
|
74
|
+
x=[1, 2, 3],
|
|
75
|
+
cython_compiler_directives={'boundscheck': False}),
|
|
76
|
+
6
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
def test_lang_version(self):
|
|
80
|
+
# GH-3419. Caching for inline code didn't always respect compiler directives.
|
|
81
|
+
inline_divcode = "def f(int a, int b): return a/b"
|
|
82
|
+
self.assertEqual(
|
|
83
|
+
inline(inline_divcode, language_level=2)['f'](5,2),
|
|
84
|
+
2
|
|
85
|
+
)
|
|
86
|
+
self.assertEqual(
|
|
87
|
+
inline(inline_divcode, language_level=3)['f'](5,2),
|
|
88
|
+
2.5
|
|
89
|
+
)
|
|
90
|
+
self.assertEqual(
|
|
91
|
+
inline(inline_divcode, language_level=2)['f'](5,2),
|
|
92
|
+
2
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def test_repeated_use(self):
|
|
96
|
+
inline_mulcode = "def f(int a, int b): return a * b"
|
|
97
|
+
self.assertEqual(inline(inline_mulcode)['f'](5, 2), 10)
|
|
98
|
+
self.assertEqual(inline(inline_mulcode)['f'](5, 3), 15)
|
|
99
|
+
self.assertEqual(inline(inline_mulcode)['f'](6, 2), 12)
|
|
100
|
+
self.assertEqual(inline(inline_mulcode)['f'](5, 2), 10)
|
|
101
|
+
|
|
102
|
+
f = inline(inline_mulcode)['f']
|
|
103
|
+
self.assertEqual(f(5, 2), 10)
|
|
104
|
+
self.assertEqual(f(5, 3), 15)
|
|
105
|
+
|
|
106
|
+
@unittest.skipIf(not has_numpy, "NumPy is not available")
|
|
107
|
+
def test_numpy(self):
|
|
108
|
+
import numpy
|
|
109
|
+
a = numpy.ndarray((10, 20))
|
|
110
|
+
a[0,0] = 10
|
|
111
|
+
self.assertEqual(safe_type(a), 'numpy.ndarray[numpy.float64_t, ndim=2]')
|
|
112
|
+
self.assertEqual(inline("return a[0,0]", a=a, **self._call_kwds), 10.0)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class TestCymeit(unittest.TestCase):
|
|
116
|
+
def _run(self, code, setup_code=None, **kwargs):
|
|
117
|
+
timings, number = cymeit(code, setup_code=setup_code, **kwargs)
|
|
118
|
+
|
|
119
|
+
self.assertGreater(min(timings), 0)
|
|
120
|
+
|
|
121
|
+
# Guard that autoscaling leads to reasonable timings.
|
|
122
|
+
# Note: we cannot compare against the expected 0.2 due to large timing variations on CI.
|
|
123
|
+
max_time = max(timing * number for timing in timings)
|
|
124
|
+
if isinstance(max_time, int):
|
|
125
|
+
self.assertGreaterEqual(max_time, 100_000)
|
|
126
|
+
else:
|
|
127
|
+
self.assertGreaterEqual(max_time, 0.0001)
|
|
128
|
+
self.assertGreater(number, 10) # arbitrary lower bound for our very quick benchmarks
|
|
129
|
+
|
|
130
|
+
return timings
|
|
131
|
+
|
|
132
|
+
def test_benchmark_simple(self):
|
|
133
|
+
setup_code = "numbers = list(range(0, 1000, 3))"
|
|
134
|
+
self._run("sum([num for num in numbers])", setup_code, repeat=3)
|
|
135
|
+
|
|
136
|
+
def test_benchmark_timer(self):
|
|
137
|
+
import time
|
|
138
|
+
setup_code = "numbers = list(range(0, 1000, 3))"
|
|
139
|
+
timings = self._run("sum([num for num in numbers])", setup_code, timer=time.perf_counter, repeat=3)
|
|
140
|
+
|
|
141
|
+
for timing in timings:
|
|
142
|
+
self.assertIsInstance(timing, float)
|
|
143
|
+
|
|
144
|
+
def test_benchmark_timer_ns(self):
|
|
145
|
+
import time
|
|
146
|
+
setup_code = "numbers = list(range(0, 1000, 3))"
|
|
147
|
+
timings = self._run("sum([num for num in numbers])", setup_code, timer=time.perf_counter_ns, repeat=3)
|
|
148
|
+
|
|
149
|
+
for timing in timings:
|
|
150
|
+
self.assertIsInstance(timing, int)
|
|
151
|
+
|
|
152
|
+
def test_benchmark_multiline_setup(self):
|
|
153
|
+
setup_code = """
|
|
154
|
+
numbers = list(range(0, 100, 3))
|
|
155
|
+
|
|
156
|
+
def csum(numbers):
|
|
157
|
+
result = 0
|
|
158
|
+
for number in numbers:
|
|
159
|
+
result += number
|
|
160
|
+
return result
|
|
161
|
+
"""
|
|
162
|
+
self._run("csum(numbers)", setup_code)
|
|
163
|
+
|
|
164
|
+
def test_benchmark_multiline_code(self):
|
|
165
|
+
setup_code = "numbers = list(range(0, 100, 3))"
|
|
166
|
+
self._run("""
|
|
167
|
+
sum([
|
|
168
|
+
num
|
|
169
|
+
for num in numbers
|
|
170
|
+
])
|
|
171
|
+
""",
|
|
172
|
+
setup_code,
|
|
173
|
+
repeat=3
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
def test_benchmark_in_module(self):
|
|
177
|
+
self._run("fsum(range(100))", import_module='math', repeat=2)
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# tag: ipython
|
|
2
|
+
|
|
3
|
+
"""Tests for the Cython magics extension."""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import io
|
|
8
|
+
import sys
|
|
9
|
+
from contextlib import contextmanager
|
|
10
|
+
from unittest import skipIf
|
|
11
|
+
|
|
12
|
+
from Cython.Build import IpythonMagic
|
|
13
|
+
from Cython.TestUtils import CythonTest
|
|
14
|
+
from Cython.Compiler.Annotate import AnnotationCCodeWriter
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import IPython.testing.globalipapp
|
|
18
|
+
except ImportError:
|
|
19
|
+
# Disable tests and fake helpers for initialisation below.
|
|
20
|
+
def skip_if_not_installed(_):
|
|
21
|
+
return None
|
|
22
|
+
else:
|
|
23
|
+
def skip_if_not_installed(c):
|
|
24
|
+
return c
|
|
25
|
+
|
|
26
|
+
# not using IPython's decorators here because they depend on "nose"
|
|
27
|
+
skip_win32 = skipIf(sys.platform == 'win32', "Skip on Windows")
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
# disable IPython history thread before it gets started to avoid having to clean it up
|
|
31
|
+
from IPython.core.history import HistoryManager
|
|
32
|
+
HistoryManager.enabled = False
|
|
33
|
+
except ImportError:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@contextmanager
|
|
38
|
+
def capture_output():
|
|
39
|
+
backup = sys.stdout, sys.stderr
|
|
40
|
+
try:
|
|
41
|
+
replacement = [
|
|
42
|
+
io.TextIOWrapper(io.BytesIO(), encoding=sys.stdout.encoding),
|
|
43
|
+
io.TextIOWrapper(io.BytesIO(), encoding=sys.stderr.encoding),
|
|
44
|
+
]
|
|
45
|
+
sys.stdout, sys.stderr = replacement
|
|
46
|
+
output = []
|
|
47
|
+
yield output
|
|
48
|
+
finally:
|
|
49
|
+
sys.stdout, sys.stderr = backup
|
|
50
|
+
for wrapper in replacement:
|
|
51
|
+
wrapper.seek(0) # rewind
|
|
52
|
+
output.append(wrapper.read())
|
|
53
|
+
wrapper.close()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
code = """\
|
|
57
|
+
def f(x):
|
|
58
|
+
return 2*x
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
cython3_code = """\
|
|
62
|
+
def f(int x):
|
|
63
|
+
return 2 / x
|
|
64
|
+
|
|
65
|
+
def call(x):
|
|
66
|
+
return f(*(x,))
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
pgo_cython3_code = cython3_code + """\
|
|
70
|
+
def main():
|
|
71
|
+
for _ in range(100): call(5)
|
|
72
|
+
main()
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
compile_error_code = '''\
|
|
76
|
+
cdef extern from *:
|
|
77
|
+
"""
|
|
78
|
+
xxx a=1;
|
|
79
|
+
"""
|
|
80
|
+
int a;
|
|
81
|
+
def doit():
|
|
82
|
+
return a
|
|
83
|
+
'''
|
|
84
|
+
|
|
85
|
+
compile_warning_code = '''\
|
|
86
|
+
cdef extern from *:
|
|
87
|
+
"""
|
|
88
|
+
#pragma message ( "CWarning" )
|
|
89
|
+
int a = 42;
|
|
90
|
+
"""
|
|
91
|
+
int a;
|
|
92
|
+
def doit():
|
|
93
|
+
return a
|
|
94
|
+
'''
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@skip_if_not_installed
|
|
98
|
+
class TestIPythonMagic(CythonTest):
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def setUpClass(cls):
|
|
102
|
+
CythonTest.setUpClass()
|
|
103
|
+
cls._ip = IPython.testing.globalipapp.get_ipython()
|
|
104
|
+
|
|
105
|
+
def setUp(self):
|
|
106
|
+
CythonTest.setUp(self)
|
|
107
|
+
self._ip.extension_manager.load_extension('cython')
|
|
108
|
+
|
|
109
|
+
def test_cython_inline(self):
|
|
110
|
+
ip = self._ip
|
|
111
|
+
ip.ex('a=10; b=20')
|
|
112
|
+
result = ip.run_cell_magic('cython_inline', '', 'return a+b')
|
|
113
|
+
self.assertEqual(result, 30)
|
|
114
|
+
|
|
115
|
+
@skip_win32
|
|
116
|
+
def test_cython_pyximport(self):
|
|
117
|
+
ip = self._ip
|
|
118
|
+
module_name = '_test_cython_pyximport'
|
|
119
|
+
ip.run_cell_magic('cython_pyximport', module_name, code)
|
|
120
|
+
ip.ex('g = f(10)')
|
|
121
|
+
self.assertEqual(ip.user_ns['g'], 20.0)
|
|
122
|
+
ip.run_cell_magic('cython_pyximport', module_name, code)
|
|
123
|
+
ip.ex('h = f(-10)')
|
|
124
|
+
self.assertEqual(ip.user_ns['h'], -20.0)
|
|
125
|
+
try:
|
|
126
|
+
os.remove(module_name + '.pyx')
|
|
127
|
+
except OSError:
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
def test_cython(self):
|
|
131
|
+
ip = self._ip
|
|
132
|
+
ip.run_cell_magic('cython', '', code)
|
|
133
|
+
ip.ex('g = f(10)')
|
|
134
|
+
self.assertEqual(ip.user_ns['g'], 20.0)
|
|
135
|
+
|
|
136
|
+
def test_cython_name(self):
|
|
137
|
+
# The Cython module named 'mymodule' defines the function f.
|
|
138
|
+
ip = self._ip
|
|
139
|
+
ip.run_cell_magic('cython', '--name=mymodule', code)
|
|
140
|
+
# This module can now be imported in the interactive namespace.
|
|
141
|
+
ip.ex('import mymodule; g = mymodule.f(10)')
|
|
142
|
+
self.assertEqual(ip.user_ns['g'], 20.0)
|
|
143
|
+
|
|
144
|
+
def test_cython_language_level(self):
|
|
145
|
+
# The Cython cell defines the functions f() and call().
|
|
146
|
+
ip = self._ip
|
|
147
|
+
ip.run_cell_magic('cython', '', cython3_code)
|
|
148
|
+
ip.ex('g = f(10); h = call(10)')
|
|
149
|
+
self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
|
|
150
|
+
self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
|
|
151
|
+
|
|
152
|
+
def test_cython3(self):
|
|
153
|
+
# The Cython cell defines the functions f() and call().
|
|
154
|
+
ip = self._ip
|
|
155
|
+
ip.run_cell_magic('cython', '-3', cython3_code)
|
|
156
|
+
ip.ex('g = f(10); h = call(10)')
|
|
157
|
+
self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
|
|
158
|
+
self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
|
|
159
|
+
|
|
160
|
+
def test_cython2(self):
|
|
161
|
+
# The Cython cell defines the functions f() and call().
|
|
162
|
+
ip = self._ip
|
|
163
|
+
ip.run_cell_magic('cython', '-2', cython3_code)
|
|
164
|
+
ip.ex('g = f(10); h = call(10)')
|
|
165
|
+
self.assertEqual(ip.user_ns['g'], 2 // 10)
|
|
166
|
+
self.assertEqual(ip.user_ns['h'], 2 // 10)
|
|
167
|
+
|
|
168
|
+
def test_cython_compile_error_shown(self):
|
|
169
|
+
ip = self._ip
|
|
170
|
+
with capture_output() as out:
|
|
171
|
+
ip.run_cell_magic('cython', '-3', compile_error_code)
|
|
172
|
+
captured_out, captured_err = out
|
|
173
|
+
|
|
174
|
+
# it could be that c-level output is captured by distutil-extension
|
|
175
|
+
# (and not by us) and is printed to stdout:
|
|
176
|
+
captured_all = captured_out + "\n" + captured_err
|
|
177
|
+
self.assertTrue("error" in captured_all, msg="error in " + captured_all)
|
|
178
|
+
|
|
179
|
+
def test_cython_link_error_shown(self):
|
|
180
|
+
ip = self._ip
|
|
181
|
+
with capture_output() as out:
|
|
182
|
+
ip.run_cell_magic('cython', '-3 -l=xxxxxxxx', code)
|
|
183
|
+
captured_out, captured_err = out
|
|
184
|
+
|
|
185
|
+
# it could be that c-level output is captured by distutil-extension
|
|
186
|
+
# (and not by us) and is printed to stdout:
|
|
187
|
+
captured_all = captured_out + "\n!" + captured_err
|
|
188
|
+
self.assertTrue("error" in captured_all, msg="error in " + captured_all)
|
|
189
|
+
|
|
190
|
+
def test_cython_warning_shown(self):
|
|
191
|
+
ip = self._ip
|
|
192
|
+
with capture_output() as out:
|
|
193
|
+
# force rebuild, otherwise no warning as after the first success
|
|
194
|
+
# no build step is performed
|
|
195
|
+
ip.run_cell_magic('cython', '-3 -f', compile_warning_code)
|
|
196
|
+
captured_out, captured_err = out
|
|
197
|
+
|
|
198
|
+
# check that warning was printed to stdout even if build hasn't failed
|
|
199
|
+
self.assertTrue("CWarning" in captured_out)
|
|
200
|
+
|
|
201
|
+
@skip_win32
|
|
202
|
+
def test_cython3_pgo(self):
|
|
203
|
+
# The Cython cell defines the functions f() and call().
|
|
204
|
+
ip = self._ip
|
|
205
|
+
ip.run_cell_magic('cython', '-3 --pgo', pgo_cython3_code)
|
|
206
|
+
ip.ex('g = f(10); h = call(10); main()')
|
|
207
|
+
self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
|
|
208
|
+
self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
|
|
209
|
+
|
|
210
|
+
@skip_win32
|
|
211
|
+
def test_extlibs(self):
|
|
212
|
+
ip = self._ip
|
|
213
|
+
code = """
|
|
214
|
+
from libc.math cimport sin
|
|
215
|
+
x = sin(0.0)
|
|
216
|
+
"""
|
|
217
|
+
ip.user_ns['x'] = 1
|
|
218
|
+
ip.run_cell_magic('cython', '-l m', code)
|
|
219
|
+
self.assertEqual(ip.user_ns['x'], 0)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def test_cython_verbose(self):
|
|
223
|
+
ip = self._ip
|
|
224
|
+
ip.run_cell_magic('cython', '--verbose', code)
|
|
225
|
+
ip.ex('g = f(10)')
|
|
226
|
+
self.assertEqual(ip.user_ns['g'], 20.0)
|
|
227
|
+
|
|
228
|
+
def test_cython_verbose_thresholds(self):
|
|
229
|
+
@contextmanager
|
|
230
|
+
def mock_distutils():
|
|
231
|
+
class MockLog:
|
|
232
|
+
DEBUG = 1
|
|
233
|
+
INFO = 2
|
|
234
|
+
thresholds = [INFO]
|
|
235
|
+
|
|
236
|
+
def set_threshold(self, val):
|
|
237
|
+
self.thresholds.append(val)
|
|
238
|
+
return self.thresholds[-2]
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
new_log = MockLog()
|
|
242
|
+
old_log = IpythonMagic.distutils.log
|
|
243
|
+
try:
|
|
244
|
+
IpythonMagic.distutils.log = new_log
|
|
245
|
+
yield new_log
|
|
246
|
+
finally:
|
|
247
|
+
IpythonMagic.distutils.log = old_log
|
|
248
|
+
|
|
249
|
+
ip = self._ip
|
|
250
|
+
with mock_distutils() as verbose_log:
|
|
251
|
+
ip.run_cell_magic('cython', '--verbose', code)
|
|
252
|
+
ip.ex('g = f(10)')
|
|
253
|
+
self.assertEqual(ip.user_ns['g'], 20.0)
|
|
254
|
+
self.assertEqual([verbose_log.INFO, verbose_log.DEBUG, verbose_log.INFO],
|
|
255
|
+
verbose_log.thresholds)
|
|
256
|
+
|
|
257
|
+
with mock_distutils() as normal_log:
|
|
258
|
+
ip.run_cell_magic('cython', '', code)
|
|
259
|
+
ip.ex('g = f(10)')
|
|
260
|
+
self.assertEqual(ip.user_ns['g'], 20.0)
|
|
261
|
+
self.assertEqual([normal_log.INFO], normal_log.thresholds)
|
|
262
|
+
|
|
263
|
+
def test_cython_no_annotate(self):
|
|
264
|
+
ip = self._ip
|
|
265
|
+
html = ip.run_cell_magic('cython', '', code)
|
|
266
|
+
self.assertTrue(html is None)
|
|
267
|
+
|
|
268
|
+
def test_cython_annotate(self):
|
|
269
|
+
ip = self._ip
|
|
270
|
+
html = ip.run_cell_magic('cython', '--annotate', code)
|
|
271
|
+
# somewhat brittle way to differentiate between annotated htmls
|
|
272
|
+
# with/without complete source code:
|
|
273
|
+
self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html.data)
|
|
274
|
+
|
|
275
|
+
def test_cython_annotate_default(self):
|
|
276
|
+
ip = self._ip
|
|
277
|
+
html = ip.run_cell_magic('cython', '-a', code)
|
|
278
|
+
# somewhat brittle way to differentiate between annotated htmls
|
|
279
|
+
# with/without complete source code:
|
|
280
|
+
self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html.data)
|
|
281
|
+
|
|
282
|
+
def test_cython_annotate_complete_c_code(self):
|
|
283
|
+
ip = self._ip
|
|
284
|
+
html = ip.run_cell_magic('cython', '--annotate-fullc', code)
|
|
285
|
+
# somewhat brittle way to differentiate between annotated htmls
|
|
286
|
+
# with/without complete source code:
|
|
287
|
+
self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE in html.data)
|