Cython 3.1.0__py3-none-any.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 +323 -0
- Cython/Build/Dependencies.py +1306 -0
- Cython/Build/Distutils.py +1 -0
- Cython/Build/Inline.py +463 -0
- Cython/Build/IpythonMagic.py +560 -0
- Cython/Build/SharedModule.py +76 -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 +8 -0
- Cython/CodeWriter.py +811 -0
- Cython/Compiler/AnalysedTreeTransforms.py +97 -0
- Cython/Compiler/Annotate.py +326 -0
- Cython/Compiler/AutoDocTransforms.py +320 -0
- Cython/Compiler/Buffer.py +680 -0
- Cython/Compiler/Builtin.py +934 -0
- Cython/Compiler/CmdLine.py +259 -0
- Cython/Compiler/Code.pxd +148 -0
- Cython/Compiler/Code.py +3375 -0
- Cython/Compiler/CodeGeneration.py +33 -0
- Cython/Compiler/CythonScope.py +187 -0
- Cython/Compiler/Dataclass.py +868 -0
- Cython/Compiler/DebugFlags.py +24 -0
- Cython/Compiler/Errors.py +295 -0
- Cython/Compiler/ExprNodes.py +15267 -0
- Cython/Compiler/FlowControl.pxd +97 -0
- Cython/Compiler/FlowControl.py +1455 -0
- Cython/Compiler/FusedNode.py +1002 -0
- Cython/Compiler/Future.py +16 -0
- Cython/Compiler/Interpreter.py +57 -0
- Cython/Compiler/Lexicon.py +340 -0
- Cython/Compiler/LineTable.py +114 -0
- Cython/Compiler/Main.py +853 -0
- Cython/Compiler/MatchCaseNodes.py +259 -0
- Cython/Compiler/MemoryView.py +922 -0
- Cython/Compiler/ModuleNode.py +4024 -0
- Cython/Compiler/Naming.py +374 -0
- Cython/Compiler/Nodes.py +10826 -0
- Cython/Compiler/Optimize.py +5256 -0
- Cython/Compiler/Options.py +835 -0
- Cython/Compiler/ParseTreeTransforms.pxd +77 -0
- Cython/Compiler/ParseTreeTransforms.py +4509 -0
- Cython/Compiler/Parsing.pxd +9 -0
- Cython/Compiler/Parsing.py +4789 -0
- Cython/Compiler/Pipeline.py +439 -0
- Cython/Compiler/PyrexTypes.py +5762 -0
- Cython/Compiler/Pythran.py +232 -0
- Cython/Compiler/Scanning.pxd +40 -0
- Cython/Compiler/Scanning.py +577 -0
- Cython/Compiler/StringEncoding.py +347 -0
- Cython/Compiler/Symtab.py +3080 -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 +86 -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 +33 -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 +584 -0
- Cython/Compiler/TypeSlots.py +1181 -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/__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 +174 -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 +67 -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 +84 -0
- Cython/Includes/libc/time.pxd +51 -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/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 +130 -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 +44 -0
- Cython/Includes/libcpp/set.pxd +228 -0
- Cython/Includes/libcpp/shared_mutex.pxd +72 -0
- Cython/Includes/libcpp/span.pxd +87 -0
- Cython/Includes/libcpp/stack.pxd +11 -0
- Cython/Includes/libcpp/stop_token.pxd +105 -0
- Cython/Includes/libcpp/string.pxd +355 -0
- Cython/Includes/libcpp/string_view.pxd +181 -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/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/DFA.pxd +14 -0
- Cython/Plex/DFA.py +164 -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/Regexps.py +539 -0
- Cython/Plex/Scanners.pxd +47 -0
- Cython/Plex/Scanners.py +360 -0
- Cython/Plex/Transitions.pxd +14 -0
- Cython/Plex/Transitions.py +239 -0
- Cython/Plex/__init__.py +34 -0
- Cython/Runtime/__init__.py +1 -0
- Cython/Runtime/refnanny.pyx +237 -0
- Cython/Shadow.py +690 -0
- Cython/Shadow.pyi +521 -0
- Cython/StringIOTree.py +170 -0
- Cython/Tempita/__init__.py +4 -0
- Cython/Tempita/_looper.py +154 -0
- Cython/Tempita/_tempita.py +1091 -0
- Cython/TestUtils.py +410 -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 +1002 -0
- Cython/Utility/Buffer.c +875 -0
- Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
- Cython/Utility/Builtins.c +776 -0
- Cython/Utility/CConvert.pyx +134 -0
- Cython/Utility/CMath.c +104 -0
- Cython/Utility/CommonStructures.c +118 -0
- Cython/Utility/Complex.c +378 -0
- Cython/Utility/Coroutine.c +2206 -0
- Cython/Utility/CpdefEnums.pyx +103 -0
- Cython/Utility/CppConvert.pyx +279 -0
- Cython/Utility/CppSupport.cpp +143 -0
- Cython/Utility/CythonFunction.c +1794 -0
- Cython/Utility/Dataclasses.c +185 -0
- Cython/Utility/Dataclasses.py +112 -0
- Cython/Utility/Embed.c +125 -0
- Cython/Utility/Exceptions.c +1012 -0
- Cython/Utility/ExtensionTypes.c +809 -0
- Cython/Utility/FunctionArguments.c +965 -0
- Cython/Utility/ImportExport.c +987 -0
- Cython/Utility/Lock.c +136 -0
- Cython/Utility/MemoryView.pxd +187 -0
- Cython/Utility/MemoryView.pyx +1481 -0
- Cython/Utility/MemoryView_C.c +1046 -0
- Cython/Utility/ModuleSetupCode.c +3059 -0
- Cython/Utility/NumpyImportArray.c +46 -0
- Cython/Utility/ObjectHandling.c +3342 -0
- Cython/Utility/Optimize.c +1589 -0
- Cython/Utility/Overflow.c +404 -0
- Cython/Utility/Printing.c +86 -0
- Cython/Utility/Profile.c +709 -0
- Cython/Utility/StringTools.c +1259 -0
- Cython/Utility/TestCyUtilityLoader.pyx +8 -0
- Cython/Utility/TestCythonScope.pyx +75 -0
- Cython/Utility/TestUtilityLoader.c +12 -0
- Cython/Utility/TypeConversion.c +1284 -0
- Cython/Utility/UFuncs.pyx +50 -0
- Cython/Utility/UFuncs_C.c +89 -0
- Cython/Utility/__init__.py +28 -0
- Cython/Utility/arrayarray.h +148 -0
- Cython/Utils.py +687 -0
- Cython/__init__.py +10 -0
- Cython/__init__.pyi +7 -0
- Cython/py.typed +0 -0
- cython-3.1.0.dist-info/COPYING.txt +19 -0
- cython-3.1.0.dist-info/LICENSE.txt +176 -0
- cython-3.1.0.dist-info/METADATA +636 -0
- cython-3.1.0.dist-info/RECORD +316 -0
- cython-3.1.0.dist-info/WHEEL +5 -0
- cython-3.1.0.dist-info/entry_points.txt +4 -0
- cython-3.1.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,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,33 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
import Cython.Compiler.StringEncoding as StringEncoding
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StringEncodingTest(unittest.TestCase):
|
|
8
|
+
"""
|
|
9
|
+
Test the StringEncoding module.
|
|
10
|
+
"""
|
|
11
|
+
def test_string_contains_lone_surrogates(self):
|
|
12
|
+
self.assertFalse(StringEncoding.string_contains_lone_surrogates("abc"))
|
|
13
|
+
self.assertFalse(StringEncoding.string_contains_lone_surrogates("\uABCD"))
|
|
14
|
+
self.assertFalse(StringEncoding.string_contains_lone_surrogates("\N{SNOWMAN}"))
|
|
15
|
+
|
|
16
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uD800\uDFFF"))
|
|
17
|
+
obfuscated_surrogate_pair = ("\uDFFF" + "\uD800")[::-1]
|
|
18
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates(obfuscated_surrogate_pair))
|
|
19
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uD800"))
|
|
20
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uDFFF"))
|
|
21
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uDFFF\uD800"))
|
|
22
|
+
self.assertTrue(StringEncoding.string_contains_lone_surrogates("\uD800x\uDFFF"))
|
|
23
|
+
|
|
24
|
+
def test_string_contains_surrogates(self):
|
|
25
|
+
self.assertFalse(StringEncoding.string_contains_surrogates("abc"))
|
|
26
|
+
self.assertFalse(StringEncoding.string_contains_surrogates("\uABCD"))
|
|
27
|
+
self.assertFalse(StringEncoding.string_contains_surrogates("\N{SNOWMAN}"))
|
|
28
|
+
|
|
29
|
+
self.assertTrue(StringEncoding.string_contains_surrogates("\uD800"))
|
|
30
|
+
self.assertTrue(StringEncoding.string_contains_surrogates("\uDFFF"))
|
|
31
|
+
self.assertTrue(StringEncoding.string_contains_surrogates("\uD800\uDFFF"))
|
|
32
|
+
self.assertTrue(StringEncoding.string_contains_surrogates("\uDFFF\uD800"))
|
|
33
|
+
self.assertTrue(StringEncoding.string_contains_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()
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
import Cython.Compiler.PyrexTypes as PT
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestMethodDispatcherTransform(unittest.TestCase):
|
|
7
|
+
|
|
8
|
+
def test_widest_numeric_type(self):
|
|
9
|
+
def assert_widest(type1, type2, widest):
|
|
10
|
+
self.assertEqual(widest, PT.widest_numeric_type(type1, type2))
|
|
11
|
+
|
|
12
|
+
assert_widest(PT.c_int_type, PT.c_long_type, PT.c_long_type)
|
|
13
|
+
assert_widest(PT.c_double_type, PT.c_long_type, PT.c_double_type)
|
|
14
|
+
assert_widest(PT.c_longdouble_type, PT.c_long_type, PT.c_longdouble_type)
|
|
15
|
+
|
|
16
|
+
cenum = PT.CEnumType("E", "cenum", typedef_flag=False)
|
|
17
|
+
assert_widest(PT.c_int_type, cenum, PT.c_int_type)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TestTypeIdentifiers(unittest.TestCase):
|
|
21
|
+
|
|
22
|
+
TEST_DATA = [
|
|
23
|
+
("char*", "char__ptr"),
|
|
24
|
+
("char *", "char__ptr"),
|
|
25
|
+
("char **", "char__ptr__ptr"),
|
|
26
|
+
("_typedef", "_typedef"),
|
|
27
|
+
("__typedef", "__dundertypedef"),
|
|
28
|
+
("___typedef", "__dunder_typedef"),
|
|
29
|
+
("____typedef", "__dunder__dundertypedef"),
|
|
30
|
+
("_____typedef", "__dunder__dunder_typedef"),
|
|
31
|
+
("const __typedef", "__const___dundertypedef"),
|
|
32
|
+
("int[42]", "int__lArr42__rArr"),
|
|
33
|
+
("int[:]", "int__lArr__D__rArr"),
|
|
34
|
+
("int[:,:]", "int__lArr__D__comma___D__rArr"),
|
|
35
|
+
("int[:,:,:]", "int__lArr__D__comma___D__comma___D__rArr"),
|
|
36
|
+
("int[:,:,...]", "int__lArr__D__comma___D__comma___EL__rArr"),
|
|
37
|
+
("std::vector", "std__in_vector"),
|
|
38
|
+
("std::vector&&", "std__in_vector__fwref"),
|
|
39
|
+
("const std::vector", "__const_std__in_vector"),
|
|
40
|
+
("const std::vector&", "__const_std__in_vector__ref"),
|
|
41
|
+
("const_std", "const_std"),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
def test_escape_special_type_characters(self):
|
|
45
|
+
test_func = PT._escape_special_type_characters # keep test usage visible for IDEs
|
|
46
|
+
function_name = "_escape_special_type_characters"
|
|
47
|
+
self._test_escape(function_name)
|
|
48
|
+
|
|
49
|
+
def test_type_identifier_for_declaration(self):
|
|
50
|
+
test_func = PT.type_identifier_from_declaration # keep test usage visible for IDEs
|
|
51
|
+
function_name = test_func.__name__
|
|
52
|
+
self._test_escape(function_name)
|
|
53
|
+
|
|
54
|
+
# differences due to whitespace removal
|
|
55
|
+
test_data = [
|
|
56
|
+
("const &std::vector", "const__refstd__in_vector"),
|
|
57
|
+
("const &std::vector<int>", "const__refstd__in_vector__lAngint__rAng"),
|
|
58
|
+
("const &&std::vector", "const__fwrefstd__in_vector"),
|
|
59
|
+
("const &&&std::vector", "const__fwref__refstd__in_vector"),
|
|
60
|
+
("const &&std::vector", "const__fwrefstd__in_vector"),
|
|
61
|
+
("void (*func)(int x, float y)",
|
|
62
|
+
"975d51__void__lParen__ptrfunc__rParen__lParenint__spac__etc"),
|
|
63
|
+
("float ** (*func)(int x, int[:] y)",
|
|
64
|
+
"31883a__float__ptr__ptr__lParen__ptrfunc__rParen__lPar__etc"),
|
|
65
|
+
]
|
|
66
|
+
self._test_escape(function_name, test_data)
|
|
67
|
+
|
|
68
|
+
def _test_escape(self, func_name, test_data=TEST_DATA):
|
|
69
|
+
escape = getattr(PT, func_name)
|
|
70
|
+
for declaration, expected in test_data:
|
|
71
|
+
escaped_value = escape(declaration)
|
|
72
|
+
self.assertEqual(escaped_value, expected, "%s('%s') == '%s' != '%s'" % (
|
|
73
|
+
func_name, declaration, escaped_value, expected))
|
|
74
|
+
# test that the length has been successfully capped
|
|
75
|
+
self.assertLessEqual(len(escaped_value), 64)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from Cython.Compiler import Code, UtilityCode
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def strip_2tup(tup):
|
|
7
|
+
return tup[0] and tup[0].strip(), tup[1] and tup[1].strip()
|
|
8
|
+
|
|
9
|
+
class TestUtilityLoader(unittest.TestCase):
|
|
10
|
+
"""
|
|
11
|
+
Test loading UtilityCodes
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
expected = "test {{loader}} prototype", "test {{loader}} impl"
|
|
15
|
+
|
|
16
|
+
required = "req {{loader}} proto", "req {{loader}} impl"
|
|
17
|
+
|
|
18
|
+
context = dict(loader='Loader')
|
|
19
|
+
|
|
20
|
+
name = "TestUtilityLoader"
|
|
21
|
+
filename = "TestUtilityLoader.c"
|
|
22
|
+
cls = Code.UtilityCode
|
|
23
|
+
|
|
24
|
+
def test_load_as_string(self):
|
|
25
|
+
got = strip_2tup(self.cls.load_as_string(self.name, self.filename))
|
|
26
|
+
self.assertEqual(got, self.expected)
|
|
27
|
+
|
|
28
|
+
def test_load(self):
|
|
29
|
+
utility = self.cls.load(self.name, from_file=self.filename)
|
|
30
|
+
got = strip_2tup((utility.proto, utility.impl))
|
|
31
|
+
self.assertEqual(got, self.expected)
|
|
32
|
+
|
|
33
|
+
required, = utility.requires
|
|
34
|
+
got = strip_2tup((required.proto, required.impl))
|
|
35
|
+
self.assertEqual(got, self.required)
|
|
36
|
+
|
|
37
|
+
utility = self.cls.load_cached(self.name, from_file=self.filename)
|
|
38
|
+
got = strip_2tup((utility.proto, utility.impl))
|
|
39
|
+
self.assertEqual(got, self.expected)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class TestTempitaUtilityLoader(TestUtilityLoader):
|
|
43
|
+
"""
|
|
44
|
+
Test loading UtilityCodes with Tempita substitution
|
|
45
|
+
"""
|
|
46
|
+
expected_tempita = (TestUtilityLoader.expected[0].replace('{{loader}}', 'Loader'),
|
|
47
|
+
TestUtilityLoader.expected[1].replace('{{loader}}', 'Loader'))
|
|
48
|
+
|
|
49
|
+
required_tempita = (TestUtilityLoader.required[0].replace('{{loader}}', 'Loader'),
|
|
50
|
+
TestUtilityLoader.required[1].replace('{{loader}}', 'Loader'))
|
|
51
|
+
|
|
52
|
+
cls = Code.TempitaUtilityCode
|
|
53
|
+
|
|
54
|
+
def test_load_as_string(self):
|
|
55
|
+
got = strip_2tup(self.cls.load_as_string(self.name, self.filename, context=self.context))
|
|
56
|
+
self.assertEqual(got, self.expected_tempita)
|
|
57
|
+
|
|
58
|
+
def test_load(self):
|
|
59
|
+
utility = self.cls.load(self.name, self.filename, context=self.context)
|
|
60
|
+
got = strip_2tup((utility.proto, utility.impl))
|
|
61
|
+
self.assertEqual(got, self.expected_tempita)
|
|
62
|
+
|
|
63
|
+
required, = utility.requires
|
|
64
|
+
got = strip_2tup((required.proto, required.impl))
|
|
65
|
+
self.assertEqual(got, self.required_tempita)
|
|
66
|
+
|
|
67
|
+
utility = self.cls.load(self.name, from_file=self.filename, context=self.context)
|
|
68
|
+
got = strip_2tup((utility.proto, utility.impl))
|
|
69
|
+
self.assertEqual(got, self.expected_tempita)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TestCythonUtilityLoader(TestTempitaUtilityLoader):
|
|
73
|
+
"""
|
|
74
|
+
Test loading CythonUtilityCodes
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
# Just change the attributes and run the same tests
|
|
78
|
+
expected = None, "test {{cy_loader}} impl"
|
|
79
|
+
expected_tempita = None, "test CyLoader impl"
|
|
80
|
+
|
|
81
|
+
required = None, "req {{cy_loader}} impl"
|
|
82
|
+
required_tempita = None, "req CyLoader impl"
|
|
83
|
+
|
|
84
|
+
context = dict(cy_loader='CyLoader')
|
|
85
|
+
|
|
86
|
+
name = "TestCyUtilityLoader"
|
|
87
|
+
filename = "TestCyUtilityLoader.pyx"
|
|
88
|
+
cls = UtilityCode.CythonUtilityCode
|
|
89
|
+
|
|
90
|
+
# Small hack to pass our tests above
|
|
91
|
+
cls.proto = None
|
|
92
|
+
|
|
93
|
+
test_load = TestUtilityLoader.test_load
|
|
94
|
+
test_load_tempita = TestTempitaUtilityLoader.test_load
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestUtilityCode(unittest.TestCase):
|
|
98
|
+
def test_equality(self):
|
|
99
|
+
c1 = Code.UtilityCode.load("NumpyImportUFunc", "NumpyImportArray.c")
|
|
100
|
+
c2 = Code.UtilityCode.load("NumpyImportArray", "NumpyImportArray.c")
|
|
101
|
+
c3 = Code.UtilityCode.load("pyunicode_strlen", "StringTools.c")
|
|
102
|
+
c4 = Code.UtilityCode.load("pyunicode_from_unicode", "StringTools.c")
|
|
103
|
+
c5 = Code.UtilityCode.load("IncludeStringH", "StringTools.c")
|
|
104
|
+
c6 = Code.UtilityCode.load("IncludeCppStringH", "StringTools.c")
|
|
105
|
+
|
|
106
|
+
codes = [c1, c2, c3, c4, c5, c6]
|
|
107
|
+
for m in range(len(codes)):
|
|
108
|
+
for n in range(len(codes)):
|
|
109
|
+
if n == m:
|
|
110
|
+
self.assertEqual(codes[m], codes[n])
|
|
111
|
+
else:
|
|
112
|
+
self.assertNotEqual(codes[m], codes[n])
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from Cython.Compiler.ModuleNode import ModuleNode
|
|
2
|
+
from Cython.Compiler.Symtab import ModuleScope
|
|
3
|
+
from Cython.TestUtils import TransformTest
|
|
4
|
+
from Cython.Compiler.Visitor import MethodDispatcherTransform
|
|
5
|
+
from Cython.Compiler.ParseTreeTransforms import (
|
|
6
|
+
NormalizeTree, AnalyseDeclarationsTransform,
|
|
7
|
+
AnalyseExpressionsTransform, InterpretCompilerDirectives)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestMethodDispatcherTransform(TransformTest):
|
|
11
|
+
_tree = None
|
|
12
|
+
|
|
13
|
+
def _build_tree(self):
|
|
14
|
+
if self._tree is None:
|
|
15
|
+
context = None
|
|
16
|
+
|
|
17
|
+
def fake_module(node):
|
|
18
|
+
scope = ModuleScope('test', None, None)
|
|
19
|
+
return ModuleNode(node.pos, doc=None, body=node,
|
|
20
|
+
scope=scope, full_module_name='test',
|
|
21
|
+
directive_comments={})
|
|
22
|
+
pipeline = [
|
|
23
|
+
fake_module,
|
|
24
|
+
NormalizeTree(context),
|
|
25
|
+
InterpretCompilerDirectives(context, {}),
|
|
26
|
+
AnalyseDeclarationsTransform(context),
|
|
27
|
+
AnalyseExpressionsTransform(context),
|
|
28
|
+
]
|
|
29
|
+
self._tree = self.run_pipeline(pipeline, """
|
|
30
|
+
cdef bytes s = b'asdfg'
|
|
31
|
+
cdef dict d = {1:2}
|
|
32
|
+
x = s * 3
|
|
33
|
+
d.get('test')
|
|
34
|
+
""")
|
|
35
|
+
return self._tree
|
|
36
|
+
|
|
37
|
+
def test_builtin_method(self):
|
|
38
|
+
calls = [0]
|
|
39
|
+
class Test(MethodDispatcherTransform):
|
|
40
|
+
def _handle_simple_method_dict_get(self, node, func, args, unbound):
|
|
41
|
+
calls[0] += 1
|
|
42
|
+
return node
|
|
43
|
+
|
|
44
|
+
tree = self._build_tree()
|
|
45
|
+
Test(None)(tree)
|
|
46
|
+
self.assertEqual(1, calls[0])
|
|
47
|
+
|
|
48
|
+
def test_binop_method(self):
|
|
49
|
+
calls = {'bytes': 0, 'object': 0}
|
|
50
|
+
class Test(MethodDispatcherTransform):
|
|
51
|
+
def _handle_simple_method_bytes___mul__(self, node, func, args, unbound):
|
|
52
|
+
calls['bytes'] += 1
|
|
53
|
+
return node
|
|
54
|
+
def _handle_simple_method_object___mul__(self, node, func, args, unbound):
|
|
55
|
+
calls['object'] += 1
|
|
56
|
+
return node
|
|
57
|
+
|
|
58
|
+
tree = self._build_tree()
|
|
59
|
+
Test(None)(tree)
|
|
60
|
+
self.assertEqual(1, calls['bytes'])
|
|
61
|
+
self.assertEqual(0, calls['object'])
|