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.
Files changed (316) hide show
  1. Cython/Build/BuildExecutable.py +169 -0
  2. Cython/Build/Cache.py +199 -0
  3. Cython/Build/Cythonize.py +323 -0
  4. Cython/Build/Dependencies.py +1306 -0
  5. Cython/Build/Distutils.py +1 -0
  6. Cython/Build/Inline.py +463 -0
  7. Cython/Build/IpythonMagic.py +560 -0
  8. Cython/Build/SharedModule.py +76 -0
  9. Cython/Build/Tests/TestCyCache.py +194 -0
  10. Cython/Build/Tests/TestCythonizeArgsParser.py +481 -0
  11. Cython/Build/Tests/TestDependencies.py +133 -0
  12. Cython/Build/Tests/TestInline.py +177 -0
  13. Cython/Build/Tests/TestIpythonMagic.py +287 -0
  14. Cython/Build/Tests/TestRecythonize.py +212 -0
  15. Cython/Build/Tests/TestStripLiterals.py +155 -0
  16. Cython/Build/Tests/__init__.py +1 -0
  17. Cython/Build/__init__.py +8 -0
  18. Cython/CodeWriter.py +811 -0
  19. Cython/Compiler/AnalysedTreeTransforms.py +97 -0
  20. Cython/Compiler/Annotate.py +326 -0
  21. Cython/Compiler/AutoDocTransforms.py +320 -0
  22. Cython/Compiler/Buffer.py +680 -0
  23. Cython/Compiler/Builtin.py +934 -0
  24. Cython/Compiler/CmdLine.py +259 -0
  25. Cython/Compiler/Code.pxd +148 -0
  26. Cython/Compiler/Code.py +3375 -0
  27. Cython/Compiler/CodeGeneration.py +33 -0
  28. Cython/Compiler/CythonScope.py +187 -0
  29. Cython/Compiler/Dataclass.py +868 -0
  30. Cython/Compiler/DebugFlags.py +24 -0
  31. Cython/Compiler/Errors.py +295 -0
  32. Cython/Compiler/ExprNodes.py +15267 -0
  33. Cython/Compiler/FlowControl.pxd +97 -0
  34. Cython/Compiler/FlowControl.py +1455 -0
  35. Cython/Compiler/FusedNode.py +1002 -0
  36. Cython/Compiler/Future.py +16 -0
  37. Cython/Compiler/Interpreter.py +57 -0
  38. Cython/Compiler/Lexicon.py +340 -0
  39. Cython/Compiler/LineTable.py +114 -0
  40. Cython/Compiler/Main.py +853 -0
  41. Cython/Compiler/MatchCaseNodes.py +259 -0
  42. Cython/Compiler/MemoryView.py +922 -0
  43. Cython/Compiler/ModuleNode.py +4024 -0
  44. Cython/Compiler/Naming.py +374 -0
  45. Cython/Compiler/Nodes.py +10826 -0
  46. Cython/Compiler/Optimize.py +5256 -0
  47. Cython/Compiler/Options.py +835 -0
  48. Cython/Compiler/ParseTreeTransforms.pxd +77 -0
  49. Cython/Compiler/ParseTreeTransforms.py +4509 -0
  50. Cython/Compiler/Parsing.pxd +9 -0
  51. Cython/Compiler/Parsing.py +4789 -0
  52. Cython/Compiler/Pipeline.py +439 -0
  53. Cython/Compiler/PyrexTypes.py +5762 -0
  54. Cython/Compiler/Pythran.py +232 -0
  55. Cython/Compiler/Scanning.pxd +40 -0
  56. Cython/Compiler/Scanning.py +577 -0
  57. Cython/Compiler/StringEncoding.py +347 -0
  58. Cython/Compiler/Symtab.py +3080 -0
  59. Cython/Compiler/Tests/TestBuffer.py +105 -0
  60. Cython/Compiler/Tests/TestBuiltin.py +72 -0
  61. Cython/Compiler/Tests/TestCmdLine.py +586 -0
  62. Cython/Compiler/Tests/TestCode.py +86 -0
  63. Cython/Compiler/Tests/TestFlowControl.py +65 -0
  64. Cython/Compiler/Tests/TestGrammar.py +202 -0
  65. Cython/Compiler/Tests/TestMemView.py +71 -0
  66. Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
  67. Cython/Compiler/Tests/TestScanning.py +134 -0
  68. Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
  69. Cython/Compiler/Tests/TestStringEncoding.py +33 -0
  70. Cython/Compiler/Tests/TestTreeFragment.py +63 -0
  71. Cython/Compiler/Tests/TestTreePath.py +103 -0
  72. Cython/Compiler/Tests/TestTypes.py +75 -0
  73. Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
  74. Cython/Compiler/Tests/TestVisitor.py +61 -0
  75. Cython/Compiler/Tests/Utils.py +36 -0
  76. Cython/Compiler/Tests/__init__.py +1 -0
  77. Cython/Compiler/TreeFragment.py +278 -0
  78. Cython/Compiler/TreePath.py +303 -0
  79. Cython/Compiler/TypeInference.py +584 -0
  80. Cython/Compiler/TypeSlots.py +1181 -0
  81. Cython/Compiler/UFuncs.py +311 -0
  82. Cython/Compiler/UtilNodes.py +389 -0
  83. Cython/Compiler/UtilityCode.py +344 -0
  84. Cython/Compiler/Version.py +8 -0
  85. Cython/Compiler/Visitor.pxd +53 -0
  86. Cython/Compiler/Visitor.py +861 -0
  87. Cython/Compiler/__init__.py +1 -0
  88. Cython/Coverage.py +448 -0
  89. Cython/Debugger/Cygdb.py +175 -0
  90. Cython/Debugger/DebugWriter.py +82 -0
  91. Cython/Debugger/Tests/TestLibCython.py +275 -0
  92. Cython/Debugger/Tests/__init__.py +1 -0
  93. Cython/Debugger/Tests/cfuncs.c +8 -0
  94. Cython/Debugger/Tests/codefile +49 -0
  95. Cython/Debugger/Tests/test_libcython_in_gdb.py +578 -0
  96. Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
  97. Cython/Debugger/__init__.py +1 -0
  98. Cython/Debugger/libcython.py +1548 -0
  99. Cython/Debugger/libpython.py +2821 -0
  100. Cython/Debugging.py +20 -0
  101. Cython/Distutils/__init__.py +2 -0
  102. Cython/Distutils/build_ext.py +139 -0
  103. Cython/Distutils/extension.py +96 -0
  104. Cython/Distutils/old_build_ext.py +351 -0
  105. Cython/Includes/cpython/__init__.pxd +173 -0
  106. Cython/Includes/cpython/array.pxd +174 -0
  107. Cython/Includes/cpython/bool.pxd +37 -0
  108. Cython/Includes/cpython/buffer.pxd +112 -0
  109. Cython/Includes/cpython/bytearray.pxd +33 -0
  110. Cython/Includes/cpython/bytes.pxd +200 -0
  111. Cython/Includes/cpython/cellobject.pxd +35 -0
  112. Cython/Includes/cpython/ceval.pxd +8 -0
  113. Cython/Includes/cpython/codecs.pxd +121 -0
  114. Cython/Includes/cpython/complex.pxd +60 -0
  115. Cython/Includes/cpython/contextvars.pxd +145 -0
  116. Cython/Includes/cpython/conversion.pxd +36 -0
  117. Cython/Includes/cpython/datetime.pxd +395 -0
  118. Cython/Includes/cpython/descr.pxd +26 -0
  119. Cython/Includes/cpython/dict.pxd +187 -0
  120. Cython/Includes/cpython/exc.pxd +263 -0
  121. Cython/Includes/cpython/fileobject.pxd +57 -0
  122. Cython/Includes/cpython/float.pxd +47 -0
  123. Cython/Includes/cpython/function.pxd +65 -0
  124. Cython/Includes/cpython/genobject.pxd +25 -0
  125. Cython/Includes/cpython/getargs.pxd +12 -0
  126. Cython/Includes/cpython/instance.pxd +25 -0
  127. Cython/Includes/cpython/iterator.pxd +36 -0
  128. Cython/Includes/cpython/iterobject.pxd +24 -0
  129. Cython/Includes/cpython/list.pxd +92 -0
  130. Cython/Includes/cpython/long.pxd +149 -0
  131. Cython/Includes/cpython/longintrepr.pxd +14 -0
  132. Cython/Includes/cpython/mapping.pxd +63 -0
  133. Cython/Includes/cpython/marshal.pxd +66 -0
  134. Cython/Includes/cpython/mem.pxd +120 -0
  135. Cython/Includes/cpython/memoryview.pxd +50 -0
  136. Cython/Includes/cpython/method.pxd +49 -0
  137. Cython/Includes/cpython/module.pxd +208 -0
  138. Cython/Includes/cpython/number.pxd +258 -0
  139. Cython/Includes/cpython/object.pxd +433 -0
  140. Cython/Includes/cpython/pycapsule.pxd +143 -0
  141. Cython/Includes/cpython/pylifecycle.pxd +68 -0
  142. Cython/Includes/cpython/pyport.pxd +8 -0
  143. Cython/Includes/cpython/pystate.pxd +95 -0
  144. Cython/Includes/cpython/pythread.pxd +53 -0
  145. Cython/Includes/cpython/ref.pxd +67 -0
  146. Cython/Includes/cpython/sequence.pxd +134 -0
  147. Cython/Includes/cpython/set.pxd +119 -0
  148. Cython/Includes/cpython/slice.pxd +70 -0
  149. Cython/Includes/cpython/time.pxd +129 -0
  150. Cython/Includes/cpython/tuple.pxd +72 -0
  151. Cython/Includes/cpython/type.pxd +53 -0
  152. Cython/Includes/cpython/unicode.pxd +639 -0
  153. Cython/Includes/cpython/version.pxd +32 -0
  154. Cython/Includes/cpython/weakref.pxd +78 -0
  155. Cython/Includes/libc/__init__.pxd +1 -0
  156. Cython/Includes/libc/complex.pxd +35 -0
  157. Cython/Includes/libc/errno.pxd +127 -0
  158. Cython/Includes/libc/float.pxd +43 -0
  159. Cython/Includes/libc/limits.pxd +28 -0
  160. Cython/Includes/libc/locale.pxd +46 -0
  161. Cython/Includes/libc/math.pxd +209 -0
  162. Cython/Includes/libc/setjmp.pxd +10 -0
  163. Cython/Includes/libc/signal.pxd +64 -0
  164. Cython/Includes/libc/stddef.pxd +9 -0
  165. Cython/Includes/libc/stdint.pxd +105 -0
  166. Cython/Includes/libc/stdio.pxd +80 -0
  167. Cython/Includes/libc/stdlib.pxd +72 -0
  168. Cython/Includes/libc/string.pxd +50 -0
  169. Cython/Includes/libc/threads.pxd +84 -0
  170. Cython/Includes/libc/time.pxd +51 -0
  171. Cython/Includes/libcpp/__init__.pxd +4 -0
  172. Cython/Includes/libcpp/algorithm.pxd +320 -0
  173. Cython/Includes/libcpp/any.pxd +16 -0
  174. Cython/Includes/libcpp/atomic.pxd +59 -0
  175. Cython/Includes/libcpp/barrier.pxd +22 -0
  176. Cython/Includes/libcpp/bit.pxd +29 -0
  177. Cython/Includes/libcpp/cast.pxd +12 -0
  178. Cython/Includes/libcpp/cmath.pxd +518 -0
  179. Cython/Includes/libcpp/complex.pxd +106 -0
  180. Cython/Includes/libcpp/deque.pxd +165 -0
  181. Cython/Includes/libcpp/exception.pxd +86 -0
  182. Cython/Includes/libcpp/execution.pxd +15 -0
  183. Cython/Includes/libcpp/forward_list.pxd +63 -0
  184. Cython/Includes/libcpp/functional.pxd +26 -0
  185. Cython/Includes/libcpp/future.pxd +103 -0
  186. Cython/Includes/libcpp/iterator.pxd +34 -0
  187. Cython/Includes/libcpp/latch.pxd +17 -0
  188. Cython/Includes/libcpp/limits.pxd +61 -0
  189. Cython/Includes/libcpp/list.pxd +117 -0
  190. Cython/Includes/libcpp/map.pxd +252 -0
  191. Cython/Includes/libcpp/memory.pxd +115 -0
  192. Cython/Includes/libcpp/mutex.pxd +130 -0
  193. Cython/Includes/libcpp/numbers.pxd +15 -0
  194. Cython/Includes/libcpp/numeric.pxd +131 -0
  195. Cython/Includes/libcpp/optional.pxd +34 -0
  196. Cython/Includes/libcpp/pair.pxd +1 -0
  197. Cython/Includes/libcpp/queue.pxd +25 -0
  198. Cython/Includes/libcpp/random.pxd +166 -0
  199. Cython/Includes/libcpp/semaphore.pxd +44 -0
  200. Cython/Includes/libcpp/set.pxd +228 -0
  201. Cython/Includes/libcpp/shared_mutex.pxd +72 -0
  202. Cython/Includes/libcpp/span.pxd +87 -0
  203. Cython/Includes/libcpp/stack.pxd +11 -0
  204. Cython/Includes/libcpp/stop_token.pxd +105 -0
  205. Cython/Includes/libcpp/string.pxd +355 -0
  206. Cython/Includes/libcpp/string_view.pxd +181 -0
  207. Cython/Includes/libcpp/typeindex.pxd +15 -0
  208. Cython/Includes/libcpp/typeinfo.pxd +10 -0
  209. Cython/Includes/libcpp/unordered_map.pxd +193 -0
  210. Cython/Includes/libcpp/unordered_set.pxd +152 -0
  211. Cython/Includes/libcpp/utility.pxd +30 -0
  212. Cython/Includes/libcpp/vector.pxd +186 -0
  213. Cython/Includes/openmp.pxd +50 -0
  214. Cython/Includes/posix/__init__.pxd +1 -0
  215. Cython/Includes/posix/dlfcn.pxd +14 -0
  216. Cython/Includes/posix/fcntl.pxd +86 -0
  217. Cython/Includes/posix/ioctl.pxd +4 -0
  218. Cython/Includes/posix/mman.pxd +101 -0
  219. Cython/Includes/posix/resource.pxd +57 -0
  220. Cython/Includes/posix/select.pxd +21 -0
  221. Cython/Includes/posix/signal.pxd +73 -0
  222. Cython/Includes/posix/stat.pxd +98 -0
  223. Cython/Includes/posix/stdio.pxd +37 -0
  224. Cython/Includes/posix/stdlib.pxd +29 -0
  225. Cython/Includes/posix/strings.pxd +9 -0
  226. Cython/Includes/posix/time.pxd +71 -0
  227. Cython/Includes/posix/types.pxd +30 -0
  228. Cython/Includes/posix/uio.pxd +26 -0
  229. Cython/Includes/posix/unistd.pxd +271 -0
  230. Cython/Includes/posix/wait.pxd +38 -0
  231. Cython/Plex/Actions.pxd +24 -0
  232. Cython/Plex/Actions.py +119 -0
  233. Cython/Plex/DFA.pxd +14 -0
  234. Cython/Plex/DFA.py +164 -0
  235. Cython/Plex/Errors.py +48 -0
  236. Cython/Plex/Lexicons.py +178 -0
  237. Cython/Plex/Machines.pxd +36 -0
  238. Cython/Plex/Machines.py +238 -0
  239. Cython/Plex/Regexps.py +539 -0
  240. Cython/Plex/Scanners.pxd +47 -0
  241. Cython/Plex/Scanners.py +360 -0
  242. Cython/Plex/Transitions.pxd +14 -0
  243. Cython/Plex/Transitions.py +239 -0
  244. Cython/Plex/__init__.py +34 -0
  245. Cython/Runtime/__init__.py +1 -0
  246. Cython/Runtime/refnanny.pyx +237 -0
  247. Cython/Shadow.py +690 -0
  248. Cython/Shadow.pyi +521 -0
  249. Cython/StringIOTree.py +170 -0
  250. Cython/Tempita/__init__.py +4 -0
  251. Cython/Tempita/_looper.py +154 -0
  252. Cython/Tempita/_tempita.py +1091 -0
  253. Cython/TestUtils.py +410 -0
  254. Cython/Tests/TestCodeWriter.py +128 -0
  255. Cython/Tests/TestCythonUtils.py +202 -0
  256. Cython/Tests/TestJediTyper.py +223 -0
  257. Cython/Tests/TestShadow.py +114 -0
  258. Cython/Tests/TestStringIOTree.py +67 -0
  259. Cython/Tests/TestTestUtils.py +90 -0
  260. Cython/Tests/__init__.py +1 -0
  261. Cython/Tests/xmlrunner.py +390 -0
  262. Cython/Utility/AsyncGen.c +1002 -0
  263. Cython/Utility/Buffer.c +875 -0
  264. Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
  265. Cython/Utility/Builtins.c +776 -0
  266. Cython/Utility/CConvert.pyx +134 -0
  267. Cython/Utility/CMath.c +104 -0
  268. Cython/Utility/CommonStructures.c +118 -0
  269. Cython/Utility/Complex.c +378 -0
  270. Cython/Utility/Coroutine.c +2206 -0
  271. Cython/Utility/CpdefEnums.pyx +103 -0
  272. Cython/Utility/CppConvert.pyx +279 -0
  273. Cython/Utility/CppSupport.cpp +143 -0
  274. Cython/Utility/CythonFunction.c +1794 -0
  275. Cython/Utility/Dataclasses.c +185 -0
  276. Cython/Utility/Dataclasses.py +112 -0
  277. Cython/Utility/Embed.c +125 -0
  278. Cython/Utility/Exceptions.c +1012 -0
  279. Cython/Utility/ExtensionTypes.c +809 -0
  280. Cython/Utility/FunctionArguments.c +965 -0
  281. Cython/Utility/ImportExport.c +987 -0
  282. Cython/Utility/Lock.c +136 -0
  283. Cython/Utility/MemoryView.pxd +187 -0
  284. Cython/Utility/MemoryView.pyx +1481 -0
  285. Cython/Utility/MemoryView_C.c +1046 -0
  286. Cython/Utility/ModuleSetupCode.c +3059 -0
  287. Cython/Utility/NumpyImportArray.c +46 -0
  288. Cython/Utility/ObjectHandling.c +3342 -0
  289. Cython/Utility/Optimize.c +1589 -0
  290. Cython/Utility/Overflow.c +404 -0
  291. Cython/Utility/Printing.c +86 -0
  292. Cython/Utility/Profile.c +709 -0
  293. Cython/Utility/StringTools.c +1259 -0
  294. Cython/Utility/TestCyUtilityLoader.pyx +8 -0
  295. Cython/Utility/TestCythonScope.pyx +75 -0
  296. Cython/Utility/TestUtilityLoader.c +12 -0
  297. Cython/Utility/TypeConversion.c +1284 -0
  298. Cython/Utility/UFuncs.pyx +50 -0
  299. Cython/Utility/UFuncs_C.c +89 -0
  300. Cython/Utility/__init__.py +28 -0
  301. Cython/Utility/arrayarray.h +148 -0
  302. Cython/Utils.py +687 -0
  303. Cython/__init__.py +10 -0
  304. Cython/__init__.pyi +7 -0
  305. Cython/py.typed +0 -0
  306. cython-3.1.0.dist-info/COPYING.txt +19 -0
  307. cython-3.1.0.dist-info/LICENSE.txt +176 -0
  308. cython-3.1.0.dist-info/METADATA +636 -0
  309. cython-3.1.0.dist-info/RECORD +316 -0
  310. cython-3.1.0.dist-info/WHEEL +5 -0
  311. cython-3.1.0.dist-info/entry_points.txt +4 -0
  312. cython-3.1.0.dist-info/top_level.txt +3 -0
  313. cython.py +29 -0
  314. pyximport/__init__.py +4 -0
  315. pyximport/pyxbuild.py +160 -0
  316. 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'])