Cython 3.1.0a1__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 (301) hide show
  1. Cython/Build/BuildExecutable.py +169 -0
  2. Cython/Build/Cache.py +199 -0
  3. Cython/Build/Cythonize.py +250 -0
  4. Cython/Build/Dependencies.py +1275 -0
  5. Cython/Build/Distutils.py +1 -0
  6. Cython/Build/Inline.py +342 -0
  7. Cython/Build/IpythonMagic.py +560 -0
  8. Cython/Build/Tests/TestCyCache.py +119 -0
  9. Cython/Build/Tests/TestCythonizeArgsParser.py +481 -0
  10. Cython/Build/Tests/TestDependencies.py +133 -0
  11. Cython/Build/Tests/TestInline.py +112 -0
  12. Cython/Build/Tests/TestIpythonMagic.py +287 -0
  13. Cython/Build/Tests/TestRecythonize.py +212 -0
  14. Cython/Build/Tests/TestStripLiterals.py +155 -0
  15. Cython/Build/Tests/__init__.py +1 -0
  16. Cython/Build/__init__.py +8 -0
  17. Cython/CodeWriter.py +811 -0
  18. Cython/Compiler/AnalysedTreeTransforms.py +97 -0
  19. Cython/Compiler/Annotate.py +326 -0
  20. Cython/Compiler/AutoDocTransforms.py +314 -0
  21. Cython/Compiler/Buffer.py +680 -0
  22. Cython/Compiler/Builtin.py +862 -0
  23. Cython/Compiler/CmdLine.py +243 -0
  24. Cython/Compiler/Code.pxd +145 -0
  25. Cython/Compiler/Code.py +3328 -0
  26. Cython/Compiler/CodeGeneration.py +33 -0
  27. Cython/Compiler/CythonScope.py +179 -0
  28. Cython/Compiler/Dataclass.py +868 -0
  29. Cython/Compiler/DebugFlags.py +21 -0
  30. Cython/Compiler/Errors.py +295 -0
  31. Cython/Compiler/ExprNodes.py +15051 -0
  32. Cython/Compiler/FlowControl.pxd +97 -0
  33. Cython/Compiler/FlowControl.py +1438 -0
  34. Cython/Compiler/FusedNode.py +998 -0
  35. Cython/Compiler/Future.py +16 -0
  36. Cython/Compiler/Interpreter.py +57 -0
  37. Cython/Compiler/Lexicon.py +340 -0
  38. Cython/Compiler/LineTable.py +114 -0
  39. Cython/Compiler/Main.py +779 -0
  40. Cython/Compiler/MatchCaseNodes.py +259 -0
  41. Cython/Compiler/MemoryView.py +860 -0
  42. Cython/Compiler/ModuleNode.py +4065 -0
  43. Cython/Compiler/Naming.py +369 -0
  44. Cython/Compiler/Nodes.py +10557 -0
  45. Cython/Compiler/Optimize.py +5269 -0
  46. Cython/Compiler/Options.py +828 -0
  47. Cython/Compiler/ParseTreeTransforms.pxd +78 -0
  48. Cython/Compiler/ParseTreeTransforms.py +4441 -0
  49. Cython/Compiler/Parsing.pxd +9 -0
  50. Cython/Compiler/Parsing.py +4797 -0
  51. Cython/Compiler/Pipeline.py +425 -0
  52. Cython/Compiler/PyrexTypes.py +5572 -0
  53. Cython/Compiler/Pythran.py +223 -0
  54. Cython/Compiler/Scanning.pxd +40 -0
  55. Cython/Compiler/Scanning.py +574 -0
  56. Cython/Compiler/StringEncoding.py +347 -0
  57. Cython/Compiler/Symtab.py +2998 -0
  58. Cython/Compiler/Tests/TestBuffer.py +105 -0
  59. Cython/Compiler/Tests/TestBuiltin.py +72 -0
  60. Cython/Compiler/Tests/TestCmdLine.py +573 -0
  61. Cython/Compiler/Tests/TestCode.py +86 -0
  62. Cython/Compiler/Tests/TestFlowControl.py +65 -0
  63. Cython/Compiler/Tests/TestGrammar.py +202 -0
  64. Cython/Compiler/Tests/TestMemView.py +71 -0
  65. Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
  66. Cython/Compiler/Tests/TestScanning.py +134 -0
  67. Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
  68. Cython/Compiler/Tests/TestStringEncoding.py +33 -0
  69. Cython/Compiler/Tests/TestTreeFragment.py +63 -0
  70. Cython/Compiler/Tests/TestTreePath.py +93 -0
  71. Cython/Compiler/Tests/TestTypes.py +75 -0
  72. Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
  73. Cython/Compiler/Tests/TestVisitor.py +61 -0
  74. Cython/Compiler/Tests/Utils.py +36 -0
  75. Cython/Compiler/Tests/__init__.py +1 -0
  76. Cython/Compiler/TreeFragment.py +278 -0
  77. Cython/Compiler/TreePath.py +290 -0
  78. Cython/Compiler/TypeInference.py +584 -0
  79. Cython/Compiler/TypeSlots.py +1181 -0
  80. Cython/Compiler/UFuncs.py +311 -0
  81. Cython/Compiler/UtilNodes.py +387 -0
  82. Cython/Compiler/UtilityCode.py +274 -0
  83. Cython/Compiler/Version.py +8 -0
  84. Cython/Compiler/Visitor.pxd +53 -0
  85. Cython/Compiler/Visitor.py +861 -0
  86. Cython/Compiler/__init__.py +1 -0
  87. Cython/Coverage.py +443 -0
  88. Cython/Debugger/Cygdb.py +179 -0
  89. Cython/Debugger/DebugWriter.py +82 -0
  90. Cython/Debugger/Tests/TestLibCython.py +275 -0
  91. Cython/Debugger/Tests/__init__.py +1 -0
  92. Cython/Debugger/Tests/cfuncs.c +8 -0
  93. Cython/Debugger/Tests/codefile +49 -0
  94. Cython/Debugger/Tests/test_libcython_in_gdb.py +578 -0
  95. Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
  96. Cython/Debugger/__init__.py +1 -0
  97. Cython/Debugger/libcython.py +1549 -0
  98. Cython/Debugger/libpython.py +2821 -0
  99. Cython/Debugging.py +20 -0
  100. Cython/Distutils/__init__.py +2 -0
  101. Cython/Distutils/build_ext.py +137 -0
  102. Cython/Distutils/extension.py +96 -0
  103. Cython/Distutils/old_build_ext.py +351 -0
  104. Cython/Includes/cpython/__init__.pxd +173 -0
  105. Cython/Includes/cpython/array.pxd +174 -0
  106. Cython/Includes/cpython/bool.pxd +37 -0
  107. Cython/Includes/cpython/buffer.pxd +112 -0
  108. Cython/Includes/cpython/bytearray.pxd +33 -0
  109. Cython/Includes/cpython/bytes.pxd +200 -0
  110. Cython/Includes/cpython/cellobject.pxd +35 -0
  111. Cython/Includes/cpython/ceval.pxd +8 -0
  112. Cython/Includes/cpython/codecs.pxd +121 -0
  113. Cython/Includes/cpython/complex.pxd +55 -0
  114. Cython/Includes/cpython/contextvars.pxd +141 -0
  115. Cython/Includes/cpython/conversion.pxd +36 -0
  116. Cython/Includes/cpython/datetime.pxd +384 -0
  117. Cython/Includes/cpython/descr.pxd +26 -0
  118. Cython/Includes/cpython/dict.pxd +187 -0
  119. Cython/Includes/cpython/exc.pxd +263 -0
  120. Cython/Includes/cpython/fileobject.pxd +57 -0
  121. Cython/Includes/cpython/float.pxd +47 -0
  122. Cython/Includes/cpython/function.pxd +65 -0
  123. Cython/Includes/cpython/genobject.pxd +25 -0
  124. Cython/Includes/cpython/getargs.pxd +12 -0
  125. Cython/Includes/cpython/instance.pxd +25 -0
  126. Cython/Includes/cpython/iterator.pxd +36 -0
  127. Cython/Includes/cpython/iterobject.pxd +24 -0
  128. Cython/Includes/cpython/list.pxd +92 -0
  129. Cython/Includes/cpython/long.pxd +149 -0
  130. Cython/Includes/cpython/longintrepr.pxd +19 -0
  131. Cython/Includes/cpython/mapping.pxd +63 -0
  132. Cython/Includes/cpython/marshal.pxd +66 -0
  133. Cython/Includes/cpython/mem.pxd +120 -0
  134. Cython/Includes/cpython/memoryview.pxd +50 -0
  135. Cython/Includes/cpython/method.pxd +49 -0
  136. Cython/Includes/cpython/module.pxd +208 -0
  137. Cython/Includes/cpython/number.pxd +258 -0
  138. Cython/Includes/cpython/object.pxd +433 -0
  139. Cython/Includes/cpython/pycapsule.pxd +143 -0
  140. Cython/Includes/cpython/pylifecycle.pxd +68 -0
  141. Cython/Includes/cpython/pyport.pxd +8 -0
  142. Cython/Includes/cpython/pystate.pxd +95 -0
  143. Cython/Includes/cpython/pythread.pxd +53 -0
  144. Cython/Includes/cpython/ref.pxd +67 -0
  145. Cython/Includes/cpython/sequence.pxd +134 -0
  146. Cython/Includes/cpython/set.pxd +119 -0
  147. Cython/Includes/cpython/slice.pxd +70 -0
  148. Cython/Includes/cpython/time.pxd +129 -0
  149. Cython/Includes/cpython/tuple.pxd +72 -0
  150. Cython/Includes/cpython/type.pxd +53 -0
  151. Cython/Includes/cpython/unicode.pxd +639 -0
  152. Cython/Includes/cpython/version.pxd +32 -0
  153. Cython/Includes/cpython/weakref.pxd +42 -0
  154. Cython/Includes/libc/__init__.pxd +1 -0
  155. Cython/Includes/libc/complex.pxd +35 -0
  156. Cython/Includes/libc/errno.pxd +127 -0
  157. Cython/Includes/libc/float.pxd +43 -0
  158. Cython/Includes/libc/limits.pxd +28 -0
  159. Cython/Includes/libc/locale.pxd +46 -0
  160. Cython/Includes/libc/math.pxd +209 -0
  161. Cython/Includes/libc/setjmp.pxd +10 -0
  162. Cython/Includes/libc/signal.pxd +64 -0
  163. Cython/Includes/libc/stddef.pxd +9 -0
  164. Cython/Includes/libc/stdint.pxd +105 -0
  165. Cython/Includes/libc/stdio.pxd +80 -0
  166. Cython/Includes/libc/stdlib.pxd +72 -0
  167. Cython/Includes/libc/string.pxd +50 -0
  168. Cython/Includes/libc/time.pxd +47 -0
  169. Cython/Includes/libcpp/__init__.pxd +4 -0
  170. Cython/Includes/libcpp/algorithm.pxd +320 -0
  171. Cython/Includes/libcpp/any.pxd +16 -0
  172. Cython/Includes/libcpp/atomic.pxd +59 -0
  173. Cython/Includes/libcpp/bit.pxd +29 -0
  174. Cython/Includes/libcpp/cast.pxd +12 -0
  175. Cython/Includes/libcpp/cmath.pxd +518 -0
  176. Cython/Includes/libcpp/complex.pxd +106 -0
  177. Cython/Includes/libcpp/deque.pxd +165 -0
  178. Cython/Includes/libcpp/execution.pxd +15 -0
  179. Cython/Includes/libcpp/forward_list.pxd +63 -0
  180. Cython/Includes/libcpp/functional.pxd +26 -0
  181. Cython/Includes/libcpp/iterator.pxd +34 -0
  182. Cython/Includes/libcpp/limits.pxd +61 -0
  183. Cython/Includes/libcpp/list.pxd +117 -0
  184. Cython/Includes/libcpp/map.pxd +252 -0
  185. Cython/Includes/libcpp/memory.pxd +115 -0
  186. Cython/Includes/libcpp/numbers.pxd +15 -0
  187. Cython/Includes/libcpp/numeric.pxd +131 -0
  188. Cython/Includes/libcpp/optional.pxd +34 -0
  189. Cython/Includes/libcpp/pair.pxd +1 -0
  190. Cython/Includes/libcpp/queue.pxd +25 -0
  191. Cython/Includes/libcpp/random.pxd +166 -0
  192. Cython/Includes/libcpp/set.pxd +228 -0
  193. Cython/Includes/libcpp/stack.pxd +11 -0
  194. Cython/Includes/libcpp/string.pxd +333 -0
  195. Cython/Includes/libcpp/typeindex.pxd +15 -0
  196. Cython/Includes/libcpp/typeinfo.pxd +10 -0
  197. Cython/Includes/libcpp/unordered_map.pxd +193 -0
  198. Cython/Includes/libcpp/unordered_set.pxd +152 -0
  199. Cython/Includes/libcpp/utility.pxd +30 -0
  200. Cython/Includes/libcpp/vector.pxd +167 -0
  201. Cython/Includes/openmp.pxd +50 -0
  202. Cython/Includes/posix/__init__.pxd +1 -0
  203. Cython/Includes/posix/dlfcn.pxd +14 -0
  204. Cython/Includes/posix/fcntl.pxd +86 -0
  205. Cython/Includes/posix/ioctl.pxd +4 -0
  206. Cython/Includes/posix/mman.pxd +101 -0
  207. Cython/Includes/posix/resource.pxd +57 -0
  208. Cython/Includes/posix/select.pxd +21 -0
  209. Cython/Includes/posix/signal.pxd +73 -0
  210. Cython/Includes/posix/stat.pxd +98 -0
  211. Cython/Includes/posix/stdio.pxd +37 -0
  212. Cython/Includes/posix/stdlib.pxd +29 -0
  213. Cython/Includes/posix/strings.pxd +9 -0
  214. Cython/Includes/posix/time.pxd +71 -0
  215. Cython/Includes/posix/types.pxd +30 -0
  216. Cython/Includes/posix/uio.pxd +26 -0
  217. Cython/Includes/posix/unistd.pxd +271 -0
  218. Cython/Includes/posix/wait.pxd +38 -0
  219. Cython/Plex/Actions.pxd +24 -0
  220. Cython/Plex/Actions.py +119 -0
  221. Cython/Plex/DFA.pxd +14 -0
  222. Cython/Plex/DFA.py +164 -0
  223. Cython/Plex/Errors.py +48 -0
  224. Cython/Plex/Lexicons.py +178 -0
  225. Cython/Plex/Machines.pxd +36 -0
  226. Cython/Plex/Machines.py +238 -0
  227. Cython/Plex/Regexps.py +539 -0
  228. Cython/Plex/Scanners.pxd +47 -0
  229. Cython/Plex/Scanners.py +360 -0
  230. Cython/Plex/Transitions.pxd +14 -0
  231. Cython/Plex/Transitions.py +239 -0
  232. Cython/Plex/__init__.py +34 -0
  233. Cython/Runtime/__init__.py +1 -0
  234. Cython/Runtime/refnanny.pyx +261 -0
  235. Cython/Shadow.py +656 -0
  236. Cython/Shadow.pyi +521 -0
  237. Cython/StringIOTree.py +170 -0
  238. Cython/Tempita/__init__.py +4 -0
  239. Cython/Tempita/_looper.py +154 -0
  240. Cython/Tempita/_tempita.py +1091 -0
  241. Cython/TestUtils.py +417 -0
  242. Cython/Tests/TestCodeWriter.py +128 -0
  243. Cython/Tests/TestCythonUtils.py +202 -0
  244. Cython/Tests/TestJediTyper.py +223 -0
  245. Cython/Tests/TestShadow.py +114 -0
  246. Cython/Tests/TestStringIOTree.py +67 -0
  247. Cython/Tests/TestTestUtils.py +90 -0
  248. Cython/Tests/__init__.py +1 -0
  249. Cython/Tests/xmlrunner.py +390 -0
  250. Cython/Utility/AsyncGen.c +1263 -0
  251. Cython/Utility/Buffer.c +875 -0
  252. Cython/Utility/Builtins.c +660 -0
  253. Cython/Utility/CConvert.pyx +134 -0
  254. Cython/Utility/CMath.c +95 -0
  255. Cython/Utility/CommonStructures.c +139 -0
  256. Cython/Utility/Complex.c +378 -0
  257. Cython/Utility/Coroutine.c +2413 -0
  258. Cython/Utility/CpdefEnums.pyx +108 -0
  259. Cython/Utility/CppConvert.pyx +279 -0
  260. Cython/Utility/CppSupport.cpp +133 -0
  261. Cython/Utility/CythonFunction.c +1851 -0
  262. Cython/Utility/Dataclasses.c +185 -0
  263. Cython/Utility/Dataclasses.py +112 -0
  264. Cython/Utility/Embed.c +125 -0
  265. Cython/Utility/Exceptions.c +1017 -0
  266. Cython/Utility/ExtensionTypes.c +797 -0
  267. Cython/Utility/FunctionArguments.c +573 -0
  268. Cython/Utility/ImportExport.c +912 -0
  269. Cython/Utility/MemoryView.pyx +1478 -0
  270. Cython/Utility/MemoryView_C.c +992 -0
  271. Cython/Utility/ModuleSetupCode.c +2501 -0
  272. Cython/Utility/NumpyImportArray.c +46 -0
  273. Cython/Utility/ObjectHandling.c +3054 -0
  274. Cython/Utility/Optimize.c +1533 -0
  275. Cython/Utility/Overflow.c +404 -0
  276. Cython/Utility/Printing.c +86 -0
  277. Cython/Utility/Profile.c +660 -0
  278. Cython/Utility/StringTools.c +1206 -0
  279. Cython/Utility/TestCyUtilityLoader.pyx +8 -0
  280. Cython/Utility/TestCythonScope.pyx +75 -0
  281. Cython/Utility/TestUtilityLoader.c +12 -0
  282. Cython/Utility/TypeConversion.c +1329 -0
  283. Cython/Utility/UFuncs.pyx +50 -0
  284. Cython/Utility/UFuncs_C.c +89 -0
  285. Cython/Utility/__init__.py +28 -0
  286. Cython/Utility/arrayarray.h +143 -0
  287. Cython/Utils.py +687 -0
  288. Cython/__init__.py +10 -0
  289. Cython/__init__.pyi +7 -0
  290. Cython/py.typed +0 -0
  291. Cython-3.1.0a1.dist-info/COPYING.txt +19 -0
  292. Cython-3.1.0a1.dist-info/LICENSE.txt +176 -0
  293. Cython-3.1.0a1.dist-info/METADATA +67 -0
  294. Cython-3.1.0a1.dist-info/RECORD +301 -0
  295. Cython-3.1.0a1.dist-info/WHEEL +5 -0
  296. Cython-3.1.0a1.dist-info/entry_points.txt +4 -0
  297. Cython-3.1.0a1.dist-info/top_level.txt +3 -0
  298. cython.py +29 -0
  299. pyximport/__init__.py +4 -0
  300. pyximport/pyxbuild.py +160 -0
  301. pyximport/pyximport.py +482 -0
@@ -0,0 +1,112 @@
1
+ import os
2
+ import tempfile
3
+ import unittest
4
+ from Cython.Shadow import inline
5
+ from Cython.Build.Inline import safe_type
6
+ from Cython.TestUtils import CythonTest
7
+
8
+ try:
9
+ import numpy
10
+ has_numpy = True
11
+ except:
12
+ has_numpy = False
13
+
14
+ test_kwds = dict(force=True, quiet=True)
15
+
16
+ global_value = 100
17
+
18
+ class TestInline(CythonTest):
19
+ def setUp(self):
20
+ CythonTest.setUp(self)
21
+ self._call_kwds = dict(test_kwds)
22
+ if os.path.isdir('TEST_TMP'):
23
+ lib_dir = os.path.join('TEST_TMP','inline')
24
+ else:
25
+ lib_dir = tempfile.mkdtemp(prefix='cython_inline_')
26
+ self._call_kwds['lib_dir'] = lib_dir
27
+
28
+ def test_simple(self):
29
+ self.assertEqual(inline("return 1+2", **self._call_kwds), 3)
30
+
31
+ def test_types(self):
32
+ self.assertEqual(inline("""
33
+ cimport cython
34
+ return cython.typeof(a), cython.typeof(b)
35
+ """, a=1.0, b=[], **self._call_kwds), ('double', 'list object'))
36
+
37
+ def test_locals(self):
38
+ a = 1
39
+ b = 2
40
+ self.assertEqual(inline("return a+b", **self._call_kwds), 3)
41
+
42
+ def test_globals(self):
43
+ self.assertEqual(inline("return global_value + 1", **self._call_kwds), global_value + 1)
44
+
45
+ def test_no_return(self):
46
+ self.assertEqual(inline("""
47
+ a = 1
48
+ cdef double b = 2
49
+ cdef c = []
50
+ """, **self._call_kwds), dict(a=1, b=2.0, c=[]))
51
+
52
+ def test_def_node(self):
53
+ foo = inline("def foo(x): return x * x", **self._call_kwds)['foo']
54
+ self.assertEqual(foo(7), 49)
55
+
56
+ def test_class_ref(self):
57
+ class Type:
58
+ pass
59
+ tp = inline("Type")['Type']
60
+ self.assertEqual(tp, Type)
61
+
62
+ def test_pure(self):
63
+ import cython as cy
64
+ b = inline("""
65
+ b = cy.declare(float, a)
66
+ c = cy.declare(cy.pointer(cy.float), &b)
67
+ return b
68
+ """, a=3, **self._call_kwds)
69
+ self.assertEqual(type(b), float)
70
+
71
+ def test_compiler_directives(self):
72
+ self.assertEqual(
73
+ inline('return sum(x)',
74
+ x=[1, 2, 3],
75
+ cython_compiler_directives={'boundscheck': False}),
76
+ 6
77
+ )
78
+
79
+ def test_lang_version(self):
80
+ # GH-3419. Caching for inline code didn't always respect compiler directives.
81
+ inline_divcode = "def f(int a, int b): return a/b"
82
+ self.assertEqual(
83
+ inline(inline_divcode, language_level=2)['f'](5,2),
84
+ 2
85
+ )
86
+ self.assertEqual(
87
+ inline(inline_divcode, language_level=3)['f'](5,2),
88
+ 2.5
89
+ )
90
+ self.assertEqual(
91
+ inline(inline_divcode, language_level=2)['f'](5,2),
92
+ 2
93
+ )
94
+
95
+ def test_repeated_use(self):
96
+ inline_mulcode = "def f(int a, int b): return a * b"
97
+ self.assertEqual(inline(inline_mulcode)['f'](5, 2), 10)
98
+ self.assertEqual(inline(inline_mulcode)['f'](5, 3), 15)
99
+ self.assertEqual(inline(inline_mulcode)['f'](6, 2), 12)
100
+ self.assertEqual(inline(inline_mulcode)['f'](5, 2), 10)
101
+
102
+ f = inline(inline_mulcode)['f']
103
+ self.assertEqual(f(5, 2), 10)
104
+ self.assertEqual(f(5, 3), 15)
105
+
106
+ @unittest.skipIf(not has_numpy, "NumPy is not available")
107
+ def test_numpy(self):
108
+ import numpy
109
+ a = numpy.ndarray((10, 20))
110
+ a[0,0] = 10
111
+ self.assertEqual(safe_type(a), 'numpy.ndarray[numpy.float64_t, ndim=2]')
112
+ self.assertEqual(inline("return a[0,0]", a=a, **self._call_kwds), 10.0)
@@ -0,0 +1,287 @@
1
+ # tag: ipython
2
+
3
+ """Tests for the Cython magics extension."""
4
+
5
+
6
+ import os
7
+ import io
8
+ import sys
9
+ from contextlib import contextmanager
10
+ from unittest import skipIf
11
+
12
+ from Cython.Build import IpythonMagic
13
+ from Cython.TestUtils import CythonTest
14
+ from Cython.Compiler.Annotate import AnnotationCCodeWriter
15
+
16
+ try:
17
+ import IPython.testing.globalipapp
18
+ except ImportError:
19
+ # Disable tests and fake helpers for initialisation below.
20
+ def skip_if_not_installed(_):
21
+ return None
22
+ else:
23
+ def skip_if_not_installed(c):
24
+ return c
25
+
26
+ # not using IPython's decorators here because they depend on "nose"
27
+ skip_win32 = skipIf(sys.platform == 'win32', "Skip on Windows")
28
+
29
+ try:
30
+ # disable IPython history thread before it gets started to avoid having to clean it up
31
+ from IPython.core.history import HistoryManager
32
+ HistoryManager.enabled = False
33
+ except ImportError:
34
+ pass
35
+
36
+
37
+ @contextmanager
38
+ def capture_output():
39
+ backup = sys.stdout, sys.stderr
40
+ try:
41
+ replacement = [
42
+ io.TextIOWrapper(io.BytesIO(), encoding=sys.stdout.encoding),
43
+ io.TextIOWrapper(io.BytesIO(), encoding=sys.stderr.encoding),
44
+ ]
45
+ sys.stdout, sys.stderr = replacement
46
+ output = []
47
+ yield output
48
+ finally:
49
+ sys.stdout, sys.stderr = backup
50
+ for wrapper in replacement:
51
+ wrapper.seek(0) # rewind
52
+ output.append(wrapper.read())
53
+ wrapper.close()
54
+
55
+
56
+ code = """\
57
+ def f(x):
58
+ return 2*x
59
+ """
60
+
61
+ cython3_code = """\
62
+ def f(int x):
63
+ return 2 / x
64
+
65
+ def call(x):
66
+ return f(*(x,))
67
+ """
68
+
69
+ pgo_cython3_code = cython3_code + """\
70
+ def main():
71
+ for _ in range(100): call(5)
72
+ main()
73
+ """
74
+
75
+ compile_error_code = '''\
76
+ cdef extern from *:
77
+ """
78
+ xxx a=1;
79
+ """
80
+ int a;
81
+ def doit():
82
+ return a
83
+ '''
84
+
85
+ compile_warning_code = '''\
86
+ cdef extern from *:
87
+ """
88
+ #pragma message ( "CWarning" )
89
+ int a = 42;
90
+ """
91
+ int a;
92
+ def doit():
93
+ return a
94
+ '''
95
+
96
+
97
+ @skip_if_not_installed
98
+ class TestIPythonMagic(CythonTest):
99
+
100
+ @classmethod
101
+ def setUpClass(cls):
102
+ CythonTest.setUpClass()
103
+ cls._ip = IPython.testing.globalipapp.get_ipython()
104
+
105
+ def setUp(self):
106
+ CythonTest.setUp(self)
107
+ self._ip.extension_manager.load_extension('cython')
108
+
109
+ def test_cython_inline(self):
110
+ ip = self._ip
111
+ ip.ex('a=10; b=20')
112
+ result = ip.run_cell_magic('cython_inline', '', 'return a+b')
113
+ self.assertEqual(result, 30)
114
+
115
+ @skip_win32
116
+ def test_cython_pyximport(self):
117
+ ip = self._ip
118
+ module_name = '_test_cython_pyximport'
119
+ ip.run_cell_magic('cython_pyximport', module_name, code)
120
+ ip.ex('g = f(10)')
121
+ self.assertEqual(ip.user_ns['g'], 20.0)
122
+ ip.run_cell_magic('cython_pyximport', module_name, code)
123
+ ip.ex('h = f(-10)')
124
+ self.assertEqual(ip.user_ns['h'], -20.0)
125
+ try:
126
+ os.remove(module_name + '.pyx')
127
+ except OSError:
128
+ pass
129
+
130
+ def test_cython(self):
131
+ ip = self._ip
132
+ ip.run_cell_magic('cython', '', code)
133
+ ip.ex('g = f(10)')
134
+ self.assertEqual(ip.user_ns['g'], 20.0)
135
+
136
+ def test_cython_name(self):
137
+ # The Cython module named 'mymodule' defines the function f.
138
+ ip = self._ip
139
+ ip.run_cell_magic('cython', '--name=mymodule', code)
140
+ # This module can now be imported in the interactive namespace.
141
+ ip.ex('import mymodule; g = mymodule.f(10)')
142
+ self.assertEqual(ip.user_ns['g'], 20.0)
143
+
144
+ def test_cython_language_level(self):
145
+ # The Cython cell defines the functions f() and call().
146
+ ip = self._ip
147
+ ip.run_cell_magic('cython', '', cython3_code)
148
+ ip.ex('g = f(10); h = call(10)')
149
+ self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
150
+ self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
151
+
152
+ def test_cython3(self):
153
+ # The Cython cell defines the functions f() and call().
154
+ ip = self._ip
155
+ ip.run_cell_magic('cython', '-3', cython3_code)
156
+ ip.ex('g = f(10); h = call(10)')
157
+ self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
158
+ self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
159
+
160
+ def test_cython2(self):
161
+ # The Cython cell defines the functions f() and call().
162
+ ip = self._ip
163
+ ip.run_cell_magic('cython', '-2', cython3_code)
164
+ ip.ex('g = f(10); h = call(10)')
165
+ self.assertEqual(ip.user_ns['g'], 2 // 10)
166
+ self.assertEqual(ip.user_ns['h'], 2 // 10)
167
+
168
+ def test_cython_compile_error_shown(self):
169
+ ip = self._ip
170
+ with capture_output() as out:
171
+ ip.run_cell_magic('cython', '-3', compile_error_code)
172
+ captured_out, captured_err = out
173
+
174
+ # it could be that c-level output is captured by distutil-extension
175
+ # (and not by us) and is printed to stdout:
176
+ captured_all = captured_out + "\n" + captured_err
177
+ self.assertTrue("error" in captured_all, msg="error in " + captured_all)
178
+
179
+ def test_cython_link_error_shown(self):
180
+ ip = self._ip
181
+ with capture_output() as out:
182
+ ip.run_cell_magic('cython', '-3 -l=xxxxxxxx', code)
183
+ captured_out, captured_err = out
184
+
185
+ # it could be that c-level output is captured by distutil-extension
186
+ # (and not by us) and is printed to stdout:
187
+ captured_all = captured_out + "\n!" + captured_err
188
+ self.assertTrue("error" in captured_all, msg="error in " + captured_all)
189
+
190
+ def test_cython_warning_shown(self):
191
+ ip = self._ip
192
+ with capture_output() as out:
193
+ # force rebuild, otherwise no warning as after the first success
194
+ # no build step is performed
195
+ ip.run_cell_magic('cython', '-3 -f', compile_warning_code)
196
+ captured_out, captured_err = out
197
+
198
+ # check that warning was printed to stdout even if build hasn't failed
199
+ self.assertTrue("CWarning" in captured_out)
200
+
201
+ @skip_win32
202
+ def test_cython3_pgo(self):
203
+ # The Cython cell defines the functions f() and call().
204
+ ip = self._ip
205
+ ip.run_cell_magic('cython', '-3 --pgo', pgo_cython3_code)
206
+ ip.ex('g = f(10); h = call(10); main()')
207
+ self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
208
+ self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
209
+
210
+ @skip_win32
211
+ def test_extlibs(self):
212
+ ip = self._ip
213
+ code = """
214
+ from libc.math cimport sin
215
+ x = sin(0.0)
216
+ """
217
+ ip.user_ns['x'] = 1
218
+ ip.run_cell_magic('cython', '-l m', code)
219
+ self.assertEqual(ip.user_ns['x'], 0)
220
+
221
+
222
+ def test_cython_verbose(self):
223
+ ip = self._ip
224
+ ip.run_cell_magic('cython', '--verbose', code)
225
+ ip.ex('g = f(10)')
226
+ self.assertEqual(ip.user_ns['g'], 20.0)
227
+
228
+ def test_cython_verbose_thresholds(self):
229
+ @contextmanager
230
+ def mock_distutils():
231
+ class MockLog:
232
+ DEBUG = 1
233
+ INFO = 2
234
+ thresholds = [INFO]
235
+
236
+ def set_threshold(self, val):
237
+ self.thresholds.append(val)
238
+ return self.thresholds[-2]
239
+
240
+
241
+ new_log = MockLog()
242
+ old_log = IpythonMagic.distutils.log
243
+ try:
244
+ IpythonMagic.distutils.log = new_log
245
+ yield new_log
246
+ finally:
247
+ IpythonMagic.distutils.log = old_log
248
+
249
+ ip = self._ip
250
+ with mock_distutils() as verbose_log:
251
+ ip.run_cell_magic('cython', '--verbose', code)
252
+ ip.ex('g = f(10)')
253
+ self.assertEqual(ip.user_ns['g'], 20.0)
254
+ self.assertEqual([verbose_log.INFO, verbose_log.DEBUG, verbose_log.INFO],
255
+ verbose_log.thresholds)
256
+
257
+ with mock_distutils() as normal_log:
258
+ ip.run_cell_magic('cython', '', code)
259
+ ip.ex('g = f(10)')
260
+ self.assertEqual(ip.user_ns['g'], 20.0)
261
+ self.assertEqual([normal_log.INFO], normal_log.thresholds)
262
+
263
+ def test_cython_no_annotate(self):
264
+ ip = self._ip
265
+ html = ip.run_cell_magic('cython', '', code)
266
+ self.assertTrue(html is None)
267
+
268
+ def test_cython_annotate(self):
269
+ ip = self._ip
270
+ html = ip.run_cell_magic('cython', '--annotate', code)
271
+ # somewhat brittle way to differentiate between annotated htmls
272
+ # with/without complete source code:
273
+ self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html.data)
274
+
275
+ def test_cython_annotate_default(self):
276
+ ip = self._ip
277
+ html = ip.run_cell_magic('cython', '-a', code)
278
+ # somewhat brittle way to differentiate between annotated htmls
279
+ # with/without complete source code:
280
+ self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html.data)
281
+
282
+ def test_cython_annotate_complete_c_code(self):
283
+ ip = self._ip
284
+ html = ip.run_cell_magic('cython', '--annotate-fullc', code)
285
+ # somewhat brittle way to differentiate between annotated htmls
286
+ # with/without complete source code:
287
+ self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE in html.data)
@@ -0,0 +1,212 @@
1
+ import shutil
2
+ import os
3
+ import tempfile
4
+ import time
5
+
6
+ import Cython.Build.Dependencies
7
+ import Cython.Utils
8
+ from Cython.TestUtils import CythonTest
9
+
10
+
11
+ def fresh_cythonize(*args, **kwargs):
12
+ Cython.Utils.clear_function_caches()
13
+ Cython.Build.Dependencies._dep_tree = None # discard method caches
14
+ Cython.Build.Dependencies.cythonize(*args, **kwargs)
15
+
16
+ class TestRecythonize(CythonTest):
17
+
18
+ def setUp(self):
19
+ CythonTest.setUp(self)
20
+ self.temp_dir = (
21
+ tempfile.mkdtemp(
22
+ prefix='recythonize-test',
23
+ dir='TEST_TMP' if os.path.isdir('TEST_TMP') else None
24
+ )
25
+ )
26
+
27
+ def tearDown(self):
28
+ CythonTest.tearDown(self)
29
+ shutil.rmtree(self.temp_dir)
30
+
31
+ def test_recythonize_pyx_on_pxd_change(self):
32
+
33
+ src_dir = tempfile.mkdtemp(prefix='src', dir=self.temp_dir)
34
+
35
+ a_pxd = os.path.join(src_dir, 'a.pxd')
36
+ a_pyx = os.path.join(src_dir, 'a.pyx')
37
+ a_c = os.path.join(src_dir, 'a.c')
38
+ dep_tree = Cython.Build.Dependencies.create_dependency_tree()
39
+
40
+ with open(a_pxd, 'w') as f:
41
+ f.write('cdef int value\n')
42
+
43
+ with open(a_pyx, 'w') as f:
44
+ f.write('value = 1\n')
45
+
46
+
47
+ # The dependencies for "a.pyx" are "a.pxd" and "a.pyx".
48
+ self.assertEqual({a_pxd, a_pyx}, dep_tree.all_dependencies(a_pyx))
49
+
50
+ # Cythonize to create a.c
51
+ fresh_cythonize(a_pyx)
52
+
53
+ # Sleep to address coarse time-stamp precision.
54
+ time.sleep(1)
55
+
56
+ with open(a_c) as f:
57
+ a_c_contents1 = f.read()
58
+
59
+ with open(a_pxd, 'w') as f:
60
+ f.write('cdef double value\n')
61
+
62
+ fresh_cythonize(a_pyx)
63
+
64
+ with open(a_c) as f:
65
+ a_c_contents2 = f.read()
66
+
67
+ self.assertTrue("__pyx_v_1a_value = 1;" in a_c_contents1)
68
+ self.assertFalse("__pyx_v_1a_value = 1;" in a_c_contents2)
69
+ self.assertTrue("__pyx_v_1a_value = 1.0;" in a_c_contents2)
70
+ self.assertFalse("__pyx_v_1a_value = 1.0;" in a_c_contents1)
71
+
72
+
73
+ def test_recythonize_py_on_pxd_change(self):
74
+
75
+ src_dir = tempfile.mkdtemp(prefix='src', dir=self.temp_dir)
76
+
77
+ a_pxd = os.path.join(src_dir, 'a.pxd')
78
+ a_py = os.path.join(src_dir, 'a.py')
79
+ a_c = os.path.join(src_dir, 'a.c')
80
+ dep_tree = Cython.Build.Dependencies.create_dependency_tree()
81
+
82
+ with open(a_pxd, 'w') as f:
83
+ f.write('cdef int value\n')
84
+
85
+ with open(a_py, 'w') as f:
86
+ f.write('value = 1\n')
87
+
88
+
89
+ # The dependencies for "a.py" are "a.pxd" and "a.py".
90
+ self.assertEqual({a_pxd, a_py}, dep_tree.all_dependencies(a_py))
91
+
92
+ # Cythonize to create a.c
93
+ fresh_cythonize(a_py)
94
+
95
+ # Sleep to address coarse time-stamp precision.
96
+ time.sleep(1)
97
+
98
+ with open(a_c) as f:
99
+ a_c_contents1 = f.read()
100
+
101
+ with open(a_pxd, 'w') as f:
102
+ f.write('cdef double value\n')
103
+
104
+ fresh_cythonize(a_py)
105
+
106
+ with open(a_c) as f:
107
+ a_c_contents2 = f.read()
108
+
109
+
110
+ self.assertTrue("__pyx_v_1a_value = 1;" in a_c_contents1)
111
+ self.assertFalse("__pyx_v_1a_value = 1;" in a_c_contents2)
112
+ self.assertTrue("__pyx_v_1a_value = 1.0;" in a_c_contents2)
113
+ self.assertFalse("__pyx_v_1a_value = 1.0;" in a_c_contents1)
114
+
115
+ def test_recythonize_pyx_on_dep_pxd_change(self):
116
+ src_dir = tempfile.mkdtemp(prefix='src', dir=self.temp_dir)
117
+
118
+ a_pxd = os.path.join(src_dir, 'a.pxd')
119
+ a_pyx = os.path.join(src_dir, 'a.pyx')
120
+ b_pyx = os.path.join(src_dir, 'b.pyx')
121
+ b_c = os.path.join(src_dir, 'b.c')
122
+ dep_tree = Cython.Build.Dependencies.create_dependency_tree()
123
+
124
+ with open(a_pxd, 'w') as f:
125
+ f.write('cdef int value\n')
126
+
127
+ with open(a_pyx, 'w') as f:
128
+ f.write('value = 1\n')
129
+
130
+ with open(b_pyx, 'w') as f:
131
+ f.write('cimport a\n' + 'a.value = 2\n')
132
+
133
+
134
+ # The dependencies for "b.pyx" are "a.pxd" and "b.pyx".
135
+ self.assertEqual({a_pxd, b_pyx}, dep_tree.all_dependencies(b_pyx))
136
+
137
+
138
+ # Cythonize to create b.c
139
+ fresh_cythonize([a_pyx, b_pyx])
140
+
141
+ # Sleep to address coarse time-stamp precision.
142
+ time.sleep(1)
143
+
144
+ with open(b_c) as f:
145
+ b_c_contents1 = f.read()
146
+
147
+ with open(a_pxd, 'w') as f:
148
+ f.write('cdef double value\n')
149
+
150
+ fresh_cythonize([a_pyx, b_pyx])
151
+
152
+ with open(b_c) as f:
153
+ b_c_contents2 = f.read()
154
+
155
+
156
+
157
+ self.assertTrue("__pyx_v_1a_value = 2;" in b_c_contents1)
158
+ self.assertFalse("__pyx_v_1a_value = 2;" in b_c_contents2)
159
+ self.assertTrue("__pyx_v_1a_value = 2.0;" in b_c_contents2)
160
+ self.assertFalse("__pyx_v_1a_value = 2.0;" in b_c_contents1)
161
+
162
+
163
+
164
+ def test_recythonize_py_on_dep_pxd_change(self):
165
+
166
+ src_dir = tempfile.mkdtemp(prefix='src', dir=self.temp_dir)
167
+
168
+ a_pxd = os.path.join(src_dir, 'a.pxd')
169
+ a_pyx = os.path.join(src_dir, 'a.pyx')
170
+ b_pxd = os.path.join(src_dir, 'b.pxd')
171
+ b_py = os.path.join(src_dir, 'b.py')
172
+ b_c = os.path.join(src_dir, 'b.c')
173
+ dep_tree = Cython.Build.Dependencies.create_dependency_tree()
174
+
175
+ with open(a_pxd, 'w') as f:
176
+ f.write('cdef int value\n')
177
+
178
+ with open(a_pyx, 'w') as f:
179
+ f.write('value = 1\n')
180
+
181
+ with open(b_pxd, 'w') as f:
182
+ f.write('cimport a\n')
183
+
184
+ with open(b_py, 'w') as f:
185
+ f.write('a.value = 2\n')
186
+
187
+
188
+ # The dependencies for b.py are "a.pxd", "b.pxd" and "b.py".
189
+ self.assertEqual({a_pxd, b_pxd, b_py}, dep_tree.all_dependencies(b_py))
190
+
191
+
192
+ # Cythonize to create b.c
193
+ fresh_cythonize([a_pyx, b_py])
194
+
195
+ # Sleep to address coarse time-stamp precision.
196
+ time.sleep(1)
197
+
198
+ with open(b_c) as f:
199
+ b_c_contents1 = f.read()
200
+
201
+ with open(a_pxd, 'w') as f:
202
+ f.write('cdef double value\n')
203
+
204
+ fresh_cythonize([a_pyx, b_py])
205
+
206
+ with open(b_c) as f:
207
+ b_c_contents2 = f.read()
208
+
209
+ self.assertTrue("__pyx_v_1a_value = 2;" in b_c_contents1)
210
+ self.assertFalse("__pyx_v_1a_value = 2;" in b_c_contents2)
211
+ self.assertTrue("__pyx_v_1a_value = 2.0;" in b_c_contents2)
212
+ self.assertFalse("__pyx_v_1a_value = 2.0;" in b_c_contents1)