Cython 3.2.0__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 +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,285 @@
|
|
|
1
|
+
import os.path
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
from Cython.TestUtils import TransformTest
|
|
5
|
+
from Cython.Compiler.ParseTreeTransforms import *
|
|
6
|
+
from Cython.Compiler.ParseTreeTransforms import _calculate_pickle_checksums
|
|
7
|
+
from Cython.Compiler.Nodes import *
|
|
8
|
+
from Cython.Compiler import Main, Symtab, Options
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestNormalizeTree(TransformTest):
|
|
12
|
+
def test_parserbehaviour_is_what_we_coded_for(self):
|
|
13
|
+
t = self.fragment("if x: y").root
|
|
14
|
+
self.assertLines("""
|
|
15
|
+
(root): StatListNode
|
|
16
|
+
stats[0]: IfStatNode
|
|
17
|
+
if_clauses[0]: IfClauseNode
|
|
18
|
+
condition: NameNode
|
|
19
|
+
body: ExprStatNode
|
|
20
|
+
expr: NameNode
|
|
21
|
+
""", self.treetypes(t))
|
|
22
|
+
|
|
23
|
+
def test_wrap_singlestat(self):
|
|
24
|
+
t = self.run_pipeline([NormalizeTree(None)], "if x: y")
|
|
25
|
+
self.assertLines("""
|
|
26
|
+
(root): StatListNode
|
|
27
|
+
stats[0]: IfStatNode
|
|
28
|
+
if_clauses[0]: IfClauseNode
|
|
29
|
+
condition: NameNode
|
|
30
|
+
body: StatListNode
|
|
31
|
+
stats[0]: ExprStatNode
|
|
32
|
+
expr: NameNode
|
|
33
|
+
""", self.treetypes(t))
|
|
34
|
+
|
|
35
|
+
def test_wrap_multistat(self):
|
|
36
|
+
t = self.run_pipeline([NormalizeTree(None)], """
|
|
37
|
+
if z:
|
|
38
|
+
x
|
|
39
|
+
y
|
|
40
|
+
""")
|
|
41
|
+
self.assertLines("""
|
|
42
|
+
(root): StatListNode
|
|
43
|
+
stats[0]: IfStatNode
|
|
44
|
+
if_clauses[0]: IfClauseNode
|
|
45
|
+
condition: NameNode
|
|
46
|
+
body: StatListNode
|
|
47
|
+
stats[0]: ExprStatNode
|
|
48
|
+
expr: NameNode
|
|
49
|
+
stats[1]: ExprStatNode
|
|
50
|
+
expr: NameNode
|
|
51
|
+
""", self.treetypes(t))
|
|
52
|
+
|
|
53
|
+
def test_statinexpr(self):
|
|
54
|
+
t = self.run_pipeline([NormalizeTree(None)], """
|
|
55
|
+
a, b = x, y
|
|
56
|
+
""")
|
|
57
|
+
self.assertLines("""
|
|
58
|
+
(root): StatListNode
|
|
59
|
+
stats[0]: SingleAssignmentNode
|
|
60
|
+
lhs: TupleNode
|
|
61
|
+
args[0]: NameNode
|
|
62
|
+
args[1]: NameNode
|
|
63
|
+
rhs: TupleNode
|
|
64
|
+
args[0]: NameNode
|
|
65
|
+
args[1]: NameNode
|
|
66
|
+
""", self.treetypes(t))
|
|
67
|
+
|
|
68
|
+
def test_wrap_offagain(self):
|
|
69
|
+
t = self.run_pipeline([NormalizeTree(None)], """
|
|
70
|
+
x
|
|
71
|
+
y
|
|
72
|
+
if z:
|
|
73
|
+
x
|
|
74
|
+
""")
|
|
75
|
+
self.assertLines("""
|
|
76
|
+
(root): StatListNode
|
|
77
|
+
stats[0]: ExprStatNode
|
|
78
|
+
expr: NameNode
|
|
79
|
+
stats[1]: ExprStatNode
|
|
80
|
+
expr: NameNode
|
|
81
|
+
stats[2]: IfStatNode
|
|
82
|
+
if_clauses[0]: IfClauseNode
|
|
83
|
+
condition: NameNode
|
|
84
|
+
body: StatListNode
|
|
85
|
+
stats[0]: ExprStatNode
|
|
86
|
+
expr: NameNode
|
|
87
|
+
""", self.treetypes(t))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class TestWithTransform: # (TransformTest): # Disabled!
|
|
91
|
+
|
|
92
|
+
def test_simplified(self):
|
|
93
|
+
t = self.run_pipeline([WithTransform(None)], """
|
|
94
|
+
with x:
|
|
95
|
+
y = z ** 3
|
|
96
|
+
""")
|
|
97
|
+
|
|
98
|
+
self.assertCode("""
|
|
99
|
+
|
|
100
|
+
$0_0 = x
|
|
101
|
+
$0_2 = $0_0.__exit__
|
|
102
|
+
$0_0.__enter__()
|
|
103
|
+
$0_1 = True
|
|
104
|
+
try:
|
|
105
|
+
try:
|
|
106
|
+
$1_0 = None
|
|
107
|
+
y = z ** 3
|
|
108
|
+
except:
|
|
109
|
+
$0_1 = False
|
|
110
|
+
if (not $0_2($1_0)):
|
|
111
|
+
raise
|
|
112
|
+
finally:
|
|
113
|
+
if $0_1:
|
|
114
|
+
$0_2(None, None, None)
|
|
115
|
+
|
|
116
|
+
""", t)
|
|
117
|
+
|
|
118
|
+
def test_basic(self):
|
|
119
|
+
t = self.run_pipeline([WithTransform(None)], """
|
|
120
|
+
with x as y:
|
|
121
|
+
y = z ** 3
|
|
122
|
+
""")
|
|
123
|
+
self.assertCode("""
|
|
124
|
+
|
|
125
|
+
$0_0 = x
|
|
126
|
+
$0_2 = $0_0.__exit__
|
|
127
|
+
$0_3 = $0_0.__enter__()
|
|
128
|
+
$0_1 = True
|
|
129
|
+
try:
|
|
130
|
+
try:
|
|
131
|
+
$1_0 = None
|
|
132
|
+
y = $0_3
|
|
133
|
+
y = z ** 3
|
|
134
|
+
except:
|
|
135
|
+
$0_1 = False
|
|
136
|
+
if (not $0_2($1_0)):
|
|
137
|
+
raise
|
|
138
|
+
finally:
|
|
139
|
+
if $0_1:
|
|
140
|
+
$0_2(None, None, None)
|
|
141
|
+
|
|
142
|
+
""", t)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class TestInterpretCompilerDirectives(TransformTest):
|
|
146
|
+
"""
|
|
147
|
+
This class tests the parallel directives AST-rewriting and importing.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
# Test the parallel directives (c)importing
|
|
151
|
+
|
|
152
|
+
import_code = """
|
|
153
|
+
cimport cython.parallel
|
|
154
|
+
cimport cython.parallel as par
|
|
155
|
+
from cython cimport parallel as par2
|
|
156
|
+
from cython cimport parallel
|
|
157
|
+
|
|
158
|
+
from cython.parallel cimport threadid as tid
|
|
159
|
+
from cython.parallel cimport threadavailable as tavail
|
|
160
|
+
from cython.parallel cimport prange
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
expected_directives_dict = {
|
|
164
|
+
'cython.parallel': 'cython.parallel',
|
|
165
|
+
'par': 'cython.parallel',
|
|
166
|
+
'par2': 'cython.parallel',
|
|
167
|
+
'parallel': 'cython.parallel',
|
|
168
|
+
|
|
169
|
+
"tid": "cython.parallel.threadid",
|
|
170
|
+
"tavail": "cython.parallel.threadavailable",
|
|
171
|
+
"prange": "cython.parallel.prange",
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def setUp(self):
|
|
176
|
+
super().setUp()
|
|
177
|
+
|
|
178
|
+
compilation_options = Options.CompilationOptions(Options.default_options)
|
|
179
|
+
ctx = Main.Context.from_options(compilation_options)
|
|
180
|
+
|
|
181
|
+
transform = InterpretCompilerDirectives(ctx, ctx.compiler_directives)
|
|
182
|
+
transform.module_scope = Symtab.ModuleScope('__main__', None, ctx)
|
|
183
|
+
self.pipeline = [transform]
|
|
184
|
+
|
|
185
|
+
self.debug_exception_on_error = DebugFlags.debug_exception_on_error
|
|
186
|
+
|
|
187
|
+
def tearDown(self):
|
|
188
|
+
DebugFlags.debug_exception_on_error = self.debug_exception_on_error
|
|
189
|
+
|
|
190
|
+
def test_parallel_directives_cimports(self):
|
|
191
|
+
self.run_pipeline(self.pipeline, self.import_code)
|
|
192
|
+
parallel_directives = self.pipeline[0].parallel_directives
|
|
193
|
+
self.assertEqual(parallel_directives, self.expected_directives_dict)
|
|
194
|
+
|
|
195
|
+
def test_parallel_directives_imports(self):
|
|
196
|
+
self.run_pipeline(self.pipeline,
|
|
197
|
+
self.import_code.replace('cimport', 'import'))
|
|
198
|
+
parallel_directives = self.pipeline[0].parallel_directives
|
|
199
|
+
self.assertEqual(parallel_directives, self.expected_directives_dict)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
# TODO: Re-enable once they're more robust.
|
|
203
|
+
if False:
|
|
204
|
+
from Cython.Debugger import DebugWriter
|
|
205
|
+
from Cython.Debugger.Tests.TestLibCython import DebuggerTestCase
|
|
206
|
+
else:
|
|
207
|
+
# skip test, don't let it inherit unittest.TestCase
|
|
208
|
+
DebuggerTestCase = object
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class TestDebugTransform(DebuggerTestCase):
|
|
212
|
+
|
|
213
|
+
def elem_hasattrs(self, elem, attrs):
|
|
214
|
+
return all(attr in elem.attrib for attr in attrs)
|
|
215
|
+
|
|
216
|
+
def test_debug_info(self):
|
|
217
|
+
try:
|
|
218
|
+
assert os.path.exists(self.debug_dest)
|
|
219
|
+
|
|
220
|
+
t = DebugWriter.etree.parse(self.debug_dest)
|
|
221
|
+
# the xpath of the standard ElementTree is primitive, don't use
|
|
222
|
+
# anything fancy
|
|
223
|
+
L = list(t.find('/Module/Globals'))
|
|
224
|
+
assert L
|
|
225
|
+
xml_globals = {e.attrib['name']: e.attrib['type'] for e in L}
|
|
226
|
+
self.assertEqual(len(L), len(xml_globals))
|
|
227
|
+
|
|
228
|
+
L = list(t.find('/Module/Functions'))
|
|
229
|
+
assert L
|
|
230
|
+
xml_funcs = {e.attrib['qualified_name']: e for e in L}
|
|
231
|
+
self.assertEqual(len(L), len(xml_funcs))
|
|
232
|
+
|
|
233
|
+
# test globals
|
|
234
|
+
self.assertEqual('CObject', xml_globals.get('c_var'))
|
|
235
|
+
self.assertEqual('PythonObject', xml_globals.get('python_var'))
|
|
236
|
+
|
|
237
|
+
# test functions
|
|
238
|
+
funcnames = ('codefile.spam', 'codefile.ham', 'codefile.eggs',
|
|
239
|
+
'codefile.closure', 'codefile.inner')
|
|
240
|
+
required_xml_attrs = 'name', 'cname', 'qualified_name'
|
|
241
|
+
assert all(f in xml_funcs for f in funcnames)
|
|
242
|
+
spam, ham, eggs = [xml_funcs[funcname] for funcname in funcnames]
|
|
243
|
+
|
|
244
|
+
self.assertEqual(spam.attrib['name'], 'spam')
|
|
245
|
+
self.assertNotEqual('spam', spam.attrib['cname'])
|
|
246
|
+
assert self.elem_hasattrs(spam, required_xml_attrs)
|
|
247
|
+
|
|
248
|
+
# test locals of functions
|
|
249
|
+
spam_locals = list(spam.find('Locals'))
|
|
250
|
+
assert spam_locals
|
|
251
|
+
spam_locals.sort(key=lambda e: e.attrib['name'])
|
|
252
|
+
names = [e.attrib['name'] for e in spam_locals]
|
|
253
|
+
self.assertEqual(list('abcd'), names)
|
|
254
|
+
assert self.elem_hasattrs(spam_locals[0], required_xml_attrs)
|
|
255
|
+
|
|
256
|
+
# test arguments of functions
|
|
257
|
+
spam_arguments = list(spam.find('Arguments'))
|
|
258
|
+
assert spam_arguments
|
|
259
|
+
self.assertEqual(1, len(list(spam_arguments)))
|
|
260
|
+
|
|
261
|
+
# test step-into functions
|
|
262
|
+
step_into = spam.find('StepIntoFunctions')
|
|
263
|
+
spam_stepinto = [x.attrib['name'] for x in step_into]
|
|
264
|
+
assert spam_stepinto
|
|
265
|
+
self.assertEqual(2, len(spam_stepinto))
|
|
266
|
+
assert 'puts' in spam_stepinto
|
|
267
|
+
assert 'some_c_function' in spam_stepinto
|
|
268
|
+
except:
|
|
269
|
+
f = open(self.debug_dest)
|
|
270
|
+
try:
|
|
271
|
+
print(f.read())
|
|
272
|
+
finally:
|
|
273
|
+
f.close()
|
|
274
|
+
raise
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class TestAnalyseDeclarationsTransform(unittest.TestCase):
|
|
278
|
+
def test_calculate_pickle_checksums(self):
|
|
279
|
+
checksums = _calculate_pickle_checksums(['member1', 'member2', 'member3'])
|
|
280
|
+
assert 2 <= len(checksums) <= 3, checksums # expecting ['0xc0af380' (MD5), '0x0c75bd4', '0xa7a7b94']
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
if __name__ == "__main__":
|
|
284
|
+
import unittest
|
|
285
|
+
unittest.main()
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from io import StringIO
|
|
3
|
+
import string
|
|
4
|
+
|
|
5
|
+
from .. import Scanning
|
|
6
|
+
from ..Symtab import ModuleScope
|
|
7
|
+
from ..TreeFragment import StringParseContext
|
|
8
|
+
from ..Errors import init_thread
|
|
9
|
+
|
|
10
|
+
# generate some fake code - just a bunch of lines of the form "a0 a1 ..."
|
|
11
|
+
code = []
|
|
12
|
+
for ch in string.ascii_lowercase:
|
|
13
|
+
line = " ".join(["%s%s" % (ch, n) for n in range(10)])
|
|
14
|
+
code.append(line)
|
|
15
|
+
code = "\n".join(code)
|
|
16
|
+
|
|
17
|
+
init_thread()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TestScanning(unittest.TestCase):
|
|
21
|
+
def make_scanner(self):
|
|
22
|
+
source = Scanning.StringSourceDescriptor("fake code", code)
|
|
23
|
+
buf = StringIO(code)
|
|
24
|
+
context = StringParseContext("fake context")
|
|
25
|
+
scope = ModuleScope("fake_module", None, None)
|
|
26
|
+
|
|
27
|
+
return Scanning.PyrexScanner(buf, source, scope=scope, context=context)
|
|
28
|
+
|
|
29
|
+
def test_put_back_positions(self):
|
|
30
|
+
scanner = self.make_scanner()
|
|
31
|
+
|
|
32
|
+
self.assertEqual(scanner.sy, "IDENT")
|
|
33
|
+
self.assertEqual(scanner.systring, "a0")
|
|
34
|
+
scanner.next()
|
|
35
|
+
self.assertEqual(scanner.sy, "IDENT")
|
|
36
|
+
self.assertEqual(scanner.systring, "a1")
|
|
37
|
+
a1pos = scanner.last_token_position_tuple
|
|
38
|
+
self.assertEqual(a1pos[1:], (1, 3))
|
|
39
|
+
a2peek = scanner.peek() # shouldn't mess up the position
|
|
40
|
+
self.assertEqual(a1pos, scanner.last_token_position_tuple)
|
|
41
|
+
scanner.next()
|
|
42
|
+
self.assertEqual(a2peek, (scanner.sy, scanner.systring))
|
|
43
|
+
|
|
44
|
+
# find next line
|
|
45
|
+
while scanner.sy != "NEWLINE":
|
|
46
|
+
scanner.next()
|
|
47
|
+
|
|
48
|
+
line_sy = []
|
|
49
|
+
line_systring = []
|
|
50
|
+
line_pos = []
|
|
51
|
+
|
|
52
|
+
scanner.next()
|
|
53
|
+
while scanner.sy != "NEWLINE":
|
|
54
|
+
line_sy.append(scanner.sy)
|
|
55
|
+
line_systring.append(scanner.systring)
|
|
56
|
+
line_pos.append(scanner.last_token_position_tuple)
|
|
57
|
+
scanner.next()
|
|
58
|
+
|
|
59
|
+
for sy, systring, pos in zip(
|
|
60
|
+
line_sy[::-1], line_systring[::-1], line_pos[::-1]
|
|
61
|
+
):
|
|
62
|
+
scanner.put_back(sy, systring, pos)
|
|
63
|
+
|
|
64
|
+
n = 0
|
|
65
|
+
while scanner.sy != "NEWLINE":
|
|
66
|
+
self.assertEqual(scanner.sy, line_sy[n])
|
|
67
|
+
self.assertEqual(scanner.systring, line_systring[n])
|
|
68
|
+
self.assertEqual(scanner.last_token_position_tuple, line_pos[n])
|
|
69
|
+
scanner.next()
|
|
70
|
+
n += 1
|
|
71
|
+
|
|
72
|
+
self.assertEqual(n, len(line_pos))
|
|
73
|
+
|
|
74
|
+
def test_tentatively_scan(self):
|
|
75
|
+
scanner = self.make_scanner()
|
|
76
|
+
with Scanning.tentatively_scan(scanner) as errors:
|
|
77
|
+
while scanner.sy != "NEWLINE":
|
|
78
|
+
scanner.next()
|
|
79
|
+
self.assertFalse(errors)
|
|
80
|
+
|
|
81
|
+
scanner.next()
|
|
82
|
+
self.assertEqual(scanner.systring, "b0")
|
|
83
|
+
pos = scanner.last_token_position_tuple
|
|
84
|
+
with Scanning.tentatively_scan(scanner) as errors:
|
|
85
|
+
while scanner.sy != "NEWLINE":
|
|
86
|
+
scanner.next()
|
|
87
|
+
if scanner.systring == "b7":
|
|
88
|
+
scanner.error("Oh no not b7!")
|
|
89
|
+
break
|
|
90
|
+
self.assertTrue(errors)
|
|
91
|
+
self.assertEqual(scanner.systring, "b0") # state has been restored
|
|
92
|
+
self.assertEqual(scanner.last_token_position_tuple, pos)
|
|
93
|
+
scanner.next()
|
|
94
|
+
self.assertEqual(scanner.systring, "b1") # and we can keep going again
|
|
95
|
+
scanner.next()
|
|
96
|
+
self.assertEqual(scanner.systring, "b2") # and we can keep going again
|
|
97
|
+
|
|
98
|
+
with Scanning.tentatively_scan(scanner) as error:
|
|
99
|
+
scanner.error("Something has gone wrong with the current symbol")
|
|
100
|
+
self.assertEqual(scanner.systring, "b2")
|
|
101
|
+
scanner.next()
|
|
102
|
+
self.assertEqual(scanner.systring, "b3")
|
|
103
|
+
|
|
104
|
+
# test a few combinations of nested scanning
|
|
105
|
+
sy1, systring1 = scanner.sy, scanner.systring
|
|
106
|
+
pos1 = scanner.last_token_position_tuple
|
|
107
|
+
with Scanning.tentatively_scan(scanner):
|
|
108
|
+
scanner.next()
|
|
109
|
+
sy2, systring2 = scanner.sy, scanner.systring
|
|
110
|
+
pos2 = scanner.last_token_position_tuple
|
|
111
|
+
with Scanning.tentatively_scan(scanner):
|
|
112
|
+
with Scanning.tentatively_scan(scanner):
|
|
113
|
+
scanner.next()
|
|
114
|
+
scanner.next()
|
|
115
|
+
scanner.error("Ooops")
|
|
116
|
+
self.assertEqual((scanner.sy, scanner.systring), (sy2, systring2))
|
|
117
|
+
self.assertEqual((scanner.sy, scanner.systring), (sy2, systring2))
|
|
118
|
+
scanner.error("eee")
|
|
119
|
+
self.assertEqual((scanner.sy, scanner.systring), (sy1, systring1))
|
|
120
|
+
with Scanning.tentatively_scan(scanner):
|
|
121
|
+
scanner.next()
|
|
122
|
+
scanner.next()
|
|
123
|
+
with Scanning.tentatively_scan(scanner):
|
|
124
|
+
scanner.next()
|
|
125
|
+
# no error - but this block should be unwound by the outer block too
|
|
126
|
+
scanner.next()
|
|
127
|
+
scanner.error("Oooops")
|
|
128
|
+
self.assertEqual((scanner.sy, scanner.systring), (sy1, systring1))
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
unittest.main()
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from Cython.Compiler import PyrexTypes as pt
|
|
4
|
+
from Cython.Compiler.ExprNodes import NameNode
|
|
5
|
+
from Cython.Compiler.PyrexTypes import CFuncTypeArg
|
|
6
|
+
|
|
7
|
+
def cfunctype(*arg_types):
|
|
8
|
+
return pt.CFuncType(pt.c_int_type,
|
|
9
|
+
[ CFuncTypeArg("name", arg_type, None) for arg_type in arg_types ])
|
|
10
|
+
|
|
11
|
+
def cppclasstype(name, base_classes):
|
|
12
|
+
return pt.CppClassType(name, None, 'CPP_'+name, base_classes)
|
|
13
|
+
|
|
14
|
+
class SignatureMatcherTest(unittest.TestCase):
|
|
15
|
+
"""
|
|
16
|
+
Test the signature matching algorithm for overloaded signatures.
|
|
17
|
+
"""
|
|
18
|
+
def assertMatches(self, expected_type, arg_types, functions):
|
|
19
|
+
match = pt.best_match(arg_types, functions)
|
|
20
|
+
if expected_type is not None:
|
|
21
|
+
self.assertNotEqual(None, match)
|
|
22
|
+
self.assertEqual(expected_type, match.type)
|
|
23
|
+
|
|
24
|
+
def test_cpp_reference_single_arg(self):
|
|
25
|
+
function_types = [
|
|
26
|
+
cfunctype(pt.CReferenceType(pt.c_int_type)),
|
|
27
|
+
cfunctype(pt.CReferenceType(pt.c_long_type)),
|
|
28
|
+
cfunctype(pt.CReferenceType(pt.c_double_type)),
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
functions = [ NameNode(None, type=t) for t in function_types ]
|
|
32
|
+
self.assertMatches(function_types[0], [pt.c_int_type], functions)
|
|
33
|
+
self.assertMatches(function_types[1], [pt.c_long_type], functions)
|
|
34
|
+
self.assertMatches(function_types[2], [pt.c_double_type], functions)
|
|
35
|
+
|
|
36
|
+
def test_cpp_reference_two_args(self):
|
|
37
|
+
function_types = [
|
|
38
|
+
cfunctype(
|
|
39
|
+
pt.CReferenceType(pt.c_int_type), pt.CReferenceType(pt.c_long_type)),
|
|
40
|
+
cfunctype(
|
|
41
|
+
pt.CReferenceType(pt.c_long_type), pt.CReferenceType(pt.c_long_type)),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
functions = [ NameNode(None, type=t) for t in function_types ]
|
|
45
|
+
self.assertMatches(function_types[0], [pt.c_int_type, pt.c_long_type], functions)
|
|
46
|
+
self.assertMatches(function_types[1], [pt.c_long_type, pt.c_long_type], functions)
|
|
47
|
+
self.assertMatches(function_types[1], [pt.c_long_type, pt.c_int_type], functions)
|
|
48
|
+
|
|
49
|
+
def test_cpp_reference_cpp_class(self):
|
|
50
|
+
classes = [ cppclasstype("Test%d" % i, []) for i in range(2) ]
|
|
51
|
+
function_types = [
|
|
52
|
+
cfunctype(pt.CReferenceType(classes[0])),
|
|
53
|
+
cfunctype(pt.CReferenceType(classes[1])),
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
functions = [ NameNode(None, type=t) for t in function_types ]
|
|
57
|
+
self.assertMatches(function_types[0], [classes[0]], functions)
|
|
58
|
+
self.assertMatches(function_types[1], [classes[1]], functions)
|
|
59
|
+
|
|
60
|
+
def test_cpp_reference_cpp_class_and_int(self):
|
|
61
|
+
classes = [ cppclasstype("Test%d" % i, []) for i in range(2) ]
|
|
62
|
+
function_types = [
|
|
63
|
+
cfunctype(pt.CReferenceType(classes[0]), pt.c_int_type),
|
|
64
|
+
cfunctype(pt.CReferenceType(classes[0]), pt.c_long_type),
|
|
65
|
+
cfunctype(pt.CReferenceType(classes[1]), pt.c_int_type),
|
|
66
|
+
cfunctype(pt.CReferenceType(classes[1]), pt.c_long_type),
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
functions = [ NameNode(None, type=t) for t in function_types ]
|
|
70
|
+
self.assertMatches(function_types[0], [classes[0], pt.c_int_type], functions)
|
|
71
|
+
self.assertMatches(function_types[1], [classes[0], pt.c_long_type], functions)
|
|
72
|
+
self.assertMatches(function_types[2], [classes[1], pt.c_int_type], functions)
|
|
73
|
+
self.assertMatches(function_types[3], [classes[1], pt.c_long_type], functions)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
import Cython.Compiler.StringEncoding as StringEncoding
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class StringEncodingTest(unittest.TestCase):
|
|
7
|
+
"""
|
|
8
|
+
Test the StringEncoding module.
|
|
9
|
+
"""
|
|
10
|
+
def test_string_contains_lone_surrogates(self):
|
|
11
|
+
self.assertFalse(StringEncoding.string_contains_lone_surrogates("abc"))
|
|
12
|
+
self.assertFalse(StringEncoding.string_contains_lone_surrogates("\uABCD"))
|
|
13
|
+
self.assertFalse(StringEncoding.string_contains_lone_surrogates("\N{SNOWMAN}"))
|
|
14
|
+
|
|
15
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uD800\uDFFF"))
|
|
16
|
+
obfuscated_surrogate_pair = ("\uDFFF" + "\uD800")[::-1]
|
|
17
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates(obfuscated_surrogate_pair))
|
|
18
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uD800"))
|
|
19
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uDFFF"))
|
|
20
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uDFFF\uD800"))
|
|
21
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uD800x\uDFFF"))
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from Cython.TestUtils import CythonTest
|
|
2
|
+
from Cython.Compiler.TreeFragment import *
|
|
3
|
+
from Cython.Compiler.Nodes import *
|
|
4
|
+
from Cython.Compiler.UtilNodes import *
|
|
5
|
+
|
|
6
|
+
class TestTreeFragments(CythonTest):
|
|
7
|
+
|
|
8
|
+
def test_basic(self):
|
|
9
|
+
F = self.fragment("x = 4")
|
|
10
|
+
T = F.copy()
|
|
11
|
+
self.assertCode("x = 4", T)
|
|
12
|
+
|
|
13
|
+
def test_copy_is_taken(self):
|
|
14
|
+
F = self.fragment("if True: x = 4")
|
|
15
|
+
T1 = F.root
|
|
16
|
+
T2 = F.copy()
|
|
17
|
+
self.assertEqual("x", T2.stats[0].if_clauses[0].body.lhs.name)
|
|
18
|
+
T2.stats[0].if_clauses[0].body.lhs.name = "other"
|
|
19
|
+
self.assertEqual("x", T1.stats[0].if_clauses[0].body.lhs.name)
|
|
20
|
+
|
|
21
|
+
def test_substitutions_are_copied(self):
|
|
22
|
+
T = self.fragment("y + y").substitute({"y": NameNode(pos=None, name="x")})
|
|
23
|
+
self.assertEqual("x", T.stats[0].expr.operand1.name)
|
|
24
|
+
self.assertEqual("x", T.stats[0].expr.operand2.name)
|
|
25
|
+
self.assertTrue(T.stats[0].expr.operand1 is not T.stats[0].expr.operand2)
|
|
26
|
+
|
|
27
|
+
def test_substitution(self):
|
|
28
|
+
F = self.fragment("x = 4")
|
|
29
|
+
y = NameNode(pos=None, name="y")
|
|
30
|
+
T = F.substitute({"x" : y})
|
|
31
|
+
self.assertCode("y = 4", T)
|
|
32
|
+
|
|
33
|
+
def test_exprstat(self):
|
|
34
|
+
F = self.fragment("PASS")
|
|
35
|
+
pass_stat = PassStatNode(pos=None)
|
|
36
|
+
T = F.substitute({"PASS" : pass_stat})
|
|
37
|
+
self.assertTrue(isinstance(T.stats[0], PassStatNode), T)
|
|
38
|
+
|
|
39
|
+
def test_pos_is_transferred(self):
|
|
40
|
+
F = self.fragment("""
|
|
41
|
+
x = y
|
|
42
|
+
x = u * v ** w
|
|
43
|
+
""")
|
|
44
|
+
T = F.substitute({"v" : NameNode(pos=None, name="a")})
|
|
45
|
+
v = F.root.stats[1].rhs.operand2.operand1
|
|
46
|
+
a = T.stats[1].rhs.operand2.operand1
|
|
47
|
+
self.assertEqual(v.pos, a.pos)
|
|
48
|
+
|
|
49
|
+
def test_temps(self):
|
|
50
|
+
TemplateTransform.temp_name_counter = 0
|
|
51
|
+
F = self.fragment("""
|
|
52
|
+
TMP
|
|
53
|
+
x = TMP
|
|
54
|
+
""")
|
|
55
|
+
T = F.substitute(temps=["TMP"])
|
|
56
|
+
s = T.body.stats
|
|
57
|
+
self.assertTrue(isinstance(s[0].expr, TempRefNode))
|
|
58
|
+
self.assertTrue(isinstance(s[1].rhs, TempRefNode))
|
|
59
|
+
self.assertTrue(s[0].expr.handle is s[1].rhs.handle)
|
|
60
|
+
|
|
61
|
+
if __name__ == "__main__":
|
|
62
|
+
import unittest
|
|
63
|
+
unittest.main()
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from Cython.TestUtils import TransformTest
|
|
3
|
+
from Cython.Compiler.TreePath import find_first, find_all
|
|
4
|
+
from Cython.Compiler import Nodes, ExprNodes
|
|
5
|
+
|
|
6
|
+
class TestTreePath(TransformTest):
|
|
7
|
+
_tree = None
|
|
8
|
+
|
|
9
|
+
def _build_tree(self):
|
|
10
|
+
if self._tree is None:
|
|
11
|
+
self._tree = self.run_pipeline([], """
|
|
12
|
+
def decorator(fun): # DefNode
|
|
13
|
+
return fun # ReturnStatNode, NameNode
|
|
14
|
+
@decorator # NameNode
|
|
15
|
+
def decorated(): # DefNode
|
|
16
|
+
pass
|
|
17
|
+
""")
|
|
18
|
+
return self._tree
|
|
19
|
+
|
|
20
|
+
def test_node_path(self):
|
|
21
|
+
t = self._build_tree()
|
|
22
|
+
self.assertEqual(2, len(find_all(t, "//DefNode")))
|
|
23
|
+
self.assertEqual(2, len(find_all(t, "//NameNode")))
|
|
24
|
+
self.assertEqual(1, len(find_all(t, "//ReturnStatNode")))
|
|
25
|
+
self.assertEqual(1, len(find_all(t, "//DefNode//ReturnStatNode")))
|
|
26
|
+
|
|
27
|
+
def test_node_path_star(self):
|
|
28
|
+
t = self._build_tree()
|
|
29
|
+
self.assertEqual(10, len(find_all(t, "//*")))
|
|
30
|
+
self.assertEqual(8, len(find_all(t, "//DefNode//*")))
|
|
31
|
+
self.assertEqual(0, len(find_all(t, "//NameNode//*")))
|
|
32
|
+
|
|
33
|
+
def test_node_path_attribute(self):
|
|
34
|
+
t = self._build_tree()
|
|
35
|
+
self.assertEqual(2, len(find_all(t, "//NameNode/@name")))
|
|
36
|
+
self.assertEqual(['fun', 'decorator'], find_all(t, "//NameNode/@name"))
|
|
37
|
+
|
|
38
|
+
def test_node_path_attribute_dotted(self):
|
|
39
|
+
t = self._build_tree()
|
|
40
|
+
self.assertEqual(1, len(find_all(t, "//ReturnStatNode/@value.name")))
|
|
41
|
+
self.assertEqual(['fun'], find_all(t, "//ReturnStatNode/@value.name"))
|
|
42
|
+
|
|
43
|
+
def test_node_path_child(self):
|
|
44
|
+
t = self._build_tree()
|
|
45
|
+
self.assertEqual(1, len(find_all(t, "//DefNode/ReturnStatNode/NameNode")))
|
|
46
|
+
self.assertEqual(1, len(find_all(t, "//ReturnStatNode/NameNode")))
|
|
47
|
+
|
|
48
|
+
def test_node_path_node_predicate(self):
|
|
49
|
+
t = self._build_tree()
|
|
50
|
+
self.assertEqual(0, len(find_all(t, "//DefNode[.//ForInStatNode]")))
|
|
51
|
+
self.assertEqual(2, len(find_all(t, "//DefNode[.//NameNode]")))
|
|
52
|
+
self.assertEqual(1, len(find_all(t, "//ReturnStatNode[./NameNode]")))
|
|
53
|
+
self.assertEqual(Nodes.ReturnStatNode,
|
|
54
|
+
type(find_first(t, "//ReturnStatNode[./NameNode]")))
|
|
55
|
+
|
|
56
|
+
def test_node_path_node_predicate_step(self):
|
|
57
|
+
t = self._build_tree()
|
|
58
|
+
self.assertEqual(2, len(find_all(t, "//DefNode[.//NameNode]")))
|
|
59
|
+
self.assertEqual(8, len(find_all(t, "//DefNode[.//NameNode]//*")))
|
|
60
|
+
self.assertEqual(1, len(find_all(t, "//DefNode[.//NameNode]//ReturnStatNode")))
|
|
61
|
+
self.assertEqual(Nodes.ReturnStatNode,
|
|
62
|
+
type(find_first(t, "//DefNode[.//NameNode]//ReturnStatNode")))
|
|
63
|
+
|
|
64
|
+
def test_node_path_attribute_exists(self):
|
|
65
|
+
t = self._build_tree()
|
|
66
|
+
self.assertEqual(2, len(find_all(t, "//NameNode[@name]")))
|
|
67
|
+
self.assertEqual(ExprNodes.NameNode,
|
|
68
|
+
type(find_first(t, "//NameNode[@name]")))
|
|
69
|
+
|
|
70
|
+
def test_node_path_attribute_exists_not(self):
|
|
71
|
+
t = self._build_tree()
|
|
72
|
+
self.assertEqual(0, len(find_all(t, "//NameNode[not(@name)]")))
|
|
73
|
+
self.assertEqual(2, len(find_all(t, "//NameNode[not(@honking)]")))
|
|
74
|
+
|
|
75
|
+
def test_node_path_and(self):
|
|
76
|
+
t = self._build_tree()
|
|
77
|
+
self.assertEqual(1, len(find_all(t, "//DefNode[.//ReturnStatNode and .//NameNode]")))
|
|
78
|
+
self.assertEqual(0, len(find_all(t, "//DefNode[.//ReturnStatNode and .//DecoratorNode]")))
|
|
79
|
+
self.assertEqual(0, len(find_all(t, "//NameNode[@honking and @name]")))
|
|
80
|
+
self.assertEqual(0, len(find_all(t, "//NameNode[@name and @honking]")))
|
|
81
|
+
self.assertEqual(2, len(find_all(t, "//DefNode[.//NameNode[@name] and @name]")))
|
|
82
|
+
|
|
83
|
+
def test_node_path_or(self):
|
|
84
|
+
t = self._build_tree()
|
|
85
|
+
self.assertEqual(2, len(find_all(t, "//DefNode[.//ReturnStatNode or .//DecoratorNode]")))
|
|
86
|
+
self.assertEqual(2, len(find_all(t, "//NameNode[@name]")))
|
|
87
|
+
self.assertEqual(0, len(find_all(t, "//NameNode[@honking]")))
|
|
88
|
+
self.assertEqual(2, len(find_all(t, "//NameNode[@name or @honking]")))
|
|
89
|
+
self.assertEqual(2, len(find_all(t, "//NameNode[@honking or @name]")))
|
|
90
|
+
self.assertEqual(2, len(find_all(t, "//DefNode[.//NameNode[@name] or @name]")))
|
|
91
|
+
|
|
92
|
+
def test_node_path_attribute_string_predicate(self):
|
|
93
|
+
t = self._build_tree()
|
|
94
|
+
self.assertEqual(1, len(find_all(t, "//NameNode[@name = 'decorator']")))
|
|
95
|
+
|
|
96
|
+
def test_node_path_recursive_predicate(self):
|
|
97
|
+
t = self._build_tree()
|
|
98
|
+
self.assertEqual(2, len(find_all(t, "//DefNode[.//NameNode[@name]]")))
|
|
99
|
+
self.assertEqual(1, len(find_all(t, "//DefNode[.//NameNode[@name = 'decorator']]")))
|
|
100
|
+
self.assertEqual(1, len(find_all(t, "//DefNode[.//ReturnStatNode[./NameNode[@name = 'fun']]/NameNode]")))
|
|
101
|
+
|
|
102
|
+
if __name__ == '__main__':
|
|
103
|
+
unittest.main()
|