Cython 3.1.0__py3-none-any.whl

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