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
Binary file
Cython/TestUtils.py ADDED
@@ -0,0 +1,422 @@
1
+ import os
2
+ import re
3
+ import unittest
4
+ import shlex
5
+ import sys
6
+ import tempfile
7
+ import textwrap
8
+ from functools import partial
9
+
10
+ from .Compiler import Errors
11
+ from .CodeWriter import CodeWriter
12
+ from .Compiler.TreeFragment import TreeFragment, strip_common_indent, StringParseContext
13
+ from .Compiler.Visitor import TreeVisitor, VisitorTransform
14
+ from .Compiler import TreePath
15
+ from .Compiler.ParseTreeTransforms import PostParse
16
+
17
+
18
+ class NodeTypeWriter(TreeVisitor):
19
+ def __init__(self):
20
+ super().__init__()
21
+ self._indents = 0
22
+ self.result = []
23
+
24
+ def visit_Node(self, node):
25
+ if not self.access_path:
26
+ name = "(root)"
27
+ else:
28
+ tip = self.access_path[-1]
29
+ if tip[2] is not None:
30
+ name = "%s[%d]" % tip[1:3]
31
+ else:
32
+ name = tip[1]
33
+
34
+ self.result.append(" " * self._indents +
35
+ "%s: %s" % (name, node.__class__.__name__))
36
+ self._indents += 1
37
+ self.visitchildren(node)
38
+ self._indents -= 1
39
+
40
+
41
+ def treetypes(root):
42
+ """Returns a string representing the tree by class names.
43
+ There's a leading and trailing whitespace so that it can be
44
+ compared by simple string comparison while still making test
45
+ cases look ok."""
46
+ w = NodeTypeWriter()
47
+ w.visit(root)
48
+ return "\n".join([""] + w.result + [""])
49
+
50
+
51
+ class CythonTest(unittest.TestCase):
52
+
53
+ def setUp(self):
54
+ Errors.init_thread()
55
+
56
+ def tearDown(self):
57
+ Errors.init_thread()
58
+
59
+ def assertLines(self, expected, result):
60
+ "Checks that the given strings or lists of strings are equal line by line"
61
+ if not isinstance(expected, list):
62
+ expected = expected.split("\n")
63
+ if not isinstance(result, list):
64
+ result = result.split("\n")
65
+ for idx, (expected_line, result_line) in enumerate(zip(expected, result)):
66
+ self.assertEqual(expected_line, result_line,
67
+ "Line %d:\nExp: %s\nGot: %s" % (idx, expected_line, result_line))
68
+ self.assertEqual(len(expected), len(result),
69
+ "Unmatched lines. Got:\n%s\nExpected:\n%s" % ("\n".join(expected), "\n".join(result)))
70
+
71
+ def codeToLines(self, tree):
72
+ writer = CodeWriter()
73
+ writer.write(tree)
74
+ return writer.result.lines
75
+
76
+ def codeToString(self, tree):
77
+ return "\n".join(self.codeToLines(tree))
78
+
79
+ def assertCode(self, expected, result_tree):
80
+ result_lines = self.codeToLines(result_tree)
81
+
82
+ expected_lines = strip_common_indent(expected.split("\n"))
83
+
84
+ for idx, (line, expected_line) in enumerate(zip(result_lines, expected_lines)):
85
+ self.assertEqual(expected_line, line,
86
+ "Line %d:\nGot: %s\nExp: %s" % (idx, line, expected_line))
87
+ self.assertEqual(len(result_lines), len(expected_lines),
88
+ "Unmatched lines. Got:\n%s\nExpected:\n%s" % ("\n".join(result_lines), expected))
89
+
90
+ def assertNodeExists(self, path, result_tree):
91
+ self.assertNotEqual(TreePath.find_first(result_tree, path), None,
92
+ "Path '%s' not found in result tree" % path)
93
+
94
+ def fragment(self, code, pxds=None, pipeline=None):
95
+ "Simply create a tree fragment using the name of the test-case in parse errors."
96
+ if pxds is None:
97
+ pxds = {}
98
+ if pipeline is None:
99
+ pipeline = []
100
+ name = self.id()
101
+ if name.startswith("__main__."):
102
+ name = name[len("__main__."):]
103
+ name = name.replace(".", "_")
104
+ return TreeFragment(code, name, pxds, pipeline=pipeline)
105
+
106
+ def treetypes(self, root):
107
+ return treetypes(root)
108
+
109
+ def should_fail(self, func, exc_type=Exception):
110
+ """Calls "func" and fails if it doesn't raise the right exception
111
+ (any exception by default). Also returns the exception in question.
112
+ """
113
+ try:
114
+ func()
115
+ self.fail("Expected an exception of type %r" % exc_type)
116
+ except exc_type as e:
117
+ self.assertTrue(isinstance(e, exc_type))
118
+ return e
119
+
120
+ def should_not_fail(self, func):
121
+ """Calls func and succeeds if and only if no exception is raised
122
+ (i.e. converts exception raising into a failed testcase). Returns
123
+ the return value of func."""
124
+ try:
125
+ return func()
126
+ except Exception as exc:
127
+ self.fail(str(exc))
128
+
129
+
130
+ class TransformTest(CythonTest):
131
+ """
132
+ Utility base class for transform unit tests. It is based around constructing
133
+ test trees (either explicitly or by parsing a Cython code string); running
134
+ the transform, serialize it using a customized Cython serializer (with
135
+ special markup for nodes that cannot be represented in Cython),
136
+ and do a string-comparison line-by-line of the result.
137
+
138
+ To create a test case:
139
+ - Call run_pipeline. The pipeline should at least contain the transform you
140
+ are testing; pyx should be either a string (passed to the parser to
141
+ create a post-parse tree) or a node representing input to pipeline.
142
+ The result will be a transformed result.
143
+
144
+ - Check that the tree is correct. If wanted, assertCode can be used, which
145
+ takes a code string as expected, and a ModuleNode in result_tree
146
+ (it serializes the ModuleNode to a string and compares line-by-line).
147
+
148
+ All code strings are first stripped for whitespace lines and then common
149
+ indentation.
150
+
151
+ Plans: One could have a pxd dictionary parameter to run_pipeline.
152
+ """
153
+
154
+ def run_pipeline(self, pipeline, pyx, pxds=None):
155
+ if pxds is None:
156
+ pxds = {}
157
+ tree = self.fragment(pyx, pxds).root
158
+ # Run pipeline
159
+ for T in pipeline:
160
+ tree = T(tree)
161
+ return tree
162
+
163
+
164
+ # For the test C code validation, we have to take care that the test directives (and thus
165
+ # the match strings) do not just appear in (multiline) C code comments containing the original
166
+ # Cython source code. Thus, we discard the comments before matching.
167
+ # This seems a prime case for re.VERBOSE, but it seems to match some of the whitespace.
168
+ _strip_c_comments = partial(re.compile(
169
+ re.sub(r'\s+', '', r'''
170
+ /[*] (
171
+ (?: [^*\n] | [*][^/] )*
172
+ [\n]
173
+ (?: [^*] | [*][^/] )*
174
+ ) [*]/
175
+ ''')
176
+ ).sub, '')
177
+
178
+ _strip_cython_code_from_html = partial(re.compile(
179
+ re.sub(r'\s\s+', '', r'''
180
+ (?:
181
+ <pre class=["'][^"']*cython\s+line[^"']*["']\s*>
182
+ (?:[^<]|<(?!/pre))+
183
+ </pre>
184
+ )|(?:
185
+ <style[^>]*>
186
+ (?:[^<]|<(?!/style))+
187
+ </style>
188
+ )
189
+ ''')
190
+ ).sub, '')
191
+
192
+
193
+ def _parse_pattern(pattern):
194
+ start = end = None
195
+ if pattern.startswith('/'):
196
+ start, pattern = re.split(r"(?<!\\)/", pattern[1:], maxsplit=1)
197
+ pattern = pattern.strip()
198
+ if pattern.startswith(':'):
199
+ pattern = pattern[1:].strip()
200
+ if pattern.startswith("/"):
201
+ end, pattern = re.split(r"(?<!\\)/", pattern[1:], maxsplit=1)
202
+ pattern = pattern.strip()
203
+ return start, end, pattern
204
+
205
+
206
+ class TreeAssertVisitor(VisitorTransform):
207
+ # actually, a TreeVisitor would be enough, but this needs to run
208
+ # as part of the compiler pipeline
209
+
210
+ def __init__(self):
211
+ super().__init__()
212
+ self._module_pos = None
213
+ self._c_patterns = []
214
+ self._c_antipatterns = []
215
+
216
+ def create_c_file_validator(self):
217
+ patterns, antipatterns = self._c_patterns, self._c_antipatterns
218
+
219
+ def fail(pos, pattern, found, file_path):
220
+ Errors.error(pos, "Pattern '%s' %s found in %s" %(
221
+ pattern,
222
+ 'was' if found else 'was not',
223
+ file_path,
224
+ ))
225
+
226
+ def extract_section(file_path, content, start, end):
227
+ if start:
228
+ split = re.search(start, content)
229
+ if split:
230
+ content = content[split.end():]
231
+ else:
232
+ fail(self._module_pos, start, found=False, file_path=file_path)
233
+ if end:
234
+ split = re.search(end, content)
235
+ if split:
236
+ content = content[:split.start()]
237
+ else:
238
+ fail(self._module_pos, end, found=False, file_path=file_path)
239
+ return content
240
+
241
+ def validate_file_content(file_path, content):
242
+ for pattern in patterns:
243
+ #print("Searching pattern '%s'" % pattern)
244
+ start, end, pattern = _parse_pattern(pattern)
245
+ section = extract_section(file_path, content, start, end)
246
+ if not re.search(pattern, section):
247
+ fail(self._module_pos, pattern, found=False, file_path=file_path)
248
+
249
+ for antipattern in antipatterns:
250
+ #print("Searching antipattern '%s'" % antipattern)
251
+ start, end, antipattern = _parse_pattern(antipattern)
252
+ section = extract_section(file_path, content, start, end)
253
+ if re.search(antipattern, section):
254
+ fail(self._module_pos, antipattern, found=True, file_path=file_path)
255
+
256
+ def validate_c_file(result):
257
+ c_file = result.c_file
258
+ if not (patterns or antipatterns):
259
+ #print("No patterns defined for %s" % c_file)
260
+ return result
261
+
262
+ with open(c_file, encoding='utf8') as f:
263
+ content = f.read()
264
+ content = _strip_c_comments(content)
265
+ validate_file_content(c_file, content)
266
+
267
+ return validate_c_file
268
+
269
+ def _check_directives(self, node):
270
+ directives = node.directives
271
+ if 'test_assert_path_exists' in directives:
272
+ for path in directives['test_assert_path_exists']:
273
+ if TreePath.find_first(node, path) is None:
274
+ Errors.error(
275
+ node.pos,
276
+ "Expected path '%s' not found in result tree" % path)
277
+ if 'test_fail_if_path_exists' in directives:
278
+ for path in directives['test_fail_if_path_exists']:
279
+ first_node = TreePath.find_first(node, path)
280
+ if first_node is not None:
281
+ Errors.error(
282
+ first_node.pos,
283
+ "Unexpected path '%s' found in result tree" % path)
284
+ if 'test_assert_c_code_has' in directives:
285
+ self._c_patterns.extend(directives['test_assert_c_code_has'])
286
+ if 'test_fail_if_c_code_has' in directives:
287
+ self._c_antipatterns.extend(directives['test_fail_if_c_code_has'])
288
+ if 'test_body_needs_exception_handling' in directives:
289
+ value = directives['test_body_needs_exception_handling']
290
+ if value is not None:
291
+ from .Compiler.ParseTreeTransforms import HasNoExceptionHandlingVisitor
292
+ visitor = HasNoExceptionHandlingVisitor()
293
+ result = not visitor(node.body)
294
+ if value != result:
295
+ visitor(node.body)
296
+ Errors.error(
297
+ node.pos,
298
+ "Node had unexpected exception handling value"
299
+ )
300
+
301
+ def visit_ModuleNode(self, node):
302
+ self._module_pos = node.pos
303
+ self._check_directives(node)
304
+ self.visitchildren(node)
305
+ return node
306
+
307
+ def visit_CompilerDirectivesNode(self, node):
308
+ self._check_directives(node)
309
+ self.visitchildren(node)
310
+ return node
311
+
312
+ visit_Node = VisitorTransform.recurse_to_children
313
+
314
+
315
+ def unpack_source_tree(tree_file, workdir, cython_root):
316
+ programs = {
317
+ 'PYTHON': [sys.executable],
318
+ 'CYTHON': [sys.executable, os.path.join(cython_root, 'cython.py')],
319
+ 'CYTHONIZE': [sys.executable, os.path.join(cython_root, 'cythonize.py')]
320
+ }
321
+
322
+ if workdir is None:
323
+ workdir = tempfile.mkdtemp()
324
+ header, cur_file = [], None
325
+ with open(tree_file, 'rb') as f:
326
+ try:
327
+ for line in f:
328
+ if line[:5] == b'#####':
329
+ filename = line.strip().strip(b'#').strip().decode('utf8').replace('/', os.path.sep)
330
+ path = os.path.join(workdir, filename)
331
+ if not os.path.exists(os.path.dirname(path)):
332
+ os.makedirs(os.path.dirname(path))
333
+ if cur_file is not None:
334
+ to_close, cur_file = cur_file, None
335
+ to_close.close()
336
+ cur_file = open(path, 'wb')
337
+ elif cur_file is not None:
338
+ cur_file.write(line)
339
+ elif line.strip() and not line.lstrip().startswith(b'#'):
340
+ if line.strip() not in (b'"""', b"'''"):
341
+ command = shlex.split(line.decode('utf8'))
342
+ if not command: continue
343
+ # In Python 3: prog, *args = command
344
+ prog, args = command[0], command[1:]
345
+ try:
346
+ header.append(programs[prog]+args)
347
+ except KeyError:
348
+ header.append(command)
349
+ finally:
350
+ if cur_file is not None:
351
+ cur_file.close()
352
+ return workdir, header
353
+
354
+
355
+ def write_file(file_path, content, dedent=False, encoding=None):
356
+ r"""Write some content (text or bytes) to the file
357
+ at `file_path` without translating `'\n'` into `os.linesep`.
358
+
359
+ The default encoding is `'utf-8'`.
360
+ """
361
+ if isinstance(content, bytes):
362
+ mode = "wb"
363
+
364
+ # binary mode doesn't take an encoding and newline arguments
365
+ newline = None
366
+ default_encoding = None
367
+ else:
368
+ mode = "w"
369
+
370
+ # any "\n" characters written are not translated
371
+ # to the system default line separator, os.linesep
372
+ newline = "\n"
373
+ default_encoding = "utf-8"
374
+
375
+ if encoding is None:
376
+ encoding = default_encoding
377
+
378
+ if dedent:
379
+ content = textwrap.dedent(content)
380
+
381
+ with open(file_path, mode=mode, encoding=encoding, newline=newline) as f:
382
+ f.write(content)
383
+
384
+
385
+ def write_newer_file(file_path, newer_than, content, dedent=False, encoding=None):
386
+ r"""
387
+ Write `content` to the file `file_path` without translating `'\n'`
388
+ into `os.linesep` and make sure it is newer than the file `newer_than`.
389
+
390
+ The default encoding is `'utf-8'` (same as for `write_file`).
391
+ """
392
+ write_file(file_path, content, dedent=dedent, encoding=encoding)
393
+
394
+ try:
395
+ other_time = os.path.getmtime(newer_than)
396
+ except OSError:
397
+ # Support writing a fresh file (which is always newer than a non-existent one)
398
+ other_time = None
399
+
400
+ while other_time is None or other_time >= os.path.getmtime(file_path):
401
+ write_file(file_path, content, dedent=dedent, encoding=encoding)
402
+
403
+
404
+ def py_parse_code(code):
405
+ """
406
+ Compiles code far enough to get errors from the parser and post-parse stage.
407
+
408
+ Is useful for checking for syntax errors, however it doesn't generate runable
409
+ code.
410
+ """
411
+ context = StringParseContext("test")
412
+ # all the errors we care about are in the parsing or postparse stage
413
+ try:
414
+ with Errors.local_errors() as errors:
415
+ result = TreeFragment(code, pipeline=[PostParse(context)])
416
+ result = result.substitute()
417
+ if errors:
418
+ raise errors[0] # compile error, which should get caught below
419
+ else:
420
+ return result
421
+ except Errors.CompileError as e:
422
+ raise SyntaxError(e.message_only)
@@ -0,0 +1,128 @@
1
+ from Cython.TestUtils import CythonTest
2
+
3
+ class TestCodeWriter(CythonTest):
4
+ # CythonTest uses the CodeWriter heavily, so do some checking by
5
+ # roundtripping Cython code through the test framework.
6
+
7
+ # Note that this test is dependent upon the normal Cython parser
8
+ # to generate the input trees to the CodeWriter. This save *a lot*
9
+ # of time; better to spend that time writing other tests than perfecting
10
+ # this one...
11
+
12
+ # Whitespace is very significant in this process:
13
+ # - always newline on new block (!)
14
+ # - indent 4 spaces
15
+ # - 1 space around every operator
16
+
17
+ def t(self, codestr):
18
+ self.assertCode(codestr, self.fragment(codestr).root)
19
+
20
+ def test_print(self):
21
+ self.t("""
22
+ print(x + y ** 2)
23
+ print(x, y, z)
24
+ print(x + y, x + y * z, x * (y + z))
25
+ """)
26
+
27
+ def test_if(self):
28
+ self.t("if x:\n pass")
29
+
30
+ def test_ifelifelse(self):
31
+ self.t("""
32
+ if x:
33
+ pass
34
+ elif y:
35
+ pass
36
+ elif z + 34 ** 34 - 2:
37
+ pass
38
+ else:
39
+ pass
40
+ """)
41
+
42
+ def test_def(self):
43
+ self.t("""
44
+ def f(x, y, z):
45
+ pass
46
+ def f(x = 34, y = 54, z):
47
+ pass
48
+ """)
49
+
50
+ def test_cdef(self):
51
+ self.t("""
52
+ cdef f(x, y, z):
53
+ pass
54
+ cdef public void (x = 34, y = 54, z):
55
+ pass
56
+ cdef f(int *x, void *y, Value *z):
57
+ pass
58
+ cdef f(int **x, void **y, Value **z):
59
+ pass
60
+ cdef inline f(int &x, Value &z):
61
+ pass
62
+ """)
63
+
64
+ def test_longness_and_signedness(self):
65
+ self.t("def f(unsigned long long long long long int y):\n pass")
66
+
67
+ def test_signed_short(self):
68
+ self.t("def f(signed short int y):\n pass")
69
+
70
+ def test_typed_args(self):
71
+ self.t("def f(int x, unsigned long int y):\n pass")
72
+
73
+ def test_cdef_var(self):
74
+ self.t("""
75
+ cdef int hello
76
+ cdef int hello = 4, x = 3, y, z
77
+ """)
78
+
79
+ def test_for_loop(self):
80
+ self.t("""
81
+ for x, y, z in f(g(h(34) * 2) + 23):
82
+ print(x, y, z)
83
+ else:
84
+ print(43)
85
+ """)
86
+ self.t("""
87
+ for abc in (1, 2, 3):
88
+ print(x, y, z)
89
+ else:
90
+ print(43)
91
+ """)
92
+
93
+ def test_while_loop(self):
94
+ self.t("""
95
+ while True:
96
+ while True:
97
+ while True:
98
+ continue
99
+ """)
100
+
101
+ def test_inplace_assignment(self):
102
+ self.t("x += 43")
103
+
104
+ def test_cascaded_assignment(self):
105
+ self.t("x = y = z = abc = 43")
106
+
107
+ def test_attribute(self):
108
+ self.t("a.x")
109
+
110
+ def test_return_none(self):
111
+ self.t("""
112
+ def f(x, y, z):
113
+ return
114
+ cdef f(x, y, z):
115
+ return
116
+ def f(x, y, z):
117
+ return None
118
+ cdef f(x, y, z):
119
+ return None
120
+ def f(x, y, z):
121
+ return 1234
122
+ cdef f(x, y, z):
123
+ return 1234
124
+ """)
125
+
126
+ if __name__ == "__main__":
127
+ import unittest
128
+ unittest.main()