Cython 3.1.0a1__py3-none-any.whl

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