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