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,905 @@
1
+ from .Errors import CompileError, error
2
+ from . import ExprNodes
3
+ from .ExprNodes import IntNode, NameNode, AttributeNode
4
+ from . import Options
5
+ from .. import Utils
6
+ from .Code import UtilityCode, TempitaUtilityCode
7
+ from .UtilityCode import CythonUtilityCode, CythonSharedUtilityCode
8
+ from . import Buffer
9
+ from . import Naming
10
+ from . import PyrexTypes
11
+
12
+ START_ERR = "Start must not be given."
13
+ STOP_ERR = "Axis specification only allowed in the 'step' slot."
14
+ STEP_ERR = "Step must be omitted, 1, or a valid specifier."
15
+ BOTH_CF_ERR = "Cannot specify an array that is both C and Fortran contiguous."
16
+ INVALID_ERR = "Invalid axis specification."
17
+ NOT_CIMPORTED_ERR = "Variable was not cimported from cython.view"
18
+ EXPR_ERR = "no expressions allowed in axis spec, only names and literals."
19
+ CF_ERR = "Invalid axis specification for a C/Fortran contiguous array."
20
+ ERR_UNINITIALIZED = ("Cannot check if memoryview %s is initialized without the "
21
+ "GIL, consider using initializedcheck(False)")
22
+
23
+
24
+ format_flag = "PyBUF_FORMAT"
25
+
26
+ memview_c_contiguous = "(PyBUF_C_CONTIGUOUS | PyBUF_FORMAT)"
27
+ memview_f_contiguous = "(PyBUF_F_CONTIGUOUS | PyBUF_FORMAT)"
28
+ memview_any_contiguous = "(PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT)"
29
+ memview_full_access = "PyBUF_FULL_RO"
30
+ memview_strided_access = "PyBUF_RECORDS_RO"
31
+
32
+ MEMVIEW_DIRECT = '__Pyx_MEMVIEW_DIRECT'
33
+ MEMVIEW_PTR = '__Pyx_MEMVIEW_PTR'
34
+ MEMVIEW_FULL = '__Pyx_MEMVIEW_FULL'
35
+ MEMVIEW_CONTIG = '__Pyx_MEMVIEW_CONTIG'
36
+ MEMVIEW_STRIDED= '__Pyx_MEMVIEW_STRIDED'
37
+ MEMVIEW_FOLLOW = '__Pyx_MEMVIEW_FOLLOW'
38
+
39
+ _spec_to_const = {
40
+ 'direct' : MEMVIEW_DIRECT,
41
+ 'ptr' : MEMVIEW_PTR,
42
+ 'full' : MEMVIEW_FULL,
43
+ 'contig' : MEMVIEW_CONTIG,
44
+ 'strided': MEMVIEW_STRIDED,
45
+ 'follow' : MEMVIEW_FOLLOW,
46
+ }
47
+
48
+ _spec_to_abbrev = {
49
+ 'direct' : 'd',
50
+ 'ptr' : 'p',
51
+ 'full' : 'f',
52
+ 'contig' : 'c',
53
+ 'strided' : 's',
54
+ 'follow' : '_',
55
+ }
56
+
57
+
58
+ def put_init_entry(mv_cname, code):
59
+ code.putln("%s.data = NULL;" % mv_cname)
60
+ code.putln("%s.memview = NULL;" % mv_cname)
61
+
62
+
63
+ #def axes_to_str(axes):
64
+ # return "".join([access[0].upper()+packing[0] for (access, packing) in axes])
65
+
66
+
67
+ def put_acquire_memoryviewslice(lhs_cname, lhs_type, lhs_pos, rhs, code,
68
+ have_gil=False, first_assignment=True):
69
+ "We can avoid decreffing the lhs if we know it is the first assignment"
70
+ assert rhs.type.is_memoryviewslice
71
+
72
+ pretty_rhs = rhs.result_in_temp() or rhs.is_simple()
73
+ if pretty_rhs:
74
+ rhstmp = rhs.result()
75
+ else:
76
+ rhstmp = code.funcstate.allocate_temp(lhs_type, manage_ref=False)
77
+ code.putln("%s = %s;" % (rhstmp, rhs.result_as(lhs_type)))
78
+
79
+ # Allow uninitialized assignment
80
+ #code.putln(code.put_error_if_unbound(lhs_pos, rhs.entry))
81
+ put_assign_to_memviewslice(lhs_cname, rhs, rhstmp, lhs_type, code,
82
+ have_gil=have_gil, first_assignment=first_assignment)
83
+
84
+ if not pretty_rhs:
85
+ code.funcstate.release_temp(rhstmp)
86
+
87
+
88
+ def put_assign_to_memviewslice(lhs_cname, rhs, rhs_cname, memviewslicetype, code,
89
+ have_gil=False, first_assignment=False):
90
+ if lhs_cname == rhs_cname:
91
+ # self assignment is tricky because memoryview xdecref clears the memoryview
92
+ # thus invalidating both sides of the assignment. Therefore make it actually do nothing
93
+ code.putln("/* memoryview self assignment no-op */")
94
+ return
95
+
96
+ if not first_assignment:
97
+ code.put_xdecref(lhs_cname, memviewslicetype,
98
+ have_gil=have_gil)
99
+
100
+ if not rhs.result_in_temp():
101
+ rhs.make_owned_memoryviewslice(code)
102
+
103
+ code.putln("%s = %s;" % (lhs_cname, rhs_cname))
104
+
105
+
106
+ def get_buf_flags(specs):
107
+ is_c_contig, is_f_contig = is_cf_contig(specs)
108
+
109
+ if is_c_contig:
110
+ return memview_c_contiguous
111
+ elif is_f_contig:
112
+ return memview_f_contiguous
113
+
114
+ access, packing = zip(*specs)
115
+
116
+ if 'full' in access or 'ptr' in access:
117
+ return memview_full_access
118
+ else:
119
+ return memview_strided_access
120
+
121
+
122
+ def insert_newaxes(memoryviewtype, n):
123
+ axes = [('direct', 'strided')] * n
124
+ axes.extend(memoryviewtype.axes)
125
+ return PyrexTypes.MemoryViewSliceType(memoryviewtype.dtype, axes)
126
+
127
+
128
+ def broadcast_types(src, dst):
129
+ n = abs(src.ndim - dst.ndim)
130
+ if src.ndim < dst.ndim:
131
+ return insert_newaxes(src, n), dst
132
+ else:
133
+ return src, insert_newaxes(dst, n)
134
+
135
+
136
+ def valid_memslice_dtype(dtype, i=0):
137
+ """
138
+ Return whether type dtype can be used as the base type of a
139
+ memoryview slice.
140
+
141
+ We support structs, numeric types and objects
142
+ """
143
+ if dtype.is_complex and dtype.real_type.is_int:
144
+ return False
145
+
146
+ if dtype is PyrexTypes.c_bint_type:
147
+ return False
148
+
149
+ if dtype.is_struct and dtype.kind == 'struct':
150
+ for member in dtype.scope.var_entries:
151
+ if not valid_memslice_dtype(member.type):
152
+ return False
153
+
154
+ return True
155
+
156
+ return (
157
+ dtype.is_error or
158
+ # Pointers are not valid (yet)
159
+ # (dtype.is_ptr and valid_memslice_dtype(dtype.base_type)) or
160
+ (dtype.is_array and i < 8 and
161
+ valid_memslice_dtype(dtype.base_type, i + 1)) or
162
+ dtype.is_numeric or
163
+ dtype.is_pyobject or
164
+ dtype.is_fused or # accept this as it will be replaced by specializations later
165
+ (dtype.is_typedef and valid_memslice_dtype(dtype.typedef_base_type))
166
+ )
167
+
168
+
169
+ class MemoryViewSliceBufferEntry(Buffer.BufferEntry):
170
+ """
171
+ May be used during code generation time to be queried for
172
+ shape/strides/suboffsets attributes, or to perform indexing or slicing.
173
+ """
174
+ def __init__(self, entry):
175
+ self.entry = entry
176
+ self.type = entry.type
177
+ self.cname = entry.cname
178
+
179
+ self.buf_ptr = "%s.data" % self.cname
180
+
181
+ dtype = self.entry.type.dtype
182
+ self.buf_ptr_type = PyrexTypes.CPtrType(dtype)
183
+ self.init_attributes()
184
+
185
+ def get_buf_suboffsetvars(self):
186
+ return self._for_all_ndim("%s.suboffsets[%d]")
187
+
188
+ def get_buf_stridevars(self):
189
+ return self._for_all_ndim("%s.strides[%d]")
190
+
191
+ def get_buf_shapevars(self):
192
+ return self._for_all_ndim("%s.shape[%d]")
193
+
194
+ def generate_buffer_lookup_code(self, code, index_cnames):
195
+ axes = [(dim, index_cnames[dim], access, packing)
196
+ for dim, (access, packing) in enumerate(self.type.axes)]
197
+ return self._generate_buffer_lookup_code(code, axes)
198
+
199
+ def _generate_buffer_lookup_code(self, code, axes, cast_result=True):
200
+ """
201
+ Generate a single expression that indexes the memory view slice
202
+ in each dimension.
203
+ """
204
+ bufp = self.buf_ptr
205
+ type_decl = self.type.dtype.empty_declaration_code()
206
+
207
+ for dim, index, access, packing in axes:
208
+ shape = "%s.shape[%d]" % (self.cname, dim)
209
+ stride = "%s.strides[%d]" % (self.cname, dim)
210
+ suboffset = "%s.suboffsets[%d]" % (self.cname, dim)
211
+
212
+ flag = get_memoryview_flag(access, packing)
213
+
214
+ if flag in ("generic", "generic_contiguous"):
215
+ # Note: we cannot do cast tricks to avoid stride multiplication
216
+ # for generic_contiguous, as we may have to do (dtype *)
217
+ # or (dtype **) arithmetic, we won't know which unless
218
+ # we check suboffsets
219
+ code.globalstate.use_utility_code(memviewslice_index_helpers)
220
+ bufp = ('__pyx_memviewslice_index_full(%s, %s, %s, %s)' %
221
+ (bufp, index, stride, suboffset))
222
+
223
+ elif flag == "indirect":
224
+ bufp = "(%s + %s * %s)" % (bufp, index, stride)
225
+ bufp = ("(*((char **) %s) + %s)" % (bufp, suboffset))
226
+
227
+ elif flag == "indirect_contiguous":
228
+ # Note: we do char ** arithmetic
229
+ bufp = "(*((char **) %s + %s) + %s)" % (bufp, index, suboffset)
230
+
231
+ elif flag == "strided":
232
+ bufp = "(%s + %s * %s)" % (bufp, index, stride)
233
+
234
+ else:
235
+ assert flag == 'contiguous', flag
236
+ bufp = '((char *) (((%s *) %s) + %s))' % (type_decl, bufp, index)
237
+
238
+ bufp = '( /* dim=%d */ %s )' % (dim, bufp)
239
+
240
+ if cast_result:
241
+ return "((%s *) %s)" % (type_decl, bufp)
242
+
243
+ return bufp
244
+
245
+ def generate_buffer_slice_code(self, code, indices, dst, dst_type, have_gil,
246
+ have_slices, directives):
247
+ """
248
+ Slice a memoryviewslice.
249
+
250
+ indices - list of index nodes. If not a SliceNode, or NoneNode,
251
+ then it must be coercible to Py_ssize_t
252
+
253
+ Simply call __pyx_memoryview_slice_memviewslice with the right
254
+ arguments, unless the dimension is omitted or a bare ':', in which
255
+ case we copy over the shape/strides/suboffsets attributes directly
256
+ for that dimension.
257
+ """
258
+ src = self.cname
259
+
260
+ code.putln("%(dst)s.data = %(src)s.data;" % locals())
261
+ code.putln("%(dst)s.memview = %(src)s.memview;" % locals())
262
+ code.put_incref_memoryviewslice(dst, dst_type, have_gil=have_gil)
263
+
264
+ all_dimensions_direct = all(access == 'direct' for access, packing in self.type.axes)
265
+ suboffset_dim_temp = []
266
+
267
+ def get_suboffset_dim():
268
+ # create global temp variable at request
269
+ if not suboffset_dim_temp:
270
+ suboffset_dim = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
271
+ code.putln("%s = -1;" % suboffset_dim)
272
+ suboffset_dim_temp.append(suboffset_dim)
273
+ return suboffset_dim_temp[0]
274
+
275
+ dim = -1
276
+ new_ndim = 0
277
+ for index in indices:
278
+ if index.is_none:
279
+ # newaxis
280
+ for attrib, value in [('shape', 1), ('strides', 0), ('suboffsets', -1)]:
281
+ code.putln("%s.%s[%d] = %d;" % (dst, attrib, new_ndim, value))
282
+
283
+ new_ndim += 1
284
+ continue
285
+
286
+ dim += 1
287
+ access, packing = self.type.axes[dim]
288
+
289
+ if index.is_slice:
290
+ # slice, unspecified dimension, or part of ellipsis
291
+ d = dict(locals())
292
+ for s in "start stop step".split():
293
+ idx = getattr(index, s)
294
+ have_idx = d['have_' + s] = not idx.is_none
295
+ d[s] = idx.result() if have_idx else "0"
296
+
297
+ if not (d['have_start'] or d['have_stop'] or d['have_step']):
298
+ # full slice (:), simply copy over the extent, stride
299
+ # and suboffset. Also update suboffset_dim if needed
300
+ d['access'] = access
301
+ util_name = "SimpleSlice"
302
+ else:
303
+ util_name = "ToughSlice"
304
+ d['error_goto'] = code.error_goto(index.pos)
305
+
306
+ new_ndim += 1
307
+ else:
308
+ # normal index
309
+ idx = index.result()
310
+
311
+ indirect = access != 'direct'
312
+ if indirect:
313
+ generic = access == 'full'
314
+ if new_ndim != 0:
315
+ return error(index.pos,
316
+ "All preceding dimensions must be "
317
+ "indexed and not sliced")
318
+
319
+ d = dict(
320
+ locals(),
321
+ wraparound=int(directives['wraparound']),
322
+ boundscheck=int(directives['boundscheck']),
323
+ )
324
+ if d['boundscheck']:
325
+ d['error_goto'] = code.error_goto(index.pos)
326
+ util_name = "SliceIndex"
327
+
328
+ _, impl = TempitaUtilityCode.load_as_string(util_name, "MemoryView_C.c", context=d)
329
+ code.put(impl)
330
+
331
+ if suboffset_dim_temp:
332
+ code.funcstate.release_temp(suboffset_dim_temp[0])
333
+
334
+
335
+ def empty_slice(pos):
336
+ none = ExprNodes.NoneNode(pos)
337
+ return ExprNodes.SliceNode(pos, start=none,
338
+ stop=none, step=none)
339
+
340
+
341
+ def unellipsify(indices, ndim):
342
+ result = []
343
+ seen_ellipsis = False
344
+ have_slices = False
345
+
346
+ newaxes = [newaxis for newaxis in indices if newaxis.is_none]
347
+ n_indices = len(indices) - len(newaxes)
348
+
349
+ for index in indices:
350
+ if isinstance(index, ExprNodes.EllipsisNode):
351
+ have_slices = True
352
+ full_slice = empty_slice(index.pos)
353
+
354
+ if seen_ellipsis:
355
+ result.append(full_slice)
356
+ else:
357
+ nslices = ndim - n_indices + 1
358
+ result.extend([full_slice] * nslices)
359
+ seen_ellipsis = True
360
+ else:
361
+ have_slices = have_slices or index.is_slice or index.is_none
362
+ result.append(index)
363
+
364
+ result_length = len(result) - len(newaxes)
365
+ if result_length < ndim:
366
+ have_slices = True
367
+ nslices = ndim - result_length
368
+ result.extend([empty_slice(indices[-1].pos)] * nslices)
369
+
370
+ return have_slices, result, newaxes
371
+
372
+
373
+ def get_memoryview_flag(access, packing):
374
+ if access == 'full' and packing in ('strided', 'follow'):
375
+ return 'generic'
376
+ elif access == 'full' and packing == 'contig':
377
+ return 'generic_contiguous'
378
+ elif access == 'ptr' and packing in ('strided', 'follow'):
379
+ return 'indirect'
380
+ elif access == 'ptr' and packing == 'contig':
381
+ return 'indirect_contiguous'
382
+ elif access == 'direct' and packing in ('strided', 'follow'):
383
+ return 'strided'
384
+ else:
385
+ assert (access, packing) == ('direct', 'contig'), (access, packing)
386
+ return 'contiguous'
387
+
388
+
389
+ def get_is_contig_func_name(contig_type, ndim):
390
+ assert contig_type in ('C', 'F')
391
+ return "__pyx_memviewslice_is_contig_%s%d" % (contig_type, ndim)
392
+
393
+
394
+ def get_is_contig_utility(contig_type, ndim):
395
+ assert contig_type in ('C', 'F')
396
+ C = dict(template_context, ndim=ndim, contig_type=contig_type)
397
+ utility = load_memview_c_utility("MemviewSliceCheckContig", context=C,
398
+ requires=[is_contig_utility])
399
+ return utility
400
+
401
+
402
+ def slice_iter(slice_type, slice_result, ndim, code, force_strided=False):
403
+ if (slice_type.is_c_contig or slice_type.is_f_contig) and not force_strided:
404
+ return ContigSliceIter(slice_type, slice_result, ndim, code)
405
+ else:
406
+ return StridedSliceIter(slice_type, slice_result, ndim, code)
407
+
408
+
409
+ class SliceIter:
410
+ def __init__(self, slice_type, slice_result, ndim, code):
411
+ self.slice_type = slice_type
412
+ self.slice_result = slice_result
413
+ self.code = code
414
+ self.ndim = ndim
415
+
416
+
417
+ class ContigSliceIter(SliceIter):
418
+ def start_loops(self):
419
+ code = self.code
420
+ code.begin_block()
421
+
422
+ type_decl = self.slice_type.dtype.empty_declaration_code()
423
+
424
+ total_size = ' * '.join("%s.shape[%d]" % (self.slice_result, i)
425
+ for i in range(self.ndim))
426
+ code.putln("Py_ssize_t __pyx_temp_extent = %s;" % total_size)
427
+ code.putln("Py_ssize_t __pyx_temp_idx;")
428
+ code.putln("%s *__pyx_temp_pointer = (%s *) %s.data;" % (
429
+ type_decl, type_decl, self.slice_result))
430
+ code.putln("for (__pyx_temp_idx = 0; "
431
+ "__pyx_temp_idx < __pyx_temp_extent; "
432
+ "__pyx_temp_idx++) {")
433
+
434
+ return "__pyx_temp_pointer"
435
+
436
+ def end_loops(self):
437
+ self.code.putln("__pyx_temp_pointer += 1;")
438
+ self.code.putln("}")
439
+ self.code.end_block()
440
+
441
+
442
+ class StridedSliceIter(SliceIter):
443
+ def start_loops(self):
444
+ code = self.code
445
+ code.begin_block()
446
+
447
+ for i in range(self.ndim):
448
+ t = i, self.slice_result, i
449
+ code.putln("Py_ssize_t __pyx_temp_extent_%d = %s.shape[%d];" % t)
450
+ code.putln("Py_ssize_t __pyx_temp_stride_%d = %s.strides[%d];" % t)
451
+ code.putln("char *__pyx_temp_pointer_%d;" % i)
452
+ code.putln("Py_ssize_t __pyx_temp_idx_%d;" % i)
453
+
454
+ code.putln("__pyx_temp_pointer_0 = %s.data;" % self.slice_result)
455
+
456
+ for i in range(self.ndim):
457
+ if i > 0:
458
+ code.putln("__pyx_temp_pointer_%d = __pyx_temp_pointer_%d;" % (i, i - 1))
459
+
460
+ code.putln("for (__pyx_temp_idx_%d = 0; "
461
+ "__pyx_temp_idx_%d < __pyx_temp_extent_%d; "
462
+ "__pyx_temp_idx_%d++) {" % (i, i, i, i))
463
+
464
+ return "__pyx_temp_pointer_%d" % (self.ndim - 1)
465
+
466
+ def end_loops(self):
467
+ code = self.code
468
+ for i in range(self.ndim - 1, -1, -1):
469
+ code.putln("__pyx_temp_pointer_%d += __pyx_temp_stride_%d;" % (i, i))
470
+ code.putln("}")
471
+
472
+ code.end_block()
473
+
474
+
475
+ def copy_c_or_fortran_cname(memview):
476
+ if memview.is_c_contig:
477
+ c_or_f = 'c'
478
+ else:
479
+ c_or_f = 'f'
480
+
481
+ return "__pyx_memoryview_copy_slice_%s_%s" % (
482
+ memview.specialization_suffix(), c_or_f)
483
+
484
+
485
+ def get_copy_new_utility(pos, from_memview, to_memview):
486
+ if (from_memview.dtype != to_memview.dtype and
487
+ not (from_memview.dtype.is_cv_qualified and from_memview.dtype.cv_base_type == to_memview.dtype)):
488
+ error(pos, "dtypes must be the same!")
489
+ return
490
+ if len(from_memview.axes) != len(to_memview.axes):
491
+ error(pos, "number of dimensions must be same")
492
+ return
493
+ if not (to_memview.is_c_contig or to_memview.is_f_contig):
494
+ error(pos, "to_memview must be c or f contiguous.")
495
+ return
496
+
497
+ for (access, packing) in from_memview.axes:
498
+ if access != 'direct':
499
+ error(pos, "cannot handle 'full' or 'ptr' access at this time.")
500
+ return
501
+
502
+ if to_memview.is_c_contig:
503
+ mode = 'c'
504
+ contig_flag = memview_c_contiguous
505
+ else:
506
+ assert to_memview.is_f_contig
507
+ mode = 'fortran'
508
+ contig_flag = memview_f_contiguous
509
+
510
+ return load_memview_c_utility(
511
+ "CopyContentsUtility",
512
+ context=dict(
513
+ template_context,
514
+ mode=mode,
515
+ dtype_decl=to_memview.dtype.empty_declaration_code(),
516
+ contig_flag=contig_flag,
517
+ ndim=to_memview.ndim,
518
+ func_cname=copy_c_or_fortran_cname(to_memview),
519
+ dtype_is_object=int(to_memview.dtype.is_pyobject),
520
+ ),
521
+ requires=[copy_contents_new_utility],
522
+ )
523
+
524
+
525
+ def get_axes_specs(env, axes):
526
+ '''
527
+ get_axes_specs(env, axes) -> list of (access, packing) specs for each axis.
528
+ access is one of 'full', 'ptr' or 'direct'
529
+ packing is one of 'contig', 'strided' or 'follow'
530
+ '''
531
+
532
+ cythonscope = env.context.cython_scope
533
+ cythonscope.load_cythonscope()
534
+ viewscope = cythonscope.viewscope
535
+
536
+ access_specs = tuple([viewscope.lookup(name)
537
+ for name in ('full', 'direct', 'ptr')])
538
+ packing_specs = tuple([viewscope.lookup(name)
539
+ for name in ('contig', 'strided', 'follow')])
540
+
541
+ is_f_contig, is_c_contig = False, False
542
+ default_access, default_packing = 'direct', 'strided'
543
+ cf_access, cf_packing = default_access, 'follow'
544
+
545
+ axes_specs = []
546
+ # analyse all axes.
547
+ for idx, axis in enumerate(axes):
548
+ if not axis.start.is_none:
549
+ raise CompileError(axis.start.pos, START_ERR)
550
+
551
+ if not axis.stop.is_none:
552
+ raise CompileError(axis.stop.pos, STOP_ERR)
553
+
554
+ if axis.step.is_none:
555
+ axes_specs.append((default_access, default_packing))
556
+
557
+ elif isinstance(axis.step, IntNode):
558
+ # the packing for the ::1 axis is contiguous,
559
+ # all others are cf_packing.
560
+ if axis.step.compile_time_value(env) != 1:
561
+ raise CompileError(axis.step.pos, STEP_ERR)
562
+
563
+ axes_specs.append((cf_access, 'cfcontig'))
564
+
565
+ elif isinstance(axis.step, (NameNode, AttributeNode)):
566
+ entry = _get_resolved_spec(env, axis.step)
567
+ if entry.name in view_constant_to_access_packing:
568
+ axes_specs.append(view_constant_to_access_packing[entry.name])
569
+ else:
570
+ raise CompileError(axis.step.pos, INVALID_ERR)
571
+
572
+ else:
573
+ raise CompileError(axis.step.pos, INVALID_ERR)
574
+
575
+ # First, find out if we have a ::1 somewhere
576
+ contig_dim = 0
577
+ is_contig = False
578
+ for idx, (access, packing) in enumerate(axes_specs):
579
+ if packing == 'cfcontig':
580
+ if is_contig:
581
+ raise CompileError(axis.step.pos, BOTH_CF_ERR)
582
+
583
+ contig_dim = idx
584
+ axes_specs[idx] = (access, 'contig')
585
+ is_contig = True
586
+
587
+ if is_contig:
588
+ # We have a ::1 somewhere, see if we're C or Fortran contiguous
589
+ if contig_dim == len(axes) - 1:
590
+ is_c_contig = True
591
+ else:
592
+ is_f_contig = True
593
+
594
+ if contig_dim and not axes_specs[contig_dim - 1][0] in ('full', 'ptr'):
595
+ raise CompileError(axes[contig_dim].pos,
596
+ "Fortran contiguous specifier must follow an indirect dimension")
597
+
598
+ if is_c_contig:
599
+ # Contiguous in the last dimension, find the last indirect dimension
600
+ contig_dim = -1
601
+ for idx, (access, packing) in enumerate(reversed(axes_specs)):
602
+ if access in ('ptr', 'full'):
603
+ contig_dim = len(axes) - idx - 1
604
+
605
+ # Replace 'strided' with 'follow' for any dimension following the last
606
+ # indirect dimension, the first dimension or the dimension following
607
+ # the ::1.
608
+ # int[::indirect, ::1, :, :]
609
+ # ^ ^
610
+ # int[::indirect, :, :, ::1]
611
+ # ^ ^
612
+ start = contig_dim + 1
613
+ stop = len(axes) - is_c_contig
614
+ for idx, (access, packing) in enumerate(axes_specs[start:stop]):
615
+ idx = contig_dim + 1 + idx
616
+ if access != 'direct':
617
+ raise CompileError(axes[idx].pos,
618
+ "Indirect dimension may not follow "
619
+ "Fortran contiguous dimension")
620
+ if packing == 'contig':
621
+ raise CompileError(axes[idx].pos,
622
+ "Dimension may not be contiguous")
623
+ axes_specs[idx] = (access, cf_packing)
624
+
625
+ if is_c_contig:
626
+ # For C contiguity, we need to fix the 'contig' dimension
627
+ # after the loop
628
+ a, p = axes_specs[-1]
629
+ axes_specs[-1] = a, 'contig'
630
+
631
+ validate_axes_specs([axis.start.pos for axis in axes],
632
+ axes_specs,
633
+ is_c_contig,
634
+ is_f_contig)
635
+
636
+ return axes_specs
637
+
638
+
639
+ def validate_axes(pos, axes):
640
+ if len(axes) >= Options.buffer_max_dims:
641
+ error(pos, "More dimensions than the maximum number"
642
+ " of buffer dimensions were used.")
643
+ return False
644
+
645
+ return True
646
+
647
+
648
+ def is_cf_contig(specs):
649
+ is_c_contig = is_f_contig = False
650
+
651
+ if len(specs) == 1 and specs == [('direct', 'contig')]:
652
+ is_c_contig = True
653
+
654
+ elif (specs[-1] == ('direct','contig') and
655
+ all(axis == ('direct','follow') for axis in specs[:-1])):
656
+ # c_contiguous: 'follow', 'follow', ..., 'follow', 'contig'
657
+ is_c_contig = True
658
+
659
+ elif (len(specs) > 1 and
660
+ specs[0] == ('direct','contig') and
661
+ all(axis == ('direct','follow') for axis in specs[1:])):
662
+ # f_contiguous: 'contig', 'follow', 'follow', ..., 'follow'
663
+ is_f_contig = True
664
+
665
+ return is_c_contig, is_f_contig
666
+
667
+
668
+ def get_mode(specs):
669
+ is_c_contig, is_f_contig = is_cf_contig(specs)
670
+
671
+ if is_c_contig:
672
+ return 'c'
673
+ elif is_f_contig:
674
+ return 'fortran'
675
+
676
+ for access, packing in specs:
677
+ if access in ('ptr', 'full'):
678
+ return 'full'
679
+
680
+ return 'strided'
681
+
682
+ view_constant_to_access_packing = {
683
+ 'generic': ('full', 'strided'),
684
+ 'strided': ('direct', 'strided'),
685
+ 'indirect': ('ptr', 'strided'),
686
+ 'generic_contiguous': ('full', 'contig'),
687
+ 'contiguous': ('direct', 'contig'),
688
+ 'indirect_contiguous': ('ptr', 'contig'),
689
+ }
690
+
691
+ def validate_axes_specs(positions, specs, is_c_contig, is_f_contig):
692
+
693
+ packing_specs = ('contig', 'strided', 'follow')
694
+ access_specs = ('direct', 'ptr', 'full')
695
+
696
+ # is_c_contig, is_f_contig = is_cf_contig(specs)
697
+
698
+ has_contig = has_follow = has_strided = has_generic_contig = False
699
+
700
+ last_indirect_dimension = -1
701
+ for idx, (access, packing) in enumerate(specs):
702
+ if access == 'ptr':
703
+ last_indirect_dimension = idx
704
+
705
+ for idx, (pos, (access, packing)) in enumerate(zip(positions, specs)):
706
+
707
+ if not (access in access_specs and
708
+ packing in packing_specs):
709
+ raise CompileError(pos, "Invalid axes specification.")
710
+
711
+ if packing == 'strided':
712
+ has_strided = True
713
+ elif packing == 'contig':
714
+ if has_contig:
715
+ raise CompileError(pos, "Only one direct contiguous "
716
+ "axis may be specified.")
717
+
718
+ valid_contig_dims = last_indirect_dimension + 1, len(specs) - 1
719
+ if idx not in valid_contig_dims and access != 'ptr':
720
+ if last_indirect_dimension + 1 != len(specs) - 1:
721
+ dims = "dimensions %d and %d" % valid_contig_dims
722
+ else:
723
+ dims = "dimension %d" % valid_contig_dims[0]
724
+
725
+ raise CompileError(pos, "Only %s may be contiguous and direct" % dims)
726
+
727
+ has_contig = access != 'ptr'
728
+ elif packing == 'follow':
729
+ if has_strided:
730
+ raise CompileError(pos, "A memoryview cannot have both follow and strided axis specifiers.")
731
+ if not (is_c_contig or is_f_contig):
732
+ raise CompileError(pos, "Invalid use of the follow specifier.")
733
+
734
+ if access in ('ptr', 'full'):
735
+ has_strided = False
736
+
737
+ def _get_resolved_spec(env, spec):
738
+ # spec must be a NameNode or an AttributeNode
739
+ if isinstance(spec, NameNode):
740
+ return _resolve_NameNode(env, spec)
741
+ elif isinstance(spec, AttributeNode):
742
+ return _resolve_AttributeNode(env, spec)
743
+ else:
744
+ raise CompileError(spec.pos, INVALID_ERR)
745
+
746
+ def _resolve_NameNode(env, node):
747
+ try:
748
+ resolved_name = env.lookup(node.name).name
749
+ except AttributeError:
750
+ raise CompileError(node.pos, INVALID_ERR)
751
+
752
+ viewscope = env.context.cython_scope.viewscope
753
+ entry = viewscope.lookup(resolved_name)
754
+ if entry is None:
755
+ raise CompileError(node.pos, NOT_CIMPORTED_ERR)
756
+
757
+ return entry
758
+
759
+ def _resolve_AttributeNode(env, node):
760
+ path = []
761
+ while isinstance(node, AttributeNode):
762
+ path.insert(0, node.attribute)
763
+ node = node.obj
764
+ if isinstance(node, NameNode):
765
+ path.insert(0, node.name)
766
+ else:
767
+ raise CompileError(node.pos, EXPR_ERR)
768
+ modnames = path[:-1]
769
+ # must be at least 1 module name, o/w not an AttributeNode.
770
+ assert modnames
771
+
772
+ scope = env
773
+ for modname in modnames:
774
+ mod = scope.lookup(modname)
775
+ if not mod or not mod.as_module:
776
+ raise CompileError(
777
+ node.pos, "undeclared name not builtin: %s" % modname)
778
+ scope = mod.as_module
779
+
780
+ entry = scope.lookup(path[-1])
781
+ if not entry:
782
+ raise CompileError(node.pos, "No such attribute '%s'" % path[-1])
783
+
784
+ return entry
785
+
786
+ #
787
+ ### Utility loading
788
+ #
789
+
790
+ def load_memview_cy_utility(util_code_name, context=None, **kwargs):
791
+ return CythonUtilityCode.load(util_code_name, "MemoryView.pyx",
792
+ context=context, **kwargs)
793
+
794
+ def load_memview_c_utility(
795
+ util_code_name, util_code_filename="MemoryView_C.c",
796
+ *,
797
+ context=None, **kwargs):
798
+ if context is None:
799
+ return UtilityCode.load(util_code_name, util_code_filename, **kwargs)
800
+ else:
801
+ return TempitaUtilityCode.load(util_code_name, util_code_filename,
802
+ context=context, **kwargs)
803
+
804
+ def use_cython_array_utility_code(env):
805
+ if env.context.shared_utility_qualified_name:
806
+ return
807
+ cython_scope = env.context.cython_scope
808
+ cython_scope.load_cythonscope()
809
+ cython_scope.viewscope.lookup('array_cwrapper').used = True
810
+
811
+ template_context = {
812
+ 'max_dims': Options.buffer_max_dims,
813
+ 'memviewslice_name': Naming.memviewslice_cname,
814
+ 'memslice_init': PyrexTypes.MemoryViewSliceType.default_value,
815
+ 'THREAD_LOCKS_PREALLOCATED': 8,
816
+ }
817
+
818
+ def _get_memviewslice_declare_code():
819
+ memviewslice_declare_code = load_memview_c_utility(
820
+ "MemviewSliceStruct",
821
+ context=template_context,
822
+ requires=[])
823
+ return memviewslice_declare_code
824
+
825
+ atomic_utility = load_memview_c_utility(
826
+ "Atomics", util_code_filename="Synchronization.c", context=template_context)
827
+
828
+ memviewslice_index_helpers = load_memview_c_utility("MemviewSliceIndex")
829
+
830
+ def _get_typeinfo_to_format_code():
831
+ return load_memview_cy_utility(
832
+ "BufferFormatFromTypeInfo", requires=[Buffer._typeinfo_to_format_code])
833
+
834
+ def get_typeinfo_to_format_code(shared_utility_qualified_name):
835
+ if shared_utility_qualified_name:
836
+ return CythonSharedUtilityCode(
837
+ 'BufferFormatFromTypeInfo.pxd',
838
+ shared_utility_qualified_name,
839
+ template_context=template_context,
840
+ requires=[])
841
+ else:
842
+ return _get_typeinfo_to_format_code()
843
+
844
+
845
+ is_contig_utility = load_memview_c_utility("MemviewSliceIsContig")
846
+ overlapping_utility = load_memview_c_utility("OverlappingSlices")
847
+ refcount_utility = load_memview_c_utility("MemviewRefcount")
848
+ slice_init_utility = load_memview_c_utility("MemviewSliceInit")
849
+ memviewslice_declare_code = load_memview_c_utility("MemviewSliceStruct", context=template_context)
850
+
851
+ copy_contents_new_utility = load_memview_c_utility(
852
+ "MemviewSliceCopyTemplate",
853
+ context=template_context,
854
+ # Requires general memoryview code - dependency is added below.
855
+ )
856
+
857
+
858
+ @Utils.cached_function
859
+ def _get_memoryview_utility_code():
860
+ memoryview_utility_code = load_memview_cy_utility(
861
+ "View.MemoryView",
862
+ context=template_context,
863
+ requires=[
864
+ Buffer.buffer_struct_declare_code,
865
+ Buffer.buffer_formats_declare_code,
866
+ memviewslice_declare_code,
867
+ refcount_utility,
868
+ atomic_utility,
869
+ is_contig_utility,
870
+ overlapping_utility,
871
+ copy_contents_new_utility,
872
+ ],
873
+ )
874
+
875
+ return memoryview_utility_code
876
+
877
+
878
+ @Utils.cached_function
879
+ def _get_memoryview_shared_utility_code(shared_utility_qualified_name):
880
+ shared_utility_code = CythonSharedUtilityCode(
881
+ 'MemoryView.pxd',
882
+ shared_utility_qualified_name,
883
+ template_context=template_context,
884
+ requires=[
885
+ Buffer.buffer_struct_declare_code,
886
+ Buffer.buffer_formats_declare_code,
887
+ memviewslice_declare_code,
888
+ refcount_utility,
889
+ atomic_utility,
890
+ copy_contents_new_utility,
891
+ ],
892
+ )
893
+
894
+ return shared_utility_code
895
+
896
+ def get_view_utility_code(shared_utility_qualified_name):
897
+ if shared_utility_qualified_name:
898
+ return _get_memoryview_shared_utility_code(shared_utility_qualified_name)
899
+ else:
900
+ return _get_memoryview_utility_code()
901
+
902
+
903
+ view_utility_allowlist = ('array', 'memoryview', 'array_cwrapper',
904
+ 'generic', 'strided', 'indirect', 'contiguous',
905
+ 'indirect_contiguous')