Cython 3.3.0__cp315-cp315-win_amd64.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 (339) hide show
  1. Cython/Build/BuildExecutable.py +156 -0
  2. Cython/Build/Cache.py +199 -0
  3. Cython/Build/Cythonize.py +349 -0
  4. Cython/Build/Dependencies.py +1281 -0
  5. Cython/Build/Distutils.py +1 -0
  6. Cython/Build/Inline.py +467 -0
  7. Cython/Build/IpythonMagic.py +559 -0
  8. Cython/Build/SharedModule.py +165 -0
  9. Cython/Build/Tests/TestCyCache.py +195 -0
  10. Cython/Build/Tests/TestCythonizeArgsParser.py +480 -0
  11. Cython/Build/Tests/TestDependencies.py +133 -0
  12. Cython/Build/Tests/TestInline.py +177 -0
  13. Cython/Build/Tests/TestIpythonMagic.py +303 -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 +825 -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 +679 -0
  23. Cython/Compiler/Builtin.py +1102 -0
  24. Cython/Compiler/CmdLine.py +373 -0
  25. Cython/Compiler/Code.cp315-win_amd64.pyd +0 -0
  26. Cython/Compiler/Code.pxd +154 -0
  27. Cython/Compiler/Code.py +3760 -0
  28. Cython/Compiler/CodeGeneration.py +33 -0
  29. Cython/Compiler/CythonScope.py +208 -0
  30. Cython/Compiler/Dataclass.py +890 -0
  31. Cython/Compiler/DebugFlags.py +24 -0
  32. Cython/Compiler/Errors.py +310 -0
  33. Cython/Compiler/ExprNodes.py +16273 -0
  34. Cython/Compiler/FlowControl.cp315-win_amd64.pyd +0 -0
  35. Cython/Compiler/FlowControl.pxd +112 -0
  36. Cython/Compiler/FlowControl.py +1573 -0
  37. Cython/Compiler/FusedNode.cp315-win_amd64.pyd +0 -0
  38. Cython/Compiler/FusedNode.py +978 -0
  39. Cython/Compiler/Future.py +16 -0
  40. Cython/Compiler/Interpreter.py +57 -0
  41. Cython/Compiler/Lexicon.py +422 -0
  42. Cython/Compiler/LineTable.cp315-win_amd64.pyd +0 -0
  43. Cython/Compiler/LineTable.py +114 -0
  44. Cython/Compiler/Main.py +856 -0
  45. Cython/Compiler/MatchCaseNodes.py +2200 -0
  46. Cython/Compiler/MemoryView.py +930 -0
  47. Cython/Compiler/ModuleNode.py +4548 -0
  48. Cython/Compiler/Naming.py +370 -0
  49. Cython/Compiler/Nodes.py +11304 -0
  50. Cython/Compiler/Optimize.py +5564 -0
  51. Cython/Compiler/Options.py +840 -0
  52. Cython/Compiler/ParseTreeTransforms.pxd +80 -0
  53. Cython/Compiler/ParseTreeTransforms.py +4808 -0
  54. Cython/Compiler/Parsing.cp315-win_amd64.pyd +0 -0
  55. Cython/Compiler/Parsing.pxd +9 -0
  56. Cython/Compiler/Parsing.py +4809 -0
  57. Cython/Compiler/Pipeline.py +439 -0
  58. Cython/Compiler/PyrexTypes.py +6588 -0
  59. Cython/Compiler/Pythran.py +232 -0
  60. Cython/Compiler/Scanning.cp315-win_amd64.pyd +0 -0
  61. Cython/Compiler/Scanning.pxd +70 -0
  62. Cython/Compiler/Scanning.py +720 -0
  63. Cython/Compiler/StringEncoding.cp315-win_amd64.pyd +0 -0
  64. Cython/Compiler/StringEncoding.py +354 -0
  65. Cython/Compiler/Symtab.py +3121 -0
  66. Cython/Compiler/Tests/TestBuffer.py +105 -0
  67. Cython/Compiler/Tests/TestBuiltin.py +196 -0
  68. Cython/Compiler/Tests/TestCmdLine.py +652 -0
  69. Cython/Compiler/Tests/TestCode.py +145 -0
  70. Cython/Compiler/Tests/TestFlowControl.py +65 -0
  71. Cython/Compiler/Tests/TestGrammar.py +202 -0
  72. Cython/Compiler/Tests/TestMemView.py +71 -0
  73. Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
  74. Cython/Compiler/Tests/TestScanning.py +132 -0
  75. Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
  76. Cython/Compiler/Tests/TestStringEncoding.py +20 -0
  77. Cython/Compiler/Tests/TestTreeFragment.py +63 -0
  78. Cython/Compiler/Tests/TestTreePath.py +103 -0
  79. Cython/Compiler/Tests/TestTypes.py +119 -0
  80. Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
  81. Cython/Compiler/Tests/TestVisitor.py +119 -0
  82. Cython/Compiler/Tests/Utils.py +36 -0
  83. Cython/Compiler/Tests/__init__.py +1 -0
  84. Cython/Compiler/TreeFragment.py +279 -0
  85. Cython/Compiler/TreePath.py +303 -0
  86. Cython/Compiler/TypeInference.py +611 -0
  87. Cython/Compiler/TypeSlots.py +1329 -0
  88. Cython/Compiler/UFuncs.py +317 -0
  89. Cython/Compiler/UtilNodes.py +389 -0
  90. Cython/Compiler/UtilityCode.py +354 -0
  91. Cython/Compiler/Version.py +8 -0
  92. Cython/Compiler/Visitor.cp315-win_amd64.pyd +0 -0
  93. Cython/Compiler/Visitor.pxd +52 -0
  94. Cython/Compiler/Visitor.py +914 -0
  95. Cython/Compiler/__init__.py +1 -0
  96. Cython/Coverage.py +448 -0
  97. Cython/Debugger/Cygdb.py +214 -0
  98. Cython/Debugger/DebugWriter.py +82 -0
  99. Cython/Debugger/Tests/TestLibCython.py +280 -0
  100. Cython/Debugger/Tests/__init__.py +1 -0
  101. Cython/Debugger/Tests/cfuncs.c +8 -0
  102. Cython/Debugger/Tests/codefile +49 -0
  103. Cython/Debugger/Tests/test_libcython_in_gdb.py +580 -0
  104. Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
  105. Cython/Debugger/__init__.py +1 -0
  106. Cython/Debugger/libcython.py +1548 -0
  107. Cython/Debugger/libpython.py +2821 -0
  108. Cython/Debugging.py +20 -0
  109. Cython/Distutils/__init__.py +2 -0
  110. Cython/Distutils/build_ext.py +143 -0
  111. Cython/Distutils/extension.py +96 -0
  112. Cython/Distutils/old_build_ext.py +351 -0
  113. Cython/Includes/cpython/__init__.pxd +173 -0
  114. Cython/Includes/cpython/array.pxd +152 -0
  115. Cython/Includes/cpython/bool.pxd +37 -0
  116. Cython/Includes/cpython/buffer.pxd +112 -0
  117. Cython/Includes/cpython/bytearray.pxd +33 -0
  118. Cython/Includes/cpython/bytes.pxd +200 -0
  119. Cython/Includes/cpython/cellobject.pxd +35 -0
  120. Cython/Includes/cpython/ceval.pxd +8 -0
  121. Cython/Includes/cpython/codecs.pxd +121 -0
  122. Cython/Includes/cpython/complex.pxd +60 -0
  123. Cython/Includes/cpython/contextvars.pxd +145 -0
  124. Cython/Includes/cpython/conversion.pxd +36 -0
  125. Cython/Includes/cpython/datetime.pxd +395 -0
  126. Cython/Includes/cpython/descr.pxd +26 -0
  127. Cython/Includes/cpython/dict.pxd +268 -0
  128. Cython/Includes/cpython/exc.pxd +263 -0
  129. Cython/Includes/cpython/fileobject.pxd +57 -0
  130. Cython/Includes/cpython/float.pxd +56 -0
  131. Cython/Includes/cpython/frozendict.pxd +37 -0
  132. Cython/Includes/cpython/function.pxd +65 -0
  133. Cython/Includes/cpython/genobject.pxd +25 -0
  134. Cython/Includes/cpython/getargs.pxd +12 -0
  135. Cython/Includes/cpython/instance.pxd +25 -0
  136. Cython/Includes/cpython/iterator.pxd +36 -0
  137. Cython/Includes/cpython/iterobject.pxd +24 -0
  138. Cython/Includes/cpython/list.pxd +144 -0
  139. Cython/Includes/cpython/long.pxd +180 -0
  140. Cython/Includes/cpython/longintrepr.pxd +14 -0
  141. Cython/Includes/cpython/mapping.pxd +63 -0
  142. Cython/Includes/cpython/marshal.pxd +66 -0
  143. Cython/Includes/cpython/mem.pxd +120 -0
  144. Cython/Includes/cpython/memoryview.pxd +50 -0
  145. Cython/Includes/cpython/method.pxd +49 -0
  146. Cython/Includes/cpython/module.pxd +208 -0
  147. Cython/Includes/cpython/number.pxd +258 -0
  148. Cython/Includes/cpython/object.pxd +430 -0
  149. Cython/Includes/cpython/pycapsule.pxd +143 -0
  150. Cython/Includes/cpython/pylifecycle.pxd +68 -0
  151. Cython/Includes/cpython/pyport.pxd +8 -0
  152. Cython/Includes/cpython/pystate.pxd +95 -0
  153. Cython/Includes/cpython/pythread.pxd +53 -0
  154. Cython/Includes/cpython/ref.pxd +141 -0
  155. Cython/Includes/cpython/sentinel.pxd +17 -0
  156. Cython/Includes/cpython/sequence.pxd +134 -0
  157. Cython/Includes/cpython/set.pxd +119 -0
  158. Cython/Includes/cpython/slice.pxd +70 -0
  159. Cython/Includes/cpython/time.pxd +129 -0
  160. Cython/Includes/cpython/tuple.pxd +72 -0
  161. Cython/Includes/cpython/type.pxd +146 -0
  162. Cython/Includes/cpython/unicode.pxd +639 -0
  163. Cython/Includes/cpython/version.pxd +32 -0
  164. Cython/Includes/cpython/weakref.pxd +78 -0
  165. Cython/Includes/libc/__init__.pxd +1 -0
  166. Cython/Includes/libc/complex.pxd +35 -0
  167. Cython/Includes/libc/errno.pxd +127 -0
  168. Cython/Includes/libc/float.pxd +43 -0
  169. Cython/Includes/libc/limits.pxd +28 -0
  170. Cython/Includes/libc/locale.pxd +46 -0
  171. Cython/Includes/libc/math.pxd +209 -0
  172. Cython/Includes/libc/setjmp.pxd +10 -0
  173. Cython/Includes/libc/signal.pxd +64 -0
  174. Cython/Includes/libc/stddef.pxd +9 -0
  175. Cython/Includes/libc/stdint.pxd +105 -0
  176. Cython/Includes/libc/stdio.pxd +80 -0
  177. Cython/Includes/libc/stdlib.pxd +72 -0
  178. Cython/Includes/libc/string.pxd +50 -0
  179. Cython/Includes/libc/threads.pxd +234 -0
  180. Cython/Includes/libc/time.pxd +52 -0
  181. Cython/Includes/libcpp/__init__.pxd +4 -0
  182. Cython/Includes/libcpp/algorithm.pxd +320 -0
  183. Cython/Includes/libcpp/any.pxd +16 -0
  184. Cython/Includes/libcpp/atomic.pxd +59 -0
  185. Cython/Includes/libcpp/barrier.pxd +22 -0
  186. Cython/Includes/libcpp/bit.pxd +29 -0
  187. Cython/Includes/libcpp/cast.pxd +12 -0
  188. Cython/Includes/libcpp/cmath.pxd +518 -0
  189. Cython/Includes/libcpp/complex.pxd +106 -0
  190. Cython/Includes/libcpp/condition_variable.pxd +322 -0
  191. Cython/Includes/libcpp/deque.pxd +165 -0
  192. Cython/Includes/libcpp/exception.pxd +216 -0
  193. Cython/Includes/libcpp/execution.pxd +15 -0
  194. Cython/Includes/libcpp/forward_list.pxd +63 -0
  195. Cython/Includes/libcpp/functional.pxd +26 -0
  196. Cython/Includes/libcpp/future.pxd +103 -0
  197. Cython/Includes/libcpp/iterator.pxd +34 -0
  198. Cython/Includes/libcpp/latch.pxd +17 -0
  199. Cython/Includes/libcpp/limits.pxd +61 -0
  200. Cython/Includes/libcpp/list.pxd +117 -0
  201. Cython/Includes/libcpp/map.pxd +252 -0
  202. Cython/Includes/libcpp/memory.pxd +115 -0
  203. Cython/Includes/libcpp/mutex.pxd +387 -0
  204. Cython/Includes/libcpp/numbers.pxd +15 -0
  205. Cython/Includes/libcpp/numeric.pxd +131 -0
  206. Cython/Includes/libcpp/optional.pxd +34 -0
  207. Cython/Includes/libcpp/pair.pxd +1 -0
  208. Cython/Includes/libcpp/queue.pxd +25 -0
  209. Cython/Includes/libcpp/random.pxd +166 -0
  210. Cython/Includes/libcpp/semaphore.pxd +43 -0
  211. Cython/Includes/libcpp/set.pxd +228 -0
  212. Cython/Includes/libcpp/shared_mutex.pxd +96 -0
  213. Cython/Includes/libcpp/span.pxd +87 -0
  214. Cython/Includes/libcpp/stack.pxd +11 -0
  215. Cython/Includes/libcpp/stop_token.pxd +117 -0
  216. Cython/Includes/libcpp/string.pxd +355 -0
  217. Cython/Includes/libcpp/string_view.pxd +183 -0
  218. Cython/Includes/libcpp/typeindex.pxd +15 -0
  219. Cython/Includes/libcpp/typeinfo.pxd +10 -0
  220. Cython/Includes/libcpp/unordered_map.pxd +193 -0
  221. Cython/Includes/libcpp/unordered_set.pxd +152 -0
  222. Cython/Includes/libcpp/utility.pxd +30 -0
  223. Cython/Includes/libcpp/vector.pxd +186 -0
  224. Cython/Includes/numpy/math.pxd +150 -0
  225. Cython/Includes/openmp.pxd +50 -0
  226. Cython/Includes/posix/__init__.pxd +1 -0
  227. Cython/Includes/posix/dlfcn.pxd +14 -0
  228. Cython/Includes/posix/fcntl.pxd +86 -0
  229. Cython/Includes/posix/ioctl.pxd +4 -0
  230. Cython/Includes/posix/mman.pxd +101 -0
  231. Cython/Includes/posix/resource.pxd +57 -0
  232. Cython/Includes/posix/select.pxd +21 -0
  233. Cython/Includes/posix/signal.pxd +73 -0
  234. Cython/Includes/posix/stat.pxd +98 -0
  235. Cython/Includes/posix/stdio.pxd +37 -0
  236. Cython/Includes/posix/stdlib.pxd +29 -0
  237. Cython/Includes/posix/strings.pxd +9 -0
  238. Cython/Includes/posix/time.pxd +71 -0
  239. Cython/Includes/posix/types.pxd +30 -0
  240. Cython/Includes/posix/uio.pxd +26 -0
  241. Cython/Includes/posix/unistd.pxd +271 -0
  242. Cython/Includes/posix/wait.pxd +38 -0
  243. Cython/LZSS.cp315-win_amd64.pyd +0 -0
  244. Cython/LZSS.py +184 -0
  245. Cython/Plex/Actions.cp315-win_amd64.pyd +0 -0
  246. Cython/Plex/Actions.pxd +24 -0
  247. Cython/Plex/Actions.py +119 -0
  248. Cython/Plex/DFA.cp315-win_amd64.pyd +0 -0
  249. Cython/Plex/DFA.pxd +14 -0
  250. Cython/Plex/DFA.py +164 -0
  251. Cython/Plex/Errors.py +48 -0
  252. Cython/Plex/Lexicons.py +178 -0
  253. Cython/Plex/Machines.cp315-win_amd64.pyd +0 -0
  254. Cython/Plex/Machines.pxd +36 -0
  255. Cython/Plex/Machines.py +238 -0
  256. Cython/Plex/Regexps.py +535 -0
  257. Cython/Plex/Scanners.cp315-win_amd64.pyd +0 -0
  258. Cython/Plex/Scanners.pxd +45 -0
  259. Cython/Plex/Scanners.py +328 -0
  260. Cython/Plex/Transitions.cp315-win_amd64.pyd +0 -0
  261. Cython/Plex/Transitions.pxd +14 -0
  262. Cython/Plex/Transitions.py +239 -0
  263. Cython/Plex/__init__.py +34 -0
  264. Cython/Runtime/__init__.py +1 -0
  265. Cython/Runtime/refnanny.cp315-win_amd64.pyd +0 -0
  266. Cython/Runtime/refnanny.pyx +237 -0
  267. Cython/Shadow.py +1174 -0
  268. Cython/StringIOTree.cp315-win_amd64.pyd +0 -0
  269. Cython/StringIOTree.py +169 -0
  270. Cython/Tempita/__init__.py +4 -0
  271. Cython/Tempita/_looper.py +154 -0
  272. Cython/Tempita/_tempita.cp315-win_amd64.pyd +0 -0
  273. Cython/Tempita/_tempita.py +1087 -0
  274. Cython/TestUtils.py +472 -0
  275. Cython/Tests/TestCodeWriter.py +128 -0
  276. Cython/Tests/TestCythonUtils.py +202 -0
  277. Cython/Tests/TestJediTyper.py +223 -0
  278. Cython/Tests/TestShadow.py +125 -0
  279. Cython/Tests/TestStringIOTree.py +68 -0
  280. Cython/Tests/TestTestUtils.py +89 -0
  281. Cython/Tests/__init__.py +1 -0
  282. Cython/Tests/xmlrunner.py +390 -0
  283. Cython/Utility/AsyncGen.c +1152 -0
  284. Cython/Utility/Buffer.c +866 -0
  285. Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
  286. Cython/Utility/Builtins.c +1068 -0
  287. Cython/Utility/CConvert.pyx +153 -0
  288. Cython/Utility/CMath.c +104 -0
  289. Cython/Utility/CommonStructures.c +244 -0
  290. Cython/Utility/Complex.c +378 -0
  291. Cython/Utility/Coroutine.c +2344 -0
  292. Cython/Utility/CpdefEnums.pyx +119 -0
  293. Cython/Utility/CppConvert.pyx +282 -0
  294. Cython/Utility/CppSupport.cpp +151 -0
  295. Cython/Utility/CythonFunction.c +2185 -0
  296. Cython/Utility/Dataclasses.c +101 -0
  297. Cython/Utility/Embed.c +129 -0
  298. Cython/Utility/Exceptions.c +1331 -0
  299. Cython/Utility/Exceptions_Cy.pyx +109 -0
  300. Cython/Utility/ExtensionTypes.c +1199 -0
  301. Cython/Utility/FunctionArguments.c +1052 -0
  302. Cython/Utility/FusedFunction.pyx +44 -0
  303. Cython/Utility/ImportExport.c +972 -0
  304. Cython/Utility/MatchCase.c +981 -0
  305. Cython/Utility/MatchCase_Cy.pyx +12 -0
  306. Cython/Utility/MemoryView.pxd +108 -0
  307. Cython/Utility/MemoryView.pyx +1499 -0
  308. Cython/Utility/MemoryView_C.c +1056 -0
  309. Cython/Utility/ModuleSetupCode.c +3319 -0
  310. Cython/Utility/NumpyImportArray.c +46 -0
  311. Cython/Utility/ObjectHandling.c +3404 -0
  312. Cython/Utility/Optimize.c +2564 -0
  313. Cython/Utility/Overflow.c +378 -0
  314. Cython/Utility/Profile.c +736 -0
  315. Cython/Utility/StringTools.c +1534 -0
  316. Cython/Utility/Synchronization.c +438 -0
  317. Cython/Utility/TString.c +369 -0
  318. Cython/Utility/TestCyUtilityLoader.pyx +8 -0
  319. Cython/Utility/TestCythonScope.pyx +75 -0
  320. Cython/Utility/TestUtilityLoader.c +12 -0
  321. Cython/Utility/TypeConversion.c +1588 -0
  322. Cython/Utility/UFuncs.pyx +50 -0
  323. Cython/Utility/UFuncs_C.c +89 -0
  324. Cython/Utility/__init__.py +28 -0
  325. Cython/Utility/arrayarray.h +172 -0
  326. Cython/Utils.cp315-win_amd64.pyd +0 -0
  327. Cython/Utils.py +680 -0
  328. Cython/__init__.py +12 -0
  329. Cython/_shared.cp315-win_amd64.pyd +0 -0
  330. Cython/py.typed +0 -0
  331. cython-3.3.0.dist-info/METADATA +555 -0
  332. cython-3.3.0.dist-info/RECORD +339 -0
  333. cython-3.3.0.dist-info/WHEEL +5 -0
  334. cython-3.3.0.dist-info/entry_points.txt +4 -0
  335. cython-3.3.0.dist-info/top_level.txt +3 -0
  336. cython.py +29 -0
  337. pyximport/__init__.py +4 -0
  338. pyximport/pyxbuild.py +160 -0
  339. pyximport/pyximport.py +482 -0
@@ -0,0 +1,930 @@
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
+ rhs_is_borrowed_temp = rhs.is_memview_slice and rhs.use_borrowed_ref
73
+
74
+ pretty_rhs = rhs.result_in_temp() or rhs.is_simple()
75
+ if pretty_rhs:
76
+ rhstmp = rhs.result()
77
+ else:
78
+ rhstmp = code.funcstate.allocate_temp(lhs_type, manage_ref=False)
79
+ code.putln("%s = %s;" % (rhstmp, rhs.result_as(lhs_type)))
80
+
81
+ # Allow uninitialized assignment
82
+ #code.putln(code.put_error_if_unbound(lhs_pos, rhs.entry))
83
+ put_assign_to_memviewslice(lhs_cname, rhs, rhstmp, lhs_type, code,
84
+ have_gil=have_gil, first_assignment=first_assignment,
85
+ rhs_is_borrowed_temp=rhs_is_borrowed_temp)
86
+
87
+ if not pretty_rhs:
88
+ code.funcstate.release_temp(rhstmp)
89
+
90
+
91
+ def put_assign_to_memviewslice(lhs_cname, rhs, rhs_cname, memviewslicetype, code,
92
+ have_gil=False, first_assignment=False,
93
+ rhs_is_borrowed_temp=False):
94
+ if lhs_cname == rhs_cname:
95
+ # self assignment is tricky because memoryview xdecref clears the memoryview
96
+ # thus invalidating both sides of the assignment. Therefore make it actually do nothing
97
+ code.putln("/* memoryview self assignment no-op */")
98
+ return
99
+
100
+ if rhs_is_borrowed_temp and not first_assignment:
101
+ # Here we can skip the reference counting in the fairly likely case
102
+ # that the lhs and rhs are equal (e.g. repeated slicing in a loop).
103
+ code.putln(f"if ({lhs_cname}.memview != {rhs_cname}.memview) ""{")
104
+ if not first_assignment:
105
+ code.put_xdecref(lhs_cname, memviewslicetype,
106
+ have_gil=have_gil)
107
+ if rhs_is_borrowed_temp:
108
+ code.put_incref_memoryviewslice(rhs_cname, memviewslicetype, have_gil=have_gil)
109
+ if not first_assignment:
110
+ code.putln("}")
111
+
112
+ if not rhs.result_in_temp():
113
+ rhs.make_owned_memoryviewslice(code)
114
+
115
+ code.putln("%s = %s;" % (lhs_cname, rhs_cname))
116
+
117
+
118
+ def get_buf_flags(specs):
119
+ is_c_contig, is_f_contig = is_cf_contig(specs)
120
+
121
+ if is_c_contig:
122
+ return memview_c_contiguous
123
+ elif is_f_contig:
124
+ return memview_f_contiguous
125
+
126
+ access, packing = zip(*specs)
127
+
128
+ if 'full' in access or 'ptr' in access:
129
+ return memview_full_access
130
+ else:
131
+ return memview_strided_access
132
+
133
+
134
+ def insert_newaxes(memoryviewtype, n):
135
+ axes = [('direct', 'strided')] * n
136
+ axes.extend(memoryviewtype.axes)
137
+ return PyrexTypes.MemoryViewSliceType(memoryviewtype.dtype, axes)
138
+
139
+
140
+ def broadcast_types(src, dst):
141
+ n = abs(src.ndim - dst.ndim)
142
+ if src.ndim < dst.ndim:
143
+ return insert_newaxes(src, n), dst
144
+ else:
145
+ return src, insert_newaxes(dst, n)
146
+
147
+
148
+ def valid_memslice_dtype(dtype, i=0):
149
+ """
150
+ Return whether type dtype can be used as the base type of a
151
+ memoryview slice.
152
+
153
+ We support structs, numeric types and objects
154
+ """
155
+ if dtype.is_complex and dtype.real_type.is_int:
156
+ return False
157
+
158
+ if dtype is PyrexTypes.c_bint_type:
159
+ return False
160
+
161
+ if dtype.is_struct and dtype.kind == 'struct':
162
+ for member in dtype.scope.var_entries:
163
+ if not valid_memslice_dtype(member.type):
164
+ return False
165
+
166
+ return True
167
+
168
+ return (
169
+ dtype.is_error or
170
+ # Pointers are not valid (yet)
171
+ # (dtype.is_ptr and valid_memslice_dtype(dtype.base_type)) or
172
+ (dtype.is_array and i < 8 and
173
+ valid_memslice_dtype(dtype.base_type, i + 1)) or
174
+ dtype.is_numeric or
175
+ dtype.is_pyobject or
176
+ dtype.is_fused or # accept this as it will be replaced by specializations later
177
+ (dtype.is_typedef and valid_memslice_dtype(dtype.typedef_base_type))
178
+ )
179
+
180
+
181
+ class MemoryViewSliceBufferEntry(Buffer.BufferEntry):
182
+ """
183
+ May be used during code generation time to be queried for
184
+ shape/strides/suboffsets attributes, or to perform indexing or slicing.
185
+ """
186
+ def __init__(self, entry):
187
+ self.entry = entry
188
+ self.type = entry.type
189
+ self.cname = entry.cname
190
+
191
+ self.buf_ptr = "%s.data" % self.cname
192
+
193
+ dtype = self.entry.type.dtype
194
+ self.buf_ptr_type = PyrexTypes.CPtrType(dtype)
195
+ self.init_attributes()
196
+
197
+ def get_buf_suboffsetvars(self):
198
+ return self._for_all_ndim("%s.suboffsets[%d]")
199
+
200
+ def get_buf_stridevars(self):
201
+ return self._for_all_ndim("%s.strides[%d]")
202
+
203
+ def get_buf_shapevars(self):
204
+ return self._for_all_ndim("%s.shape[%d]")
205
+
206
+ def generate_buffer_lookup_code(self, code, index_cnames):
207
+ axes = [(dim, index_cnames[dim], access, packing)
208
+ for dim, (access, packing) in enumerate(self.type.axes)]
209
+ return self._generate_buffer_lookup_code(code, axes)
210
+
211
+ def _generate_buffer_lookup_code(self, code, axes, cast_result=True):
212
+ """
213
+ Generate a single expression that indexes the memory view slice
214
+ in each dimension.
215
+ """
216
+ bufp = self.buf_ptr
217
+ type_decl = self.type.dtype.empty_declaration_code()
218
+
219
+ for dim, index, access, packing in axes:
220
+ shape = "%s.shape[%d]" % (self.cname, dim)
221
+ stride = "%s.strides[%d]" % (self.cname, dim)
222
+ suboffset = "%s.suboffsets[%d]" % (self.cname, dim)
223
+
224
+ flag = get_memoryview_flag(access, packing)
225
+
226
+ if flag in ("generic", "generic_contiguous"):
227
+ # Note: we cannot do cast tricks to avoid stride multiplication
228
+ # for generic_contiguous, as we may have to do (dtype *)
229
+ # or (dtype **) arithmetic, we won't know which unless
230
+ # we check suboffsets
231
+ code.globalstate.use_utility_code(memviewslice_index_helpers)
232
+ bufp = ('__pyx_memviewslice_index_full(%s, %s, %s, %s)' %
233
+ (bufp, index, stride, suboffset))
234
+
235
+ elif flag == "indirect":
236
+ bufp = "(%s + %s * %s)" % (bufp, index, stride)
237
+ bufp = ("(*((char **) %s) + %s)" % (bufp, suboffset))
238
+
239
+ elif flag == "indirect_contiguous":
240
+ # Note: we do char ** arithmetic
241
+ bufp = "(*((char **) %s + %s) + %s)" % (bufp, index, suboffset)
242
+
243
+ elif flag == "strided":
244
+ bufp = "(%s + %s * %s)" % (bufp, index, stride)
245
+
246
+ else:
247
+ assert flag == 'contiguous', flag
248
+ bufp = '((char *) (((%s *) %s) + %s))' % (type_decl, bufp, index)
249
+
250
+ bufp = '( /* dim=%d */ %s )' % (dim, bufp)
251
+
252
+ if cast_result:
253
+ return "((%s *) %s)" % (type_decl, bufp)
254
+
255
+ return bufp
256
+
257
+ def generate_buffer_slice_code(self, code, indices, dst, dst_type, have_gil,
258
+ have_slices, directives, drop_temp_refcounting):
259
+ """
260
+ Slice a memoryviewslice.
261
+
262
+ indices - list of index nodes. If not a SliceNode, or NoneNode,
263
+ then it must be coercible to Py_ssize_t
264
+
265
+ Simply call __pyx_memoryview_slice_memviewslice with the right
266
+ arguments, unless the dimension is omitted or a bare ':', in which
267
+ case we copy over the shape/strides/suboffsets attributes directly
268
+ for that dimension.
269
+ """
270
+ src = self.cname
271
+
272
+ code.putln(f"{dst}.data = {src}.data;")
273
+ code.putln(f"{dst}.memview = {src}.memview;")
274
+ if not drop_temp_refcounting:
275
+ code.put_incref_memoryviewslice(dst, dst_type, have_gil=have_gil)
276
+
277
+ all_dimensions_direct = all(access == 'direct' for access, packing in self.type.axes)
278
+ suboffset_dim_temp = []
279
+
280
+ def get_suboffset_dim():
281
+ # create global temp variable at request
282
+ if not suboffset_dim_temp:
283
+ suboffset_dim = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
284
+ code.putln(f"{suboffset_dim} = -1;")
285
+ suboffset_dim_temp.append(suboffset_dim)
286
+ return suboffset_dim_temp[0]
287
+
288
+ boundscheck = directives['boundscheck']
289
+ template_vars = {
290
+ 'src': src,
291
+ 'dst': dst,
292
+ 'have_gil': have_gil,
293
+ 'get_suboffset_dim': get_suboffset_dim,
294
+ 'all_dimensions_direct': all_dimensions_direct,
295
+ 'wraparound': int(directives['wraparound']),
296
+ 'boundscheck': int(boundscheck),
297
+ }
298
+
299
+ dim = -1
300
+ new_ndim = 0
301
+ for index in indices:
302
+ if index.is_none:
303
+ # newaxis
304
+ for attrib, value in [('shape', 1), ('strides', 0), ('suboffsets', -1)]:
305
+ code.putln(f"{dst}.{attrib}[{new_ndim:d}] = {value:d};")
306
+
307
+ new_ndim += 1
308
+ continue
309
+
310
+ dim += 1
311
+ access, packing = self.type.axes[dim]
312
+
313
+ d = dict(
314
+ template_vars,
315
+ dim=dim,
316
+ new_ndim=new_ndim,
317
+ access=access,
318
+ )
319
+
320
+ if index.is_slice:
321
+ # slice, unspecified dimension, or part of ellipsis
322
+ is_full_slice = True
323
+ for s in ("start", "stop", "step"):
324
+ idx = getattr(index, s)
325
+ if idx.is_none:
326
+ d['have_' + s] = False
327
+ d[s] = "0"
328
+ else:
329
+ is_full_slice = False
330
+ d['have_' + s] = True
331
+ d[s] = idx.result()
332
+
333
+ if is_full_slice:
334
+ # For a full slice (:), we just copy over the extent, stride and suboffset.
335
+ # Also update suboffset_dim if needed.
336
+ util_name = "SimpleSlice"
337
+ else:
338
+ util_name = "ToughSlice"
339
+ code.globalstate.use_utility_code(slice_memviewslice_utility)
340
+ d['error_goto'] = code.error_goto(index.pos)
341
+
342
+ new_ndim += 1
343
+ else:
344
+ # normal index
345
+ if access != 'direct' and new_ndim != 0:
346
+ error(index.pos, "All preceding dimensions must be indexed and not sliced")
347
+ return
348
+
349
+ util_name = "SliceIndex"
350
+ d.update(
351
+ idx=index.result(),
352
+ indirect=access != 'direct',
353
+ generic=access == 'full',
354
+ )
355
+ if boundscheck:
356
+ d['error_goto'] = code.error_goto(index.pos)
357
+
358
+ _, impl = TempitaUtilityCode.load_as_string(util_name, "MemoryView_C.c", context=d)
359
+ code.put(impl)
360
+
361
+ if suboffset_dim_temp:
362
+ code.funcstate.release_temp(suboffset_dim_temp[0])
363
+
364
+
365
+ def empty_slice(pos):
366
+ none = ExprNodes.NoneNode(pos)
367
+ return ExprNodes.SliceNode(pos, start=none,
368
+ stop=none, step=none)
369
+
370
+
371
+ def unellipsify(indices, ndim):
372
+ result = []
373
+ seen_ellipsis = False
374
+ have_slices = False
375
+
376
+ newaxes = [newaxis for newaxis in indices if newaxis.is_none]
377
+ n_indices = len(indices) - len(newaxes)
378
+
379
+ for index in indices:
380
+ if isinstance(index, ExprNodes.EllipsisNode):
381
+ have_slices = True
382
+ full_slice = empty_slice(index.pos)
383
+
384
+ if seen_ellipsis:
385
+ result.append(full_slice)
386
+ else:
387
+ nslices = ndim - n_indices + 1
388
+ result.extend([full_slice] * nslices)
389
+ seen_ellipsis = True
390
+ else:
391
+ have_slices = have_slices or index.is_slice or index.is_none
392
+ result.append(index)
393
+
394
+ result_length = len(result) - len(newaxes)
395
+ if result_length < ndim:
396
+ have_slices = True
397
+ nslices = ndim - result_length
398
+ result.extend([empty_slice(indices[-1].pos)] * nslices)
399
+
400
+ return have_slices, result, newaxes
401
+
402
+
403
+ def get_memoryview_flag(access, packing):
404
+ if access == 'full' and packing in ('strided', 'follow'):
405
+ return 'generic'
406
+ elif access == 'full' and packing == 'contig':
407
+ return 'generic_contiguous'
408
+ elif access == 'ptr' and packing in ('strided', 'follow'):
409
+ return 'indirect'
410
+ elif access == 'ptr' and packing == 'contig':
411
+ return 'indirect_contiguous'
412
+ elif access == 'direct' and packing in ('strided', 'follow'):
413
+ return 'strided'
414
+ else:
415
+ assert (access, packing) == ('direct', 'contig'), (access, packing)
416
+ return 'contiguous'
417
+
418
+
419
+ def get_is_contig_func_name(contig_type, ndim):
420
+ assert contig_type in ('C', 'F')
421
+ return "__pyx_memviewslice_is_contig_%s%d" % (contig_type, ndim)
422
+
423
+
424
+ def get_is_contig_utility(contig_type, ndim):
425
+ assert contig_type in ('C', 'F')
426
+ C = dict(template_context, ndim=ndim, contig_type=contig_type)
427
+ utility = load_memview_c_utility("MemviewSliceCheckContig", context=C,
428
+ requires=[is_contig_utility])
429
+ return utility
430
+
431
+
432
+ def slice_iter(slice_type, slice_result, ndim, code, force_strided=False):
433
+ if (slice_type.is_c_contig or slice_type.is_f_contig) and not force_strided:
434
+ return ContigSliceIter(slice_type, slice_result, ndim, code)
435
+ else:
436
+ return StridedSliceIter(slice_type, slice_result, ndim, code)
437
+
438
+
439
+ class SliceIter:
440
+ def __init__(self, slice_type, slice_result, ndim, code):
441
+ self.slice_type = slice_type
442
+ self.slice_result = slice_result
443
+ self.code = code
444
+ self.ndim = ndim
445
+
446
+
447
+ class ContigSliceIter(SliceIter):
448
+ def start_loops(self):
449
+ code = self.code
450
+ code.begin_block()
451
+
452
+ type_decl = self.slice_type.dtype.empty_declaration_code()
453
+
454
+ total_size = ' * '.join("%s.shape[%d]" % (self.slice_result, i)
455
+ for i in range(self.ndim))
456
+ code.putln("Py_ssize_t __pyx_temp_extent = %s;" % total_size)
457
+ code.putln("Py_ssize_t __pyx_temp_idx;")
458
+ code.putln("%s *__pyx_temp_pointer = (%s *) %s.data;" % (
459
+ type_decl, type_decl, self.slice_result))
460
+ code.putln("for (__pyx_temp_idx = 0; "
461
+ "__pyx_temp_idx < __pyx_temp_extent; "
462
+ "__pyx_temp_idx++) {")
463
+
464
+ return "__pyx_temp_pointer"
465
+
466
+ def end_loops(self):
467
+ self.code.putln("__pyx_temp_pointer += 1;")
468
+ self.code.putln("}")
469
+ self.code.end_block()
470
+
471
+
472
+ class StridedSliceIter(SliceIter):
473
+ def start_loops(self):
474
+ code = self.code
475
+ code.begin_block()
476
+
477
+ for i in range(self.ndim):
478
+ t = i, self.slice_result, i
479
+ code.putln("Py_ssize_t __pyx_temp_extent_%d = %s.shape[%d];" % t)
480
+ code.putln("Py_ssize_t __pyx_temp_stride_%d = %s.strides[%d];" % t)
481
+ code.putln("char *__pyx_temp_pointer_%d;" % i)
482
+ code.putln("Py_ssize_t __pyx_temp_idx_%d;" % i)
483
+
484
+ code.putln("__pyx_temp_pointer_0 = %s.data;" % self.slice_result)
485
+
486
+ for i in range(self.ndim):
487
+ if i > 0:
488
+ code.putln("__pyx_temp_pointer_%d = __pyx_temp_pointer_%d;" % (i, i - 1))
489
+
490
+ code.putln("for (__pyx_temp_idx_%d = 0; "
491
+ "__pyx_temp_idx_%d < __pyx_temp_extent_%d; "
492
+ "__pyx_temp_idx_%d++) {" % (i, i, i, i))
493
+
494
+ return "__pyx_temp_pointer_%d" % (self.ndim - 1)
495
+
496
+ def end_loops(self):
497
+ code = self.code
498
+ for i in range(self.ndim - 1, -1, -1):
499
+ code.putln("__pyx_temp_pointer_%d += __pyx_temp_stride_%d;" % (i, i))
500
+ code.putln("}")
501
+
502
+ code.end_block()
503
+
504
+
505
+ def copy_c_or_fortran_cname(memview):
506
+ if memview.is_c_contig:
507
+ c_or_f = 'c'
508
+ else:
509
+ c_or_f = 'f'
510
+
511
+ return "__pyx_memoryview_copy_slice_%s_%s" % (
512
+ memview.specialization_suffix(), c_or_f)
513
+
514
+
515
+ def get_copy_new_utility(pos, from_memview, to_memview):
516
+ if (from_memview.dtype != to_memview.dtype and
517
+ not (from_memview.dtype.is_cv_qualified and from_memview.dtype.cv_base_type == to_memview.dtype)):
518
+ error(pos, "dtypes must be the same!")
519
+ return
520
+ if len(from_memview.axes) != len(to_memview.axes):
521
+ error(pos, "number of dimensions must be same")
522
+ return
523
+ if not (to_memview.is_c_contig or to_memview.is_f_contig):
524
+ error(pos, "to_memview must be c or f contiguous.")
525
+ return
526
+
527
+ for (access, packing) in from_memview.axes:
528
+ if access != 'direct':
529
+ error(pos, "cannot handle 'full' or 'ptr' access at this time.")
530
+ return
531
+
532
+ if to_memview.is_c_contig:
533
+ mode = 'c'
534
+ contig_flag = memview_c_contiguous
535
+ else:
536
+ assert to_memview.is_f_contig
537
+ mode = 'fortran'
538
+ contig_flag = memview_f_contiguous
539
+
540
+ return load_memview_c_utility(
541
+ "CopyContentsUtility",
542
+ context=dict(
543
+ template_context,
544
+ mode=mode,
545
+ dtype_decl=to_memview.dtype.empty_declaration_code(),
546
+ contig_flag=contig_flag,
547
+ ndim=to_memview.ndim,
548
+ func_cname=copy_c_or_fortran_cname(to_memview),
549
+ dtype_is_object=int(to_memview.dtype.is_pyobject),
550
+ ),
551
+ )
552
+
553
+
554
+ def get_axes_specs(env, axes):
555
+ '''
556
+ get_axes_specs(env, axes) -> list of (access, packing) specs for each axis.
557
+ access is one of 'full', 'ptr' or 'direct'
558
+ packing is one of 'contig', 'strided' or 'follow'
559
+ '''
560
+
561
+ cythonscope = env.context.cython_scope
562
+ cythonscope.load_cythonscope()
563
+ viewscope = cythonscope.viewscope
564
+
565
+ access_specs = tuple([viewscope.lookup(name)
566
+ for name in ('full', 'direct', 'ptr')])
567
+ packing_specs = tuple([viewscope.lookup(name)
568
+ for name in ('contig', 'strided', 'follow')])
569
+
570
+ is_f_contig, is_c_contig = False, False
571
+ default_access, default_packing = 'direct', 'strided'
572
+ cf_access, cf_packing = default_access, 'follow'
573
+
574
+ axes_specs = []
575
+ # analyse all axes.
576
+ for idx, axis in enumerate(axes):
577
+ if not axis.start.is_none:
578
+ raise CompileError(axis.start.pos, START_ERR)
579
+
580
+ if not axis.stop.is_none:
581
+ raise CompileError(axis.stop.pos, STOP_ERR)
582
+
583
+ if axis.step.is_none:
584
+ axes_specs.append((default_access, default_packing))
585
+
586
+ elif isinstance(axis.step, IntNode):
587
+ # the packing for the ::1 axis is contiguous,
588
+ # all others are cf_packing.
589
+ if axis.step.compile_time_value(env) != 1:
590
+ raise CompileError(axis.step.pos, STEP_ERR)
591
+
592
+ axes_specs.append((cf_access, 'cfcontig'))
593
+
594
+ elif isinstance(axis.step, (NameNode, AttributeNode)):
595
+ entry = _get_resolved_spec(env, axis.step)
596
+ if entry.name in view_constant_to_access_packing:
597
+ axes_specs.append(view_constant_to_access_packing[entry.name])
598
+ else:
599
+ raise CompileError(axis.step.pos, INVALID_ERR)
600
+
601
+ else:
602
+ raise CompileError(axis.step.pos, INVALID_ERR)
603
+
604
+ # First, find out if we have a ::1 somewhere
605
+ contig_dim = 0
606
+ is_contig = False
607
+ for idx, (access, packing) in enumerate(axes_specs):
608
+ if packing == 'cfcontig':
609
+ if is_contig:
610
+ raise CompileError(axis.step.pos, BOTH_CF_ERR)
611
+
612
+ contig_dim = idx
613
+ axes_specs[idx] = (access, 'contig')
614
+ is_contig = True
615
+
616
+ if is_contig:
617
+ # We have a ::1 somewhere, see if we're C or Fortran contiguous
618
+ if contig_dim == len(axes) - 1:
619
+ is_c_contig = True
620
+ else:
621
+ is_f_contig = True
622
+
623
+ if contig_dim and not axes_specs[contig_dim - 1][0] in ('full', 'ptr'):
624
+ raise CompileError(axes[contig_dim].pos,
625
+ "Fortran contiguous specifier must follow an indirect dimension")
626
+
627
+ if is_c_contig:
628
+ # Contiguous in the last dimension, find the last indirect dimension
629
+ contig_dim = -1
630
+ for idx, (access, packing) in enumerate(reversed(axes_specs)):
631
+ if access in ('ptr', 'full'):
632
+ contig_dim = len(axes) - idx - 1
633
+
634
+ # Replace 'strided' with 'follow' for any dimension following the last
635
+ # indirect dimension, the first dimension or the dimension following
636
+ # the ::1.
637
+ # int[::indirect, ::1, :, :]
638
+ # ^ ^
639
+ # int[::indirect, :, :, ::1]
640
+ # ^ ^
641
+ start = contig_dim + 1
642
+ stop = len(axes) - is_c_contig
643
+ for idx, (access, packing) in enumerate(axes_specs[start:stop]):
644
+ idx = contig_dim + 1 + idx
645
+ if access != 'direct':
646
+ raise CompileError(axes[idx].pos,
647
+ "Indirect dimension may not follow "
648
+ "Fortran contiguous dimension")
649
+ if packing == 'contig':
650
+ raise CompileError(axes[idx].pos,
651
+ "Dimension may not be contiguous")
652
+ axes_specs[idx] = (access, cf_packing)
653
+
654
+ if is_c_contig:
655
+ # For C contiguity, we need to fix the 'contig' dimension
656
+ # after the loop
657
+ a, p = axes_specs[-1]
658
+ axes_specs[-1] = a, 'contig'
659
+
660
+ validate_axes_specs([axis.start.pos for axis in axes],
661
+ axes_specs,
662
+ is_c_contig,
663
+ is_f_contig)
664
+
665
+ return axes_specs
666
+
667
+
668
+ def validate_axes(pos, axes):
669
+ if len(axes) >= Options.buffer_max_dims:
670
+ error(pos, "More dimensions than the maximum number"
671
+ " of buffer dimensions were used.")
672
+ return False
673
+
674
+ return True
675
+
676
+
677
+ def is_cf_contig(specs):
678
+ is_c_contig = is_f_contig = False
679
+
680
+ if len(specs) == 1 and specs == [('direct', 'contig')]:
681
+ is_c_contig = True
682
+
683
+ elif (specs[-1] == ('direct','contig') and
684
+ all(axis == ('direct','follow') for axis in specs[:-1])):
685
+ # c_contiguous: 'follow', 'follow', ..., 'follow', 'contig'
686
+ is_c_contig = True
687
+
688
+ elif (len(specs) > 1 and
689
+ specs[0] == ('direct','contig') and
690
+ all(axis == ('direct','follow') for axis in specs[1:])):
691
+ # f_contiguous: 'contig', 'follow', 'follow', ..., 'follow'
692
+ is_f_contig = True
693
+
694
+ return is_c_contig, is_f_contig
695
+
696
+
697
+ def get_mode(specs):
698
+ is_c_contig, is_f_contig = is_cf_contig(specs)
699
+
700
+ if is_c_contig:
701
+ return 'c'
702
+ elif is_f_contig:
703
+ return 'fortran'
704
+
705
+ for access, packing in specs:
706
+ if access in ('ptr', 'full'):
707
+ return 'full'
708
+
709
+ return 'strided'
710
+
711
+ view_constant_to_access_packing = {
712
+ 'generic': ('full', 'strided'),
713
+ 'strided': ('direct', 'strided'),
714
+ 'indirect': ('ptr', 'strided'),
715
+ 'generic_contiguous': ('full', 'contig'),
716
+ 'contiguous': ('direct', 'contig'),
717
+ 'indirect_contiguous': ('ptr', 'contig'),
718
+ }
719
+
720
+ def validate_axes_specs(positions, specs, is_c_contig, is_f_contig):
721
+
722
+ packing_specs = ('contig', 'strided', 'follow')
723
+ access_specs = ('direct', 'ptr', 'full')
724
+
725
+ # is_c_contig, is_f_contig = is_cf_contig(specs)
726
+
727
+ has_contig = has_follow = has_strided = has_generic_contig = False
728
+
729
+ last_indirect_dimension = -1
730
+ for idx, (access, packing) in enumerate(specs):
731
+ if access == 'ptr':
732
+ last_indirect_dimension = idx
733
+
734
+ for idx, (pos, (access, packing)) in enumerate(zip(positions, specs)):
735
+
736
+ if not (access in access_specs and
737
+ packing in packing_specs):
738
+ raise CompileError(pos, "Invalid axes specification.")
739
+
740
+ if packing == 'strided':
741
+ has_strided = True
742
+ elif packing == 'contig':
743
+ if has_contig:
744
+ raise CompileError(pos, "Only one direct contiguous "
745
+ "axis may be specified.")
746
+
747
+ valid_contig_dims = last_indirect_dimension + 1, len(specs) - 1
748
+ if idx not in valid_contig_dims and access != 'ptr':
749
+ if last_indirect_dimension + 1 != len(specs) - 1:
750
+ dims = "dimensions %d and %d" % valid_contig_dims
751
+ else:
752
+ dims = "dimension %d" % valid_contig_dims[0]
753
+
754
+ raise CompileError(pos, "Only %s may be contiguous and direct" % dims)
755
+
756
+ has_contig = access != 'ptr'
757
+ elif packing == 'follow':
758
+ if has_strided:
759
+ raise CompileError(pos, "A memoryview cannot have both follow and strided axis specifiers.")
760
+ if not (is_c_contig or is_f_contig):
761
+ raise CompileError(pos, "Invalid use of the follow specifier.")
762
+
763
+ if access in ('ptr', 'full'):
764
+ has_strided = False
765
+
766
+ def _get_resolved_spec(env, spec):
767
+ # spec must be a NameNode or an AttributeNode
768
+ if isinstance(spec, NameNode):
769
+ return _resolve_NameNode(env, spec)
770
+ elif isinstance(spec, AttributeNode):
771
+ return _resolve_AttributeNode(env, spec)
772
+ else:
773
+ raise CompileError(spec.pos, INVALID_ERR)
774
+
775
+ def _resolve_NameNode(env, node):
776
+ try:
777
+ resolved_name = env.lookup(node.name).name
778
+ except AttributeError:
779
+ raise CompileError(node.pos, INVALID_ERR)
780
+
781
+ viewscope = env.context.cython_scope.viewscope
782
+ entry = viewscope.lookup(resolved_name)
783
+ if entry is None:
784
+ raise CompileError(node.pos, NOT_CIMPORTED_ERR)
785
+
786
+ return entry
787
+
788
+ def _resolve_AttributeNode(env, node):
789
+ path = []
790
+ while isinstance(node, AttributeNode):
791
+ path.insert(0, node.attribute)
792
+ node = node.obj
793
+ if isinstance(node, NameNode):
794
+ path.insert(0, node.name)
795
+ else:
796
+ raise CompileError(node.pos, EXPR_ERR)
797
+ modnames = path[:-1]
798
+ # must be at least 1 module name, o/w not an AttributeNode.
799
+ assert modnames
800
+
801
+ scope = env
802
+ for modname in modnames:
803
+ mod = scope.lookup(modname)
804
+ if not mod or not mod.as_module:
805
+ raise CompileError(
806
+ node.pos, "undeclared name not builtin: %s" % modname)
807
+ scope = mod.as_module
808
+
809
+ entry = scope.lookup(path[-1])
810
+ if not entry:
811
+ raise CompileError(node.pos, "No such attribute '%s'" % path[-1])
812
+
813
+ return entry
814
+
815
+ #
816
+ ### Utility loading
817
+ #
818
+
819
+ def load_memview_cy_utility(util_code_name, context=None, **kwargs):
820
+ return CythonUtilityCode.load(util_code_name, "MemoryView.pyx",
821
+ context=context, **kwargs)
822
+
823
+ def load_memview_c_utility(
824
+ util_code_name, util_code_filename="MemoryView_C.c",
825
+ *,
826
+ context=None, **kwargs):
827
+ if context is None:
828
+ return UtilityCode.load(util_code_name, util_code_filename, **kwargs)
829
+ else:
830
+ return TempitaUtilityCode.load(util_code_name, util_code_filename,
831
+ context=context, **kwargs)
832
+
833
+ def use_cython_array_utility_code(env):
834
+ if env.context.shared_utility_qualified_name:
835
+ return
836
+ cython_scope = env.context.cython_scope
837
+ cython_scope.load_cythonscope()
838
+ cython_scope.viewscope.lookup('array_cwrapper').used = True
839
+
840
+ template_context = {
841
+ 'max_dims': Options.buffer_max_dims,
842
+ 'memviewslice_name': Naming.memviewslice_cname,
843
+ 'memslice_init': PyrexTypes.MemoryViewSliceType.default_value,
844
+ 'THREAD_LOCKS_PREALLOCATED': 8,
845
+ }
846
+
847
+ def _get_memviewslice_declare_code():
848
+ memviewslice_declare_code = load_memview_c_utility(
849
+ "MemviewSliceStruct",
850
+ context=template_context,
851
+ requires=[])
852
+ return memviewslice_declare_code
853
+
854
+ atomic_utility = load_memview_c_utility(
855
+ "Atomics", util_code_filename="Synchronization.c", context=template_context)
856
+
857
+ memviewslice_index_helpers = load_memview_c_utility("MemviewSliceIndex")
858
+
859
+ def _get_typeinfo_to_format_code():
860
+ return load_memview_cy_utility(
861
+ "BufferFormatFromTypeInfo", requires=[Buffer._typeinfo_to_format_code])
862
+
863
+ def get_typeinfo_to_format_code(shared_utility_qualified_name):
864
+ if shared_utility_qualified_name:
865
+ return CythonSharedUtilityCode(
866
+ 'BufferFormatFromTypeInfo.pxd',
867
+ shared_utility_qualified_name,
868
+ template_context=template_context,
869
+ requires=[])
870
+ else:
871
+ return _get_typeinfo_to_format_code()
872
+
873
+
874
+ is_contig_utility = load_memview_c_utility("MemviewSliceIsContig")
875
+ overlapping_utility = load_memview_c_utility("OverlappingSlices")
876
+ refcount_utility = load_memview_c_utility("MemviewRefcount")
877
+ slice_init_utility = load_memview_c_utility("MemviewSliceInit")
878
+ memviewslice_declare_code = load_memview_c_utility("MemviewSliceStruct", context=template_context)
879
+ copy_contents_new_utility = load_memview_c_utility("MemviewSliceCopy")
880
+ slice_memviewslice_utility = load_memview_c_utility("SliceMemoryviewSlice")
881
+
882
+
883
+ @Utils.cached_function
884
+ def _get_memoryview_utility_code():
885
+ memoryview_utility_code = load_memview_cy_utility(
886
+ "View.MemoryView",
887
+ context=template_context,
888
+ requires=[
889
+ Buffer.buffer_struct_declare_code,
890
+ Buffer.buffer_formats_declare_code,
891
+ memviewslice_declare_code,
892
+ refcount_utility,
893
+ atomic_utility,
894
+ is_contig_utility,
895
+ overlapping_utility,
896
+ copy_contents_new_utility,
897
+ slice_memviewslice_utility,
898
+ ],
899
+ )
900
+
901
+ return memoryview_utility_code
902
+
903
+
904
+ @Utils.cached_function
905
+ def _get_memoryview_shared_utility_code(shared_utility_qualified_name):
906
+ shared_utility_code = CythonSharedUtilityCode(
907
+ 'MemoryView.pxd',
908
+ shared_utility_qualified_name,
909
+ template_context=template_context,
910
+ requires=[
911
+ Buffer.buffer_struct_declare_code,
912
+ Buffer.buffer_formats_declare_code,
913
+ memviewslice_declare_code,
914
+ refcount_utility,
915
+ atomic_utility,
916
+ ],
917
+ )
918
+
919
+ return shared_utility_code
920
+
921
+ def get_view_utility_code(shared_utility_qualified_name):
922
+ if shared_utility_qualified_name:
923
+ return _get_memoryview_shared_utility_code(shared_utility_qualified_name)
924
+ else:
925
+ return _get_memoryview_utility_code()
926
+
927
+
928
+ view_utility_allowlist = ('array', 'memoryview', 'array_cwrapper',
929
+ 'generic', 'strided', 'indirect', 'contiguous',
930
+ 'indirect_contiguous')