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,591 @@
1
+ from .Errors import error, message
2
+ from . import ExprNodes
3
+ from . import Nodes
4
+ from . import Builtin
5
+ from . import PyrexTypes
6
+ from .. import Utils
7
+ from .PyrexTypes import py_object_type, unspecified_type
8
+ from .Visitor import CythonTransform, EnvTransform
9
+
10
+ from functools import reduce
11
+
12
+
13
+ class TypedExprNode(ExprNodes.ExprNode):
14
+ # Used for declaring assignments of a specified type without a known entry.
15
+ subexprs = []
16
+
17
+ def __init__(self, type, pos=None):
18
+ super().__init__(pos, type=type)
19
+
20
+ object_expr = TypedExprNode(py_object_type)
21
+
22
+
23
+ class MarkParallelAssignments(EnvTransform):
24
+ # Collects assignments inside parallel blocks prange, with parallel.
25
+ # Perhaps it's better to move it to ControlFlowAnalysis.
26
+
27
+ # tells us whether we're in a normal loop
28
+ in_loop = False
29
+
30
+ parallel_errors = False
31
+
32
+ def __init__(self, context):
33
+ # Track the parallel block scopes (with parallel, for i in prange())
34
+ self.parallel_block_stack = []
35
+ super().__init__(context)
36
+
37
+ def mark_assignment(self, lhs, rhs, inplace_op=None):
38
+ if isinstance(lhs, (ExprNodes.NameNode, Nodes.PyArgDeclNode)):
39
+ if lhs.entry is None:
40
+ # TODO: This shouldn't happen...
41
+ return
42
+
43
+ if self.parallel_block_stack:
44
+ parallel_node = self.parallel_block_stack[-1]
45
+ previous_assignment = parallel_node.assignments.get(lhs.entry)
46
+
47
+ # If there was a previous assignment to the variable, keep the
48
+ # previous assignment position
49
+ if previous_assignment:
50
+ pos, previous_inplace_op = previous_assignment
51
+
52
+ if (inplace_op and previous_inplace_op and
53
+ inplace_op != previous_inplace_op):
54
+ # x += y; x *= y
55
+ t = (inplace_op, previous_inplace_op)
56
+ error(lhs.pos,
57
+ "Reduction operator '%s' is inconsistent "
58
+ "with previous reduction operator '%s'" % t)
59
+ else:
60
+ pos = lhs.pos
61
+
62
+ parallel_node.assignments[lhs.entry] = (pos, inplace_op)
63
+ parallel_node.assigned_nodes.append(lhs)
64
+
65
+ elif isinstance(lhs, ExprNodes.SequenceNode):
66
+ for i, arg in enumerate(lhs.args):
67
+ if not rhs or arg.is_starred:
68
+ item_node = None
69
+ else:
70
+ item_node = rhs.inferable_item_node(i)
71
+ self.mark_assignment(arg, item_node)
72
+ else:
73
+ # Could use this info to infer cdef class attributes...
74
+ pass
75
+
76
+ def visit_WithTargetAssignmentStatNode(self, node):
77
+ self.mark_assignment(node.lhs, node.with_node.enter_call)
78
+ self.visitchildren(node)
79
+ return node
80
+
81
+ def visit_SingleAssignmentNode(self, node):
82
+ if self.parallel_block_stack:
83
+ node.in_parallel_block = True
84
+ self.mark_assignment(node.lhs, node.rhs)
85
+ self.visitchildren(node)
86
+ return node
87
+
88
+ def visit_CascadedAssignmentNode(self, node):
89
+ for lhs in node.lhs_list:
90
+ self.mark_assignment(lhs, node.rhs)
91
+ self.visitchildren(node)
92
+ return node
93
+
94
+ def visit_InPlaceAssignmentNode(self, node):
95
+ self.mark_assignment(node.lhs, node.create_binop_node(), node.operator)
96
+ self.visitchildren(node)
97
+ return node
98
+
99
+ def visit_ForInStatNode(self, node):
100
+ # TODO: Remove redundancy with range optimization...
101
+ is_special = False
102
+ sequence = node.iterator.sequence
103
+ target = node.target
104
+ iterator_scope = node.iterator.expr_scope or self.current_env()
105
+ if isinstance(sequence, ExprNodes.SimpleCallNode):
106
+ function = sequence.function
107
+ if sequence.self is None and function.is_name:
108
+ entry = iterator_scope.lookup(function.name)
109
+ if not entry or entry.is_builtin:
110
+ if function.name == 'reversed' and len(sequence.args) == 1:
111
+ sequence = sequence.args[0]
112
+ elif function.name == 'enumerate' and len(sequence.args) == 1:
113
+ if target.is_sequence_constructor and len(target.args) == 2:
114
+ iterator = sequence.args[0]
115
+ if iterator.is_name:
116
+ iterator_type = iterator.infer_type(iterator_scope)
117
+ if iterator_type.is_builtin_type:
118
+ # assume that builtin types have a length within Py_ssize_t
119
+ self.mark_assignment(
120
+ target.args[0],
121
+ ExprNodes.IntNode(target.pos, value='PY_SSIZE_T_MAX',
122
+ type=PyrexTypes.c_py_ssize_t_type))
123
+ target = target.args[1]
124
+ sequence = sequence.args[0]
125
+ if isinstance(sequence, ExprNodes.SimpleCallNode):
126
+ function = sequence.function
127
+ if sequence.self is None and function.is_name and function.name in ('range', 'xrange'):
128
+ entry = iterator_scope.lookup(function.name)
129
+ if not entry or entry.is_type and entry.type is Builtin.range_type:
130
+ is_special = True
131
+ for arg in sequence.args[:2]:
132
+ self.mark_assignment(target, arg)
133
+ if len(sequence.args) > 2:
134
+ self.mark_assignment(
135
+ target,
136
+ ExprNodes.binop_node(node.pos,
137
+ '+',
138
+ sequence.args[0],
139
+ sequence.args[2]))
140
+ if not is_special:
141
+ # A for-loop basically translates to subsequent calls to
142
+ # __getitem__(), so using an IndexNode here allows us to
143
+ # naturally infer the base type of pointers, C arrays,
144
+ # Python strings, etc., while correctly falling back to an
145
+ # object type when the base type cannot be handled.
146
+ self.mark_assignment(target, ExprNodes.IndexNode(
147
+ node.pos,
148
+ base=sequence,
149
+ index=ExprNodes.IntNode(target.pos, value='PY_SSIZE_T_MAX',
150
+ type=PyrexTypes.c_py_ssize_t_type)))
151
+
152
+ self.visitchildren(node)
153
+ return node
154
+
155
+ def visit_ForFromStatNode(self, node):
156
+ self.mark_assignment(node.target, node.bound1)
157
+ if node.step is not None:
158
+ self.mark_assignment(node.target,
159
+ ExprNodes.binop_node(node.pos,
160
+ '+',
161
+ node.bound1,
162
+ node.step))
163
+ self.visitchildren(node)
164
+ return node
165
+
166
+ def visit_WhileStatNode(self, node):
167
+ self.visitchildren(node)
168
+ return node
169
+
170
+ def visit_ExceptClauseNode(self, node):
171
+ if node.target is not None:
172
+ self.mark_assignment(node.target, node.exc_value)
173
+ self.visitchildren(node)
174
+ return node
175
+
176
+ def visit_FromCImportStatNode(self, node):
177
+ return node # Can't be assigned to...
178
+
179
+ def visit_FromImportStatNode(self, node):
180
+ for name, target in node.items:
181
+ if name != "*":
182
+ self.mark_assignment(target, object_expr)
183
+ self.visitchildren(node)
184
+ return node
185
+
186
+ def visit_DefNode(self, node):
187
+ # use fake expressions with the right result type
188
+ if node.star_arg:
189
+ self.mark_assignment(
190
+ node.star_arg, TypedExprNode(Builtin.tuple_type, node.pos))
191
+ if node.starstar_arg:
192
+ self.mark_assignment(
193
+ node.starstar_arg, TypedExprNode(Builtin.dict_type, node.pos))
194
+ EnvTransform.visit_FuncDefNode(self, node)
195
+ return node
196
+
197
+ def visit_DelStatNode(self, node):
198
+ for arg in node.args:
199
+ self.mark_assignment(arg, arg)
200
+ self.visitchildren(node)
201
+ return node
202
+
203
+ def visit_ParallelStatNode(self, node):
204
+ if self.parallel_block_stack:
205
+ node.parent = self.parallel_block_stack[-1]
206
+ else:
207
+ node.parent = None
208
+
209
+ nested = False
210
+ if node.is_prange:
211
+ if not node.parent:
212
+ node.is_parallel = True
213
+ else:
214
+ node.is_parallel = (node.parent.is_prange or not
215
+ node.parent.is_parallel)
216
+ nested = node.parent.is_prange
217
+ else:
218
+ node.is_parallel = True
219
+ # Note: nested with parallel() blocks are handled by
220
+ # ParallelRangeTransform!
221
+ # nested = node.parent
222
+ nested = node.parent and node.parent.is_prange
223
+
224
+ self.parallel_block_stack.append(node)
225
+
226
+ nested = nested or len(self.parallel_block_stack) > 2
227
+ if not self.parallel_errors and nested and not node.is_prange:
228
+ error(node.pos, "Only prange() may be nested")
229
+ self.parallel_errors = True
230
+
231
+ if node.is_prange:
232
+ self.visitchildren(node, attrs=('body', 'target', 'args'))
233
+
234
+ self.parallel_block_stack.pop()
235
+ if node.else_clause:
236
+ node.else_clause = self.visit(node.else_clause)
237
+ else:
238
+ self.visitchildren(node)
239
+ self.parallel_block_stack.pop()
240
+
241
+ self.parallel_errors = False
242
+ return node
243
+
244
+ def visit_YieldExprNode(self, node):
245
+ if self.parallel_block_stack:
246
+ error(node.pos, "'%s' not allowed in parallel sections" % node.expr_keyword)
247
+ return node
248
+
249
+ def visit_ReturnStatNode(self, node):
250
+ node.in_parallel = bool(self.parallel_block_stack)
251
+ return node
252
+
253
+ def visit_ExprNode(self, node):
254
+ self.visitchildren(node)
255
+ if self.parallel_block_stack:
256
+ node.in_parallel_block = True
257
+ return node
258
+
259
+
260
+ class MarkOverflowingArithmetic(CythonTransform):
261
+
262
+ # It may be possible to integrate this with the above for
263
+ # performance improvements (though likely not worth it).
264
+
265
+ might_overflow = False
266
+
267
+ def __call__(self, root):
268
+ self.env_stack = []
269
+ self.env = root.scope
270
+ return super().__call__(root)
271
+
272
+ def visit_safe_node(self, node):
273
+ self.might_overflow, saved = False, self.might_overflow
274
+ self.visitchildren(node)
275
+ self.might_overflow = saved
276
+ return node
277
+
278
+ def visit_neutral_node(self, node):
279
+ self.visitchildren(node)
280
+ return node
281
+
282
+ def visit_dangerous_node(self, node):
283
+ self.might_overflow, saved = True, self.might_overflow
284
+ self.visitchildren(node)
285
+ self.might_overflow = saved
286
+ return node
287
+
288
+ def visit_FuncDefNode(self, node):
289
+ self.env_stack.append(self.env)
290
+ self.env = node.local_scope
291
+ self.visit_safe_node(node)
292
+ self.env = self.env_stack.pop()
293
+ return node
294
+
295
+ def visit_NameNode(self, node):
296
+ if self.might_overflow:
297
+ entry = node.entry or self.env.lookup(node.name)
298
+ if entry:
299
+ entry.might_overflow = True
300
+ return node
301
+
302
+ def visit_BinopNode(self, node):
303
+ if node.operator in '&|^':
304
+ return self.visit_neutral_node(node)
305
+ else:
306
+ return self.visit_dangerous_node(node)
307
+
308
+ def visit_SimpleCallNode(self, node):
309
+ if node.function.is_name and node.function.name == 'abs':
310
+ # Overflows for minimum value of fixed size ints.
311
+ return self.visit_dangerous_node(node)
312
+ else:
313
+ return self.visit_neutral_node(node)
314
+
315
+ visit_UnopNode = visit_neutral_node
316
+
317
+ visit_UnaryMinusNode = visit_dangerous_node
318
+
319
+ visit_InPlaceAssignmentNode = visit_dangerous_node
320
+
321
+ visit_Node = visit_safe_node
322
+
323
+ def visit_assignment(self, lhs, rhs):
324
+ if (isinstance(rhs, ExprNodes.IntNode)
325
+ and isinstance(lhs, ExprNodes.NameNode)
326
+ and Utils.long_literal(rhs.value)):
327
+ entry = lhs.entry or self.env.lookup(lhs.name)
328
+ if entry:
329
+ entry.might_overflow = True
330
+
331
+ def visit_SingleAssignmentNode(self, node):
332
+ self.visit_assignment(node.lhs, node.rhs)
333
+ self.visitchildren(node)
334
+ return node
335
+
336
+ def visit_CascadedAssignmentNode(self, node):
337
+ for lhs in node.lhs_list:
338
+ self.visit_assignment(lhs, node.rhs)
339
+ self.visitchildren(node)
340
+ return node
341
+
342
+ class PyObjectTypeInferer:
343
+ """
344
+ If it's not declared, it's a PyObject.
345
+ """
346
+ def infer_types(self, scope):
347
+ """
348
+ Given a dict of entries, map all unspecified types to a specified type.
349
+ """
350
+ for name, entry in scope.entries.items():
351
+ if entry.type is unspecified_type:
352
+ entry.type = py_object_type
353
+
354
+ class SimpleAssignmentTypeInferer:
355
+ """
356
+ Very basic type inference.
357
+
358
+ Note: in order to support cross-closure type inference, this must be
359
+ applies to nested scopes in top-down order.
360
+ """
361
+ def set_entry_type(self, entry, entry_type, scope):
362
+ for e in entry.all_entries():
363
+ e.type = entry_type
364
+ if e.type.is_memoryviewslice:
365
+ # memoryview slices crash if they don't get initialized
366
+ e.init = e.type.default_value
367
+ if e.type.is_cpp_class:
368
+ if scope.directives['cpp_locals']:
369
+ e.make_cpp_optional()
370
+ else:
371
+ e.type.check_nullary_constructor(entry.pos)
372
+
373
+ def infer_types(self, scope):
374
+ enabled = scope.directives['infer_types']
375
+ verbose = scope.directives['infer_types.verbose']
376
+
377
+ if enabled == True:
378
+ spanning_type = aggressive_spanning_type
379
+ elif enabled is None: # safe mode
380
+ spanning_type = safe_spanning_type
381
+ else:
382
+ for entry in scope.entries.values():
383
+ if entry.type is unspecified_type:
384
+ self.set_entry_type(entry, py_object_type, scope)
385
+ return
386
+
387
+ # Set of assignments
388
+ assignments = set()
389
+ assmts_resolved = set()
390
+ dependencies = {}
391
+ assmt_to_names = {}
392
+
393
+ for name, entry in scope.entries.items():
394
+ for assmt in entry.cf_assignments:
395
+ names = assmt.type_dependencies()
396
+ assmt_to_names[assmt] = names
397
+ assmts = set()
398
+ for node in names:
399
+ assmts.update(node.cf_state)
400
+ dependencies[assmt] = assmts
401
+ if entry.type is unspecified_type:
402
+ assignments.update(entry.cf_assignments)
403
+ else:
404
+ assmts_resolved.update(entry.cf_assignments)
405
+
406
+ def infer_name_node_type(node):
407
+ types = [assmt.inferred_type for assmt in node.cf_state]
408
+ if not types:
409
+ node_type = py_object_type
410
+ else:
411
+ entry = node.entry
412
+ node_type = spanning_type(
413
+ types, entry.might_overflow, scope)
414
+ node.inferred_type = node_type
415
+
416
+ def infer_name_node_type_partial(node):
417
+ types = [assmt.inferred_type for assmt in node.cf_state
418
+ if assmt.inferred_type is not None]
419
+ if not types:
420
+ return
421
+ entry = node.entry
422
+ return spanning_type(types, entry.might_overflow, scope)
423
+
424
+ def inferred_types(entry):
425
+ has_none = False
426
+ has_pyobjects = False
427
+ types = []
428
+ for assmt in entry.cf_assignments:
429
+ if assmt.rhs.is_none:
430
+ has_none = True
431
+ else:
432
+ rhs_type = assmt.inferred_type
433
+ if rhs_type and rhs_type.is_pyobject:
434
+ has_pyobjects = True
435
+ types.append(rhs_type)
436
+ # Ignore None assignments as long as there are concrete Python type assignments.
437
+ # but include them if None is the only assigned Python object.
438
+ if has_none and not has_pyobjects:
439
+ types.append(py_object_type)
440
+ return types
441
+
442
+ def resolve_assignments(assignments):
443
+ resolved = set()
444
+ for assmt in assignments:
445
+ deps = dependencies[assmt]
446
+ # All assignments are resolved
447
+ if assmts_resolved.issuperset(deps):
448
+ for node in assmt_to_names[assmt]:
449
+ infer_name_node_type(node)
450
+ # Resolve assmt
451
+ inferred_type = assmt.infer_type()
452
+ assmts_resolved.add(assmt)
453
+ resolved.add(assmt)
454
+ assignments.difference_update(resolved)
455
+ return resolved
456
+
457
+ def partial_infer(assmt):
458
+ partial_types = []
459
+ for node in assmt_to_names[assmt]:
460
+ partial_type = infer_name_node_type_partial(node)
461
+ if partial_type is None:
462
+ return False
463
+ partial_types.append((node, partial_type))
464
+ for node, partial_type in partial_types:
465
+ node.inferred_type = partial_type
466
+ assmt.infer_type()
467
+ return True
468
+
469
+ partial_assmts = set()
470
+ def resolve_partial(assignments):
471
+ # try to handle circular references
472
+ partials = set()
473
+ for assmt in assignments:
474
+ if assmt in partial_assmts:
475
+ continue
476
+ if partial_infer(assmt):
477
+ partials.add(assmt)
478
+ assmts_resolved.add(assmt)
479
+ partial_assmts.update(partials)
480
+ return partials
481
+
482
+ # Infer assignments
483
+ while True:
484
+ if not resolve_assignments(assignments):
485
+ if not resolve_partial(assignments):
486
+ break
487
+ inferred = set()
488
+ # First pass
489
+ for entry in scope.entries.values():
490
+ if entry.type is not unspecified_type:
491
+ continue
492
+ entry_type = py_object_type
493
+ if assmts_resolved.issuperset(entry.cf_assignments):
494
+ types = inferred_types(entry)
495
+ if types and all(types):
496
+ entry_type = spanning_type(
497
+ types, entry.might_overflow, scope)
498
+ inferred.add(entry)
499
+ self.set_entry_type(entry, entry_type, scope)
500
+
501
+ def reinfer():
502
+ dirty = False
503
+ for entry in inferred:
504
+ for assmt in entry.cf_assignments:
505
+ assmt.infer_type()
506
+ types = inferred_types(entry)
507
+ new_type = spanning_type(types, entry.might_overflow, scope)
508
+ if new_type != entry.type:
509
+ self.set_entry_type(entry, new_type, scope)
510
+ dirty = True
511
+ return dirty
512
+
513
+ # types propagation
514
+ while reinfer():
515
+ pass
516
+
517
+ if verbose:
518
+ for entry in inferred:
519
+ message(entry.pos, "inferred '%s' to be of type '%s'" % (
520
+ entry.name, entry.type))
521
+
522
+
523
+ def find_spanning_type(type1, type2):
524
+ if type1 is type2:
525
+ result_type = type1
526
+ elif type1 is PyrexTypes.c_bint_type or type2 is PyrexTypes.c_bint_type:
527
+ # type inference can break the coercion back to a Python bool
528
+ # if it returns an arbitrary int type here
529
+ return py_object_type
530
+ else:
531
+ result_type = PyrexTypes.spanning_type(type1, type2)
532
+ if result_type in (PyrexTypes.c_double_type, PyrexTypes.c_float_type,
533
+ Builtin.float_type):
534
+ # Python's float type is just a C double, so it's safe to
535
+ # use the C type instead
536
+ return PyrexTypes.c_double_type
537
+ return result_type
538
+
539
+ def simply_type(result_type):
540
+ result_type = PyrexTypes.remove_cv_ref(result_type, remove_fakeref=True)
541
+ if result_type.is_array:
542
+ result_type = PyrexTypes.c_ptr_type(result_type.base_type)
543
+ return result_type
544
+
545
+ def aggressive_spanning_type(types, might_overflow, scope):
546
+ return simply_type(reduce(find_spanning_type, types))
547
+
548
+ def safe_spanning_type(types, might_overflow, scope):
549
+ result_type = simply_type(reduce(find_spanning_type, types))
550
+ if result_type.is_pyobject:
551
+ return result_type
552
+ elif (result_type is PyrexTypes.c_double_type or
553
+ result_type is PyrexTypes.c_float_type):
554
+ # Python's float type is just a C double, so it's safe to use
555
+ # the C type instead. Similarly if given a C float, it leads to
556
+ # a small loss of precision vs Python but is otherwise the same
557
+ return result_type
558
+ elif result_type is PyrexTypes.c_bint_type:
559
+ # find_spanning_type() only returns 'bint' for clean boolean
560
+ # operations without other int types, so this is safe, too
561
+ return result_type
562
+ elif result_type.is_pythran_expr:
563
+ return result_type
564
+ elif result_type.is_ptr:
565
+ # Any pointer except (signed|unsigned|) char* can't implicitly
566
+ # become a PyObject, and inferring char* is now accepted, too.
567
+ return result_type
568
+ elif result_type.is_cpp_class:
569
+ # These can't implicitly become Python objects either.
570
+ return result_type
571
+ elif result_type.is_struct:
572
+ # Though we have struct -> object for some structs, this is uncommonly
573
+ # used, won't arise in pure Python, and there shouldn't be side
574
+ # effects, so I'm declaring this safe.
575
+ return result_type
576
+ elif result_type.is_memoryviewslice:
577
+ return result_type
578
+ elif result_type is PyrexTypes.soft_complex_type:
579
+ return result_type
580
+ elif result_type == PyrexTypes.c_double_complex_type:
581
+ return result_type
582
+ elif (result_type.is_int or result_type.is_enum) and not might_overflow:
583
+ return result_type
584
+ elif (not result_type.can_coerce_to_pyobject(scope)
585
+ and not result_type.is_error):
586
+ return result_type
587
+ return py_object_type
588
+
589
+
590
+ def get_type_inferer():
591
+ return SimpleAssignmentTypeInferer()