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,1481 @@
1
+ #################### View.MemoryView ####################
2
+
3
+ # cython: language_level=3
4
+ # cython: binding=False
5
+
6
+ # This utility provides cython.array and cython.view.memoryview
7
+
8
+ from __future__ import absolute_import
9
+
10
+ cimport cython
11
+
12
+ # from cpython cimport ...
13
+ cdef extern from "Python.h":
14
+ ctypedef struct PyObject
15
+ int PyIndex_Check(object)
16
+ PyObject *PyExc_IndexError
17
+ PyObject *PyExc_ValueError
18
+
19
+ cdef extern from "pythread.h":
20
+ ctypedef void *PyThread_type_lock
21
+
22
+ PyThread_type_lock PyThread_allocate_lock()
23
+ void PyThread_free_lock(PyThread_type_lock)
24
+
25
+ cdef extern from "<string.h>":
26
+ void *memset(void *b, int c, size_t len)
27
+
28
+ cdef extern from *:
29
+ bint __PYX_CYTHON_ATOMICS_ENABLED()
30
+ bint __PYX_GET_CYTHON_COMPILING_IN_CPYTHON_FREETHREADING()
31
+ int PyObject_GetBuffer(object, Py_buffer *, int) except -1
32
+ void PyBuffer_Release(Py_buffer *)
33
+
34
+ ctypedef struct PyObject
35
+ ctypedef Py_ssize_t Py_intptr_t
36
+ void Py_INCREF(PyObject *)
37
+ void Py_DECREF(PyObject *)
38
+
39
+ void* PyMem_Malloc(size_t n)
40
+ void PyMem_Free(void *p)
41
+ void* PyObject_Malloc(size_t n)
42
+ void PyObject_Free(void *p)
43
+
44
+ cdef struct __pyx_memoryview "__pyx_memoryview_obj":
45
+ Py_buffer view
46
+ PyObject *obj
47
+ const __Pyx_TypeInfo *typeinfo
48
+
49
+ ctypedef struct {{memviewslice_name}}:
50
+ __pyx_memoryview *memview
51
+ char *data
52
+ Py_ssize_t shape[{{max_dims}}]
53
+ Py_ssize_t strides[{{max_dims}}]
54
+ Py_ssize_t suboffsets[{{max_dims}}]
55
+
56
+ void __PYX_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil)
57
+ void __PYX_XCLEAR_MEMVIEW({{memviewslice_name}} *memslice, int have_gil)
58
+
59
+ ctypedef struct __pyx_buffer "Py_buffer":
60
+ PyObject *obj
61
+
62
+ PyObject *Py_None
63
+
64
+ cdef enum:
65
+ PyBUF_C_CONTIGUOUS,
66
+ PyBUF_F_CONTIGUOUS,
67
+ PyBUF_ANY_CONTIGUOUS
68
+ PyBUF_FORMAT
69
+ PyBUF_WRITABLE
70
+ PyBUF_STRIDES
71
+ PyBUF_INDIRECT
72
+ PyBUF_ND
73
+ PyBUF_RECORDS
74
+ PyBUF_RECORDS_RO
75
+
76
+ ctypedef struct __Pyx_TypeInfo:
77
+ pass
78
+
79
+ cdef extern from *:
80
+ ctypedef int __pyx_atomic_int_type
81
+ {{memviewslice_name}} slice_copy_contig "__pyx_memoryview_copy_new_contig"(
82
+ {{memviewslice_name}} *from_mvs,
83
+ const char *mode, int ndim,
84
+ size_t sizeof_dtype, int contig_flag,
85
+ bint dtype_is_object) except * nogil
86
+ bint slice_is_contig "__pyx_memviewslice_is_contig" (
87
+ {{memviewslice_name}} mvs, char order, int ndim) nogil
88
+ bint slices_overlap "__pyx_slices_overlap" ({{memviewslice_name}} *slice1,
89
+ {{memviewslice_name}} *slice2,
90
+ int ndim, size_t itemsize) nogil
91
+
92
+
93
+ cdef extern from "<stdlib.h>":
94
+ void *malloc(size_t) nogil
95
+ void free(void *) nogil
96
+ void *memcpy(void *dest, void *src, size_t n) nogil
97
+
98
+ # the sequence abstract base class
99
+ cdef object __pyx_collections_abc_Sequence "__pyx_collections_abc_Sequence"
100
+ try:
101
+ __pyx_collections_abc_Sequence = __import__("collections.abc").abc.Sequence
102
+ except:
103
+ # it isn't a big problem if this fails
104
+ __pyx_collections_abc_Sequence = None
105
+
106
+ #
107
+ ### cython.array class
108
+ #
109
+
110
+ @cython.collection_type("sequence")
111
+ @cname("__pyx_array")
112
+ cdef class array:
113
+
114
+ cdef:
115
+ char *data
116
+ Py_ssize_t len
117
+ char *format
118
+ int ndim
119
+ Py_ssize_t *_shape
120
+ Py_ssize_t *_strides
121
+ Py_ssize_t itemsize
122
+ unicode mode # FIXME: this should have been a simple 'char'
123
+ bytes _format
124
+ void (*callback_free_data)(void *data) noexcept
125
+ # cdef object _memview
126
+ cdef bint free_data
127
+ cdef bint dtype_is_object
128
+
129
+ def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
130
+ mode="c", bint allocate_buffer=True):
131
+
132
+ cdef int idx
133
+ cdef Py_ssize_t dim
134
+
135
+ self.ndim = <int> len(shape)
136
+ self.itemsize = itemsize
137
+
138
+ if not self.ndim:
139
+ raise ValueError, "Empty shape tuple for cython.array"
140
+
141
+ if itemsize <= 0:
142
+ raise ValueError, "itemsize <= 0 for cython.array"
143
+
144
+ if not isinstance(format, bytes):
145
+ format = format.encode('ASCII')
146
+ self._format = format # keep a reference to the byte string
147
+ self.format = self._format
148
+
149
+ # use single malloc() for both shape and strides
150
+ self._shape = <Py_ssize_t *> PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
151
+ self._strides = self._shape + self.ndim
152
+
153
+ if not self._shape:
154
+ raise MemoryError, "unable to allocate shape and strides."
155
+
156
+ # cdef Py_ssize_t dim, stride
157
+ for idx, dim in enumerate(shape):
158
+ if dim <= 0:
159
+ raise ValueError, f"Invalid shape in axis {idx}: {dim}."
160
+ self._shape[idx] = dim
161
+
162
+ cdef char order
163
+ if mode == 'c':
164
+ order = b'C'
165
+ self.mode = u'c'
166
+ elif mode == 'fortran':
167
+ order = b'F'
168
+ self.mode = u'fortran'
169
+ else:
170
+ raise ValueError, f"Invalid mode, expected 'c' or 'fortran', got {mode}"
171
+
172
+ self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order)
173
+
174
+ self.free_data = allocate_buffer
175
+ self.dtype_is_object = format == b'O'
176
+
177
+ if allocate_buffer:
178
+ _allocate_buffer(self)
179
+
180
+ @cname('getbuffer')
181
+ def __getbuffer__(self, Py_buffer *info, int flags):
182
+ cdef int bufmode = -1
183
+ if flags & (PyBUF_C_CONTIGUOUS | PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS):
184
+ if self.mode == u"c":
185
+ bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
186
+ elif self.mode == u"fortran":
187
+ bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
188
+ if not (flags & bufmode):
189
+ raise ValueError, "Can only create a buffer that is contiguous in memory."
190
+ info.buf = self.data
191
+ info.len = self.len
192
+
193
+ if flags & PyBUF_STRIDES:
194
+ info.ndim = self.ndim
195
+ info.shape = self._shape
196
+ info.strides = self._strides
197
+ else:
198
+ info.ndim = 1
199
+ info.shape = &self.len if flags & PyBUF_ND else NULL
200
+ info.strides = NULL
201
+
202
+ info.suboffsets = NULL
203
+ info.itemsize = self.itemsize
204
+ info.readonly = 0
205
+ info.format = self.format if flags & PyBUF_FORMAT else NULL
206
+ info.obj = self
207
+
208
+ def __dealloc__(array self):
209
+ if self.callback_free_data != NULL:
210
+ self.callback_free_data(self.data)
211
+ elif self.free_data and self.data is not NULL:
212
+ if self.dtype_is_object:
213
+ refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, inc=False)
214
+ free(self.data)
215
+ PyObject_Free(self._shape)
216
+
217
+ @property
218
+ def memview(self):
219
+ return self.get_memview()
220
+
221
+ @cname('get_memview')
222
+ cdef get_memview(self):
223
+ flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
224
+ return memoryview(self, flags, self.dtype_is_object)
225
+
226
+ def __len__(self):
227
+ return self._shape[0]
228
+
229
+ def __getattr__(self, attr):
230
+ return getattr(self.memview, attr)
231
+
232
+ def __getitem__(self, item):
233
+ return self.memview[item]
234
+
235
+ def __setitem__(self, item, value):
236
+ self.memview[item] = value
237
+
238
+ # Sequence methods
239
+ try:
240
+ count = __pyx_collections_abc_Sequence.count
241
+ index = __pyx_collections_abc_Sequence.index
242
+ except:
243
+ pass
244
+
245
+ @cname("__pyx_array_allocate_buffer")
246
+ cdef int _allocate_buffer(array self) except -1:
247
+ # use malloc() for backwards compatibility
248
+ # in case external code wants to change the data pointer
249
+ cdef Py_ssize_t i
250
+ cdef PyObject **p
251
+
252
+ self.free_data = True
253
+ self.data = <char *>malloc(self.len)
254
+ if not self.data:
255
+ raise MemoryError, "unable to allocate array data."
256
+
257
+ if self.dtype_is_object:
258
+ p = <PyObject **> self.data
259
+ for i in range(self.len // self.itemsize):
260
+ p[i] = Py_None
261
+ Py_INCREF(Py_None)
262
+ return 0
263
+
264
+
265
+ @cname("__pyx_array_new")
266
+ cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, const char *c_mode, char *buf):
267
+ cdef array result
268
+ cdef str mode = "fortran" if c_mode[0] == b'f' else "c" # this often comes from a constant C string.
269
+
270
+ if buf is NULL:
271
+ result = array.__new__(array, shape, itemsize, format, mode)
272
+ else:
273
+ result = array.__new__(array, shape, itemsize, format, mode, allocate_buffer=False)
274
+ result.data = buf
275
+
276
+ return result
277
+
278
+
279
+ #
280
+ ### Memoryview constants and cython.view.memoryview class
281
+ #
282
+
283
+ # Disable generic_contiguous, as it makes trouble verifying contiguity:
284
+ # - 'contiguous' or '::1' means the dimension is contiguous with dtype
285
+ # - 'indirect_contiguous' means a contiguous list of pointers
286
+ # - dtype contiguous must be contiguous in the first or last dimension
287
+ # from the start, or from the dimension following the last indirect dimension
288
+ #
289
+ # e.g.
290
+ # int[::indirect_contiguous, ::contiguous, :]
291
+ #
292
+ # is valid (list of pointers to 2d fortran-contiguous array), but
293
+ #
294
+ # int[::generic_contiguous, ::contiguous, :]
295
+ #
296
+ # would mean you'd have assert dimension 0 to be indirect (and pointer contiguous) at runtime.
297
+ # So it doesn't bring any performance benefit, and it's only confusing.
298
+
299
+ @cname('__pyx_MemviewEnum')
300
+ cdef class Enum(object):
301
+ cdef object name
302
+ def __init__(self, name):
303
+ self.name = name
304
+ def __repr__(self):
305
+ return self.name
306
+
307
+ cdef generic = Enum("<strided and direct or indirect>")
308
+ cdef strided = Enum("<strided and direct>") # default
309
+ cdef indirect = Enum("<strided and indirect>")
310
+ # Disable generic_contiguous, as it is a troublemaker
311
+ #cdef generic_contiguous = Enum("<contiguous and direct or indirect>")
312
+ cdef contiguous = Enum("<contiguous and direct>")
313
+ cdef indirect_contiguous = Enum("<contiguous and indirect>")
314
+
315
+ # 'follow' is implied when the first or last axis is ::1
316
+
317
+
318
+ # pre-allocate thread locks for reuse
319
+ ## note that this could be implemented in a more beautiful way in "normal" Cython,
320
+ ## but this code gets merged into the user module and not everything works there.
321
+ cdef int __pyx_memoryview_thread_locks_used = 0
322
+ cdef PyThread_type_lock[{{THREAD_LOCKS_PREALLOCATED}}] __pyx_memoryview_thread_locks = [
323
+ {{for _ in range(THREAD_LOCKS_PREALLOCATED)}}
324
+ PyThread_allocate_lock(),
325
+ {{endfor}}
326
+ ]
327
+
328
+
329
+ @cname('__pyx_memoryview')
330
+ cdef class memoryview:
331
+
332
+ cdef object obj
333
+ cdef object _size
334
+ cdef object _array_interface
335
+ cdef PyThread_type_lock lock
336
+ cdef __pyx_atomic_int_type acquisition_count
337
+ cdef Py_buffer view
338
+ cdef int flags
339
+ cdef bint dtype_is_object
340
+ cdef const __Pyx_TypeInfo *typeinfo
341
+
342
+ def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
343
+ self.obj = obj
344
+ self.flags = flags
345
+ if type(self) is memoryview or obj is not None:
346
+ PyObject_GetBuffer(obj, &self.view, flags)
347
+ if <PyObject *> self.view.obj == NULL:
348
+ (<__pyx_buffer *> &self.view).obj = Py_None
349
+ Py_INCREF(Py_None)
350
+
351
+ if not __PYX_CYTHON_ATOMICS_ENABLED():
352
+ global __pyx_memoryview_thread_locks_used
353
+ if (__pyx_memoryview_thread_locks_used < {{THREAD_LOCKS_PREALLOCATED}} and
354
+ # preallocated locks cannot be made thread-safe in freethreading
355
+ not __PYX_GET_CYTHON_COMPILING_IN_CPYTHON_FREETHREADING()):
356
+ self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]
357
+ __pyx_memoryview_thread_locks_used += 1
358
+ if self.lock is NULL:
359
+ self.lock = PyThread_allocate_lock()
360
+ if self.lock is NULL:
361
+ raise MemoryError
362
+
363
+ if flags & PyBUF_FORMAT:
364
+ self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0')
365
+ else:
366
+ self.dtype_is_object = dtype_is_object
367
+
368
+ assert <Py_intptr_t><void*>(&self.acquisition_count) % sizeof(__pyx_atomic_int_type) == 0
369
+ self.typeinfo = NULL
370
+
371
+ def __dealloc__(memoryview self):
372
+ if self.obj is not None:
373
+ PyBuffer_Release(&self.view)
374
+ elif (<__pyx_buffer *> &self.view).obj == Py_None:
375
+ # Undo the incref in __cinit__() above.
376
+ (<__pyx_buffer *> &self.view).obj = NULL
377
+ Py_DECREF(Py_None)
378
+
379
+ cdef int i
380
+ global __pyx_memoryview_thread_locks_used
381
+ if self.lock != NULL:
382
+ for i in range(0 if __PYX_GET_CYTHON_COMPILING_IN_CPYTHON_FREETHREADING() else __pyx_memoryview_thread_locks_used):
383
+ if __pyx_memoryview_thread_locks[i] is self.lock:
384
+ __pyx_memoryview_thread_locks_used -= 1
385
+ if i != __pyx_memoryview_thread_locks_used:
386
+ __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = (
387
+ __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i])
388
+ break
389
+ else:
390
+ PyThread_free_lock(self.lock)
391
+
392
+ cdef char *get_item_pointer(memoryview self, object index) except NULL:
393
+ cdef Py_ssize_t dim
394
+ cdef char *itemp = <char *> self.view.buf
395
+
396
+ for dim, idx in enumerate(index):
397
+ itemp = pybuffer_index(&self.view, itemp, idx, dim)
398
+
399
+ return itemp
400
+
401
+ #@cname('__pyx_memoryview_getitem')
402
+ def __getitem__(memoryview self, object index):
403
+ if index is Ellipsis:
404
+ return self
405
+
406
+ have_slices, indices = _unellipsify(index, self.view.ndim)
407
+
408
+ cdef char *itemp
409
+ if have_slices:
410
+ return memview_slice(self, indices)
411
+ else:
412
+ itemp = self.get_item_pointer(indices)
413
+ return self.convert_item_to_object(itemp)
414
+
415
+ def __setitem__(memoryview self, object index, object value):
416
+ if self.view.readonly:
417
+ raise TypeError, "Cannot assign to read-only memoryview"
418
+
419
+ have_slices, index = _unellipsify(index, self.view.ndim)
420
+
421
+ if have_slices:
422
+ obj = self.is_slice(value)
423
+ if obj is not None:
424
+ self.setitem_slice_assignment(self[index], obj)
425
+ else:
426
+ self.setitem_slice_assign_scalar(self[index], value)
427
+ else:
428
+ self.setitem_indexed(index, value)
429
+
430
+ cdef is_slice(self, obj):
431
+ if not isinstance(obj, memoryview):
432
+ try:
433
+ obj = memoryview(obj, self.flags & ~PyBUF_WRITABLE | PyBUF_ANY_CONTIGUOUS,
434
+ self.dtype_is_object)
435
+ except TypeError:
436
+ return None
437
+
438
+ return obj
439
+
440
+ cdef setitem_slice_assignment(self, dst, src):
441
+ cdef {{memviewslice_name}} dst_slice
442
+ cdef {{memviewslice_name}} src_slice
443
+ cdef {{memviewslice_name}} msrc = get_slice_from_memview(src, &src_slice)[0]
444
+ cdef {{memviewslice_name}} mdst = get_slice_from_memview(dst, &dst_slice)[0]
445
+
446
+ memoryview_copy_contents(msrc, mdst, src.ndim, dst.ndim, self.dtype_is_object)
447
+
448
+ cdef setitem_slice_assign_scalar(self, memoryview dst, value):
449
+ cdef int array[128]
450
+ cdef void *tmp = NULL
451
+ cdef void *item
452
+
453
+ cdef {{memviewslice_name}} *dst_slice
454
+ cdef {{memviewslice_name}} tmp_slice
455
+ dst_slice = get_slice_from_memview(dst, &tmp_slice)
456
+
457
+ if <size_t>self.view.itemsize > sizeof(array):
458
+ tmp = PyMem_Malloc(self.view.itemsize)
459
+ if tmp == NULL:
460
+ raise MemoryError
461
+ item = tmp
462
+ else:
463
+ item = <void *> array
464
+
465
+ try:
466
+ if self.dtype_is_object:
467
+ (<PyObject **> item)[0] = <PyObject *> value
468
+ else:
469
+ self.assign_item_from_object(<char *> item, value)
470
+
471
+ # It would be easy to support indirect dimensions, but it's easier
472
+ # to disallow :)
473
+ if self.view.suboffsets != NULL:
474
+ assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
475
+ slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
476
+ item, self.dtype_is_object)
477
+ finally:
478
+ PyMem_Free(tmp)
479
+
480
+ cdef setitem_indexed(self, index, value):
481
+ cdef char *itemp = self.get_item_pointer(index)
482
+ self.assign_item_from_object(itemp, value)
483
+
484
+ cdef convert_item_to_object(self, char *itemp):
485
+ """Only used if instantiated manually by the user, or if Cython doesn't
486
+ know how to convert the type"""
487
+ import struct
488
+ cdef bytes bytesitem
489
+ # Do a manual and complete check here instead of this easy hack
490
+ bytesitem = itemp[:self.view.itemsize]
491
+ try:
492
+ result = struct.unpack(self.view.format, bytesitem)
493
+ except struct.error:
494
+ raise ValueError, "Unable to convert item to object"
495
+ else:
496
+ if len(self.view.format) == 1:
497
+ return result[0]
498
+ return result
499
+
500
+ cdef assign_item_from_object(self, char *itemp, object value):
501
+ """Only used if instantiated manually by the user, or if Cython doesn't
502
+ know how to convert the type"""
503
+ import struct
504
+ cdef char c
505
+ cdef bytes bytesvalue
506
+ cdef Py_ssize_t i
507
+
508
+ if isinstance(value, tuple):
509
+ bytesvalue = struct.pack(self.view.format, *value)
510
+ else:
511
+ bytesvalue = struct.pack(self.view.format, value)
512
+
513
+ for i, c in enumerate(bytesvalue):
514
+ itemp[i] = c
515
+
516
+ @cname('getbuffer')
517
+ def __getbuffer__(self, Py_buffer *info, int flags):
518
+ if flags & PyBUF_WRITABLE and self.view.readonly:
519
+ raise ValueError, "Cannot create writable memory view from read-only memoryview"
520
+
521
+ if flags & PyBUF_ND:
522
+ info.shape = self.view.shape
523
+ else:
524
+ info.shape = NULL
525
+
526
+ if flags & PyBUF_STRIDES:
527
+ info.strides = self.view.strides
528
+ else:
529
+ info.strides = NULL
530
+
531
+ if flags & PyBUF_INDIRECT:
532
+ info.suboffsets = self.view.suboffsets
533
+ else:
534
+ info.suboffsets = NULL
535
+
536
+ if flags & PyBUF_FORMAT:
537
+ info.format = self.view.format
538
+ else:
539
+ info.format = NULL
540
+
541
+ info.buf = self.view.buf
542
+ info.ndim = self.view.ndim
543
+ info.itemsize = self.view.itemsize
544
+ info.len = self.view.len
545
+ info.readonly = self.view.readonly
546
+ info.obj = self
547
+
548
+ # Some properties that have the same semantics as in NumPy
549
+ @property
550
+ def T(self):
551
+ cdef _memoryviewslice result = memoryview_copy(self)
552
+ transpose_memslice(&result.from_slice)
553
+ return result
554
+
555
+ @property
556
+ def base(self):
557
+ return self._get_base()
558
+
559
+ cdef _get_base(self):
560
+ return self.obj
561
+
562
+ @property
563
+ def shape(self):
564
+ return tuple([length for length in self.view.shape[:self.view.ndim]])
565
+
566
+ @property
567
+ def strides(self):
568
+ if self.view.strides == NULL:
569
+ # Note: we always ask for strides, so if this is not set it's a bug
570
+ raise ValueError, "Buffer view does not expose strides"
571
+
572
+ return tuple([stride for stride in self.view.strides[:self.view.ndim]])
573
+
574
+ @property
575
+ def suboffsets(self):
576
+ if self.view.suboffsets == NULL:
577
+ return (-1,) * self.view.ndim
578
+
579
+ return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]])
580
+
581
+ @property
582
+ def ndim(self):
583
+ return self.view.ndim
584
+
585
+ @property
586
+ def itemsize(self):
587
+ return self.view.itemsize
588
+
589
+ @property
590
+ def nbytes(self):
591
+ return self.size * self.view.itemsize
592
+
593
+ @property
594
+ def size(self):
595
+ if self._size is None:
596
+ result = 1
597
+
598
+ for length in self.view.shape[:self.view.ndim]:
599
+ result *= length
600
+
601
+ self._size = result
602
+
603
+ return self._size
604
+
605
+ def __len__(self):
606
+ if self.view.ndim >= 1:
607
+ return self.view.shape[0]
608
+
609
+ return 0
610
+
611
+ def __repr__(self):
612
+ return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
613
+ id(self))
614
+
615
+ def __str__(self):
616
+ return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
617
+
618
+ # Support the same attributes as memoryview slices
619
+ def is_c_contig(self):
620
+ cdef {{memviewslice_name}} *mslice
621
+ cdef {{memviewslice_name}} tmp
622
+ mslice = get_slice_from_memview(self, &tmp)
623
+ return slice_is_contig(mslice[0], 'C', self.view.ndim)
624
+
625
+ def is_f_contig(self):
626
+ cdef {{memviewslice_name}} *mslice
627
+ cdef {{memviewslice_name}} tmp
628
+ mslice = get_slice_from_memview(self, &tmp)
629
+ return slice_is_contig(mslice[0], 'F', self.view.ndim)
630
+
631
+ def copy(self):
632
+ cdef {{memviewslice_name}} mslice
633
+ cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
634
+
635
+ slice_copy(self, &mslice)
636
+ mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
637
+ self.view.itemsize,
638
+ flags|PyBUF_C_CONTIGUOUS,
639
+ self.dtype_is_object)
640
+
641
+ return memoryview_copy_from_slice(self, &mslice)
642
+
643
+ def copy_fortran(self):
644
+ cdef {{memviewslice_name}} src, dst
645
+ cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
646
+
647
+ slice_copy(self, &src)
648
+ dst = slice_copy_contig(&src, "fortran", self.view.ndim,
649
+ self.view.itemsize,
650
+ flags|PyBUF_F_CONTIGUOUS,
651
+ self.dtype_is_object)
652
+
653
+ return memoryview_copy_from_slice(self, &dst)
654
+
655
+
656
+ @cname('__pyx_memoryview_new')
657
+ cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, const __Pyx_TypeInfo *typeinfo):
658
+ cdef memoryview result = memoryview(o, flags, dtype_is_object)
659
+ result.typeinfo = typeinfo
660
+ return result
661
+
662
+ @cname('__pyx_memoryview_check')
663
+ cdef inline bint memoryview_check(object o) noexcept:
664
+ return isinstance(o, memoryview)
665
+
666
+ cdef tuple _unellipsify(object index, int ndim):
667
+ """
668
+ Replace all ellipses with full slices and fill incomplete indices with
669
+ full slices.
670
+ """
671
+ cdef Py_ssize_t idx
672
+ tup = <tuple>index if isinstance(index, tuple) else (index,)
673
+
674
+ result = [slice(None)] * ndim
675
+ have_slices = False
676
+ seen_ellipsis = False
677
+ idx = 0
678
+ for item in tup:
679
+ if item is Ellipsis:
680
+ if not seen_ellipsis:
681
+ idx += ndim - len(tup)
682
+ seen_ellipsis = True
683
+ have_slices = True
684
+ else:
685
+ if isinstance(item, slice):
686
+ have_slices = True
687
+ elif not PyIndex_Check(item):
688
+ raise TypeError, f"Cannot index with type '{type(item)}'"
689
+ result[idx] = item
690
+ idx += 1
691
+
692
+ nslices = ndim - idx
693
+ return have_slices or nslices, tuple(result)
694
+
695
+ cdef int assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim) except -1:
696
+ for suboffset in suboffsets[:ndim]:
697
+ if suboffset >= 0:
698
+ raise ValueError, "Indirect dimensions not supported"
699
+ return 0 # return type just used as an error flag
700
+
701
+ #
702
+ ### Slicing a memoryview
703
+ #
704
+
705
+ @cname('__pyx_memview_slice')
706
+ cdef memoryview memview_slice(memoryview memview, object indices):
707
+ cdef int new_ndim = 0, suboffset_dim = -1, dim
708
+ cdef bint negative_step
709
+ cdef {{memviewslice_name}} src, dst
710
+ cdef {{memviewslice_name}} *p_src
711
+
712
+ # dst is copied by value in memoryview_fromslice -- initialize it
713
+ # src is never copied
714
+ memset(&dst, 0, sizeof(dst))
715
+
716
+ cdef _memoryviewslice memviewsliceobj
717
+
718
+ assert memview.view.ndim > 0
719
+
720
+ if isinstance(memview, _memoryviewslice):
721
+ memviewsliceobj = memview
722
+ p_src = &memviewsliceobj.from_slice
723
+ else:
724
+ slice_copy(memview, &src)
725
+ p_src = &src
726
+
727
+ # Note: don't use variable src at this point
728
+ # SubNote: we should be able to declare variables in blocks...
729
+
730
+ # memoryview_fromslice() will inc our dst slice
731
+ dst.memview = p_src.memview
732
+ dst.data = p_src.data
733
+
734
+ # Put everything in temps to avoid this bloody warning:
735
+ # "Argument evaluation order in C function call is undefined and
736
+ # may not be as expected"
737
+ cdef {{memviewslice_name}} *p_dst = &dst
738
+ cdef int *p_suboffset_dim = &suboffset_dim
739
+ cdef Py_ssize_t start, stop, step, cindex
740
+ cdef bint have_start, have_stop, have_step
741
+
742
+ for dim, index in enumerate(indices):
743
+ if PyIndex_Check(index):
744
+ cindex = index
745
+ slice_memviewslice(
746
+ p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
747
+ dim, new_ndim, p_suboffset_dim,
748
+ cindex, 0, 0, # start, stop, step
749
+ 0, 0, 0, # have_{start,stop,step}
750
+ False)
751
+ elif index is None:
752
+ p_dst.shape[new_ndim] = 1
753
+ p_dst.strides[new_ndim] = 0
754
+ p_dst.suboffsets[new_ndim] = -1
755
+ new_ndim += 1
756
+ else:
757
+ start = index.start or 0
758
+ stop = index.stop or 0
759
+ step = index.step or 0
760
+
761
+ have_start = index.start is not None
762
+ have_stop = index.stop is not None
763
+ have_step = index.step is not None
764
+
765
+ slice_memviewslice(
766
+ p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
767
+ dim, new_ndim, p_suboffset_dim,
768
+ start, stop, step,
769
+ have_start, have_stop, have_step,
770
+ True)
771
+ new_ndim += 1
772
+
773
+ if isinstance(memview, _memoryviewslice):
774
+ return memoryview_fromslice(dst, new_ndim,
775
+ memviewsliceobj.to_object_func,
776
+ memviewsliceobj.to_dtype_func,
777
+ memview.dtype_is_object)
778
+ else:
779
+ return memoryview_fromslice(dst, new_ndim, NULL, NULL,
780
+ memview.dtype_is_object)
781
+
782
+
783
+ #
784
+ ### Slicing in a single dimension of a memoryviewslice
785
+ #
786
+
787
+ @cname('__pyx_memoryview_slice_memviewslice')
788
+ cdef int slice_memviewslice(
789
+ {{memviewslice_name}} *dst,
790
+ Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
791
+ int dim, int new_ndim, int *suboffset_dim,
792
+ Py_ssize_t start, Py_ssize_t stop, Py_ssize_t step,
793
+ int have_start, int have_stop, int have_step,
794
+ bint is_slice) except -1 nogil:
795
+ """
796
+ Create a new slice dst given slice src.
797
+
798
+ dim - the current src dimension (indexing will make dimensions
799
+ disappear)
800
+ new_dim - the new dst dimension
801
+ suboffset_dim - pointer to a single int initialized to -1 to keep track of
802
+ where slicing offsets should be added
803
+ """
804
+
805
+ cdef Py_ssize_t new_shape
806
+ cdef bint negative_step
807
+
808
+ if not is_slice:
809
+ # index is a normal integer-like index
810
+ if start < 0:
811
+ start += shape
812
+ if not 0 <= start < shape:
813
+ _err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim)
814
+ else:
815
+ # index is a slice
816
+ if have_step:
817
+ negative_step = step < 0
818
+ if step == 0:
819
+ _err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim)
820
+ else:
821
+ negative_step = False
822
+ step = 1
823
+
824
+ # check our bounds and set defaults
825
+ if have_start:
826
+ if start < 0:
827
+ start += shape
828
+ if start < 0:
829
+ start = 0
830
+ elif start >= shape:
831
+ if negative_step:
832
+ start = shape - 1
833
+ else:
834
+ start = shape
835
+ else:
836
+ if negative_step:
837
+ start = shape - 1
838
+ else:
839
+ start = 0
840
+
841
+ if have_stop:
842
+ if stop < 0:
843
+ stop += shape
844
+ if stop < 0:
845
+ stop = 0
846
+ elif stop > shape:
847
+ stop = shape
848
+ else:
849
+ if negative_step:
850
+ stop = -1
851
+ else:
852
+ stop = shape
853
+
854
+ # len = ceil( (stop - start) / step )
855
+ with cython.cdivision(True):
856
+ new_shape = (stop - start) // step
857
+
858
+ if (stop - start) - step * new_shape:
859
+ new_shape += 1
860
+
861
+ if new_shape < 0:
862
+ new_shape = 0
863
+
864
+ # shape/strides/suboffsets
865
+ dst.strides[new_ndim] = stride * step
866
+ dst.shape[new_ndim] = new_shape
867
+ dst.suboffsets[new_ndim] = suboffset
868
+
869
+ # Add the slicing or indexing offsets to the right suboffset or base data *
870
+ if suboffset_dim[0] < 0:
871
+ dst.data += start * stride
872
+ else:
873
+ dst.suboffsets[suboffset_dim[0]] += start * stride
874
+
875
+ if suboffset >= 0:
876
+ if not is_slice:
877
+ if new_ndim == 0:
878
+ dst.data = (<char **> dst.data)[0] + suboffset
879
+ else:
880
+ _err_dim(PyExc_IndexError, "All dimensions preceding dimension %d "
881
+ "must be indexed and not sliced", dim)
882
+ else:
883
+ suboffset_dim[0] = new_ndim
884
+
885
+ return 0
886
+
887
+ #
888
+ ### Index a memoryview
889
+ #
890
+ @cname('__pyx_pybuffer_index')
891
+ cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
892
+ Py_ssize_t dim) except NULL:
893
+ cdef Py_ssize_t shape, stride, suboffset = -1
894
+ cdef Py_ssize_t itemsize = view.itemsize
895
+ cdef char *resultp
896
+
897
+ if view.ndim == 0:
898
+ shape = view.len // itemsize
899
+ stride = itemsize
900
+ else:
901
+ shape = view.shape[dim]
902
+ stride = view.strides[dim]
903
+ if view.suboffsets != NULL:
904
+ suboffset = view.suboffsets[dim]
905
+
906
+ if index < 0:
907
+ index += view.shape[dim]
908
+ if index < 0:
909
+ raise IndexError, f"Out of bounds on buffer access (axis {dim})"
910
+
911
+ if index >= shape:
912
+ raise IndexError, f"Out of bounds on buffer access (axis {dim})"
913
+
914
+ resultp = bufp + index * stride
915
+ if suboffset >= 0:
916
+ resultp = (<char **> resultp)[0] + suboffset
917
+
918
+ return resultp
919
+
920
+ #
921
+ ### Transposing a memoryviewslice
922
+ #
923
+ @cname('__pyx_memslice_transpose')
924
+ cdef int transpose_memslice({{memviewslice_name}} *memslice) except -1 nogil:
925
+ cdef int ndim = memslice.memview.view.ndim
926
+
927
+ cdef Py_ssize_t *shape = memslice.shape
928
+ cdef Py_ssize_t *strides = memslice.strides
929
+
930
+ # reverse strides and shape
931
+ cdef int i, j
932
+ for i in range(ndim // 2):
933
+ j = ndim - 1 - i
934
+ strides[i], strides[j] = strides[j], strides[i]
935
+ shape[i], shape[j] = shape[j], shape[i]
936
+
937
+ if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
938
+ _err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions")
939
+
940
+ return 0
941
+
942
+ #
943
+ ### Creating new memoryview objects from slices and memoryviews
944
+ #
945
+ @cython.collection_type("sequence")
946
+ @cname('__pyx_memoryviewslice')
947
+ cdef class _memoryviewslice(memoryview):
948
+ "Internal class for passing memoryview slices to Python"
949
+
950
+ # We need this to keep our shape/strides/suboffset pointers valid
951
+ cdef {{memviewslice_name}} from_slice
952
+ # We need this only to print it's class' name
953
+ cdef object from_object
954
+
955
+ cdef object (*to_object_func)(char *)
956
+ cdef int (*to_dtype_func)(char *, object) except 0
957
+
958
+ def __dealloc__(self):
959
+ __PYX_XCLEAR_MEMVIEW(&self.from_slice, 1)
960
+
961
+ cdef convert_item_to_object(self, char *itemp):
962
+ if self.to_object_func != NULL:
963
+ return self.to_object_func(itemp)
964
+ else:
965
+ return memoryview.convert_item_to_object(self, itemp)
966
+
967
+ cdef assign_item_from_object(self, char *itemp, object value):
968
+ if self.to_dtype_func != NULL:
969
+ self.to_dtype_func(itemp, value)
970
+ else:
971
+ memoryview.assign_item_from_object(self, itemp, value)
972
+
973
+ cdef _get_base(self):
974
+ return self.from_object
975
+
976
+ # Sequence methods
977
+ try:
978
+ count = __pyx_collections_abc_Sequence.count
979
+ index = __pyx_collections_abc_Sequence.index
980
+ except:
981
+ pass
982
+
983
+ try:
984
+ if __pyx_collections_abc_Sequence:
985
+ # The main value of registering _memoryviewslice as a
986
+ # Sequence is that it can be used in structural pattern
987
+ # matching in Python 3.10+
988
+ __pyx_collections_abc_Sequence.register(_memoryviewslice)
989
+ __pyx_collections_abc_Sequence.register(array)
990
+ except:
991
+ pass # ignore failure, it's a minor issue
992
+
993
+ @cname('__pyx_memoryview_fromslice')
994
+ cdef memoryview_fromslice({{memviewslice_name}} memviewslice,
995
+ int ndim,
996
+ object (*to_object_func)(char *),
997
+ int (*to_dtype_func)(char *, object) except 0,
998
+ bint dtype_is_object):
999
+
1000
+ cdef _memoryviewslice result
1001
+
1002
+ if <PyObject *> memviewslice.memview == Py_None:
1003
+ return None
1004
+
1005
+ # assert 0 < ndim <= memviewslice.memview.view.ndim, (
1006
+ # ndim, memviewslice.memview.view.ndim)
1007
+
1008
+ result = _memoryviewslice.__new__(_memoryviewslice, None, 0, dtype_is_object)
1009
+
1010
+ result.from_slice = memviewslice
1011
+ __PYX_INC_MEMVIEW(&memviewslice, 1)
1012
+
1013
+ result.from_object = (<memoryview> memviewslice.memview)._get_base()
1014
+ result.typeinfo = memviewslice.memview.typeinfo
1015
+
1016
+ result.view = memviewslice.memview.view
1017
+ result.view.buf = <void *> memviewslice.data
1018
+ result.view.ndim = ndim
1019
+ (<__pyx_buffer *> &result.view).obj = Py_None
1020
+ Py_INCREF(Py_None)
1021
+
1022
+ if (<memoryview>memviewslice.memview).flags & PyBUF_WRITABLE:
1023
+ result.flags = PyBUF_RECORDS
1024
+ else:
1025
+ result.flags = PyBUF_RECORDS_RO
1026
+
1027
+ result.view.shape = <Py_ssize_t *> result.from_slice.shape
1028
+ result.view.strides = <Py_ssize_t *> result.from_slice.strides
1029
+
1030
+ # only set suboffsets if actually used, otherwise set to NULL to improve compatibility
1031
+ result.view.suboffsets = NULL
1032
+ for suboffset in result.from_slice.suboffsets[:ndim]:
1033
+ if suboffset >= 0:
1034
+ result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
1035
+ break
1036
+
1037
+ result.view.len = result.view.itemsize
1038
+ for length in result.view.shape[:ndim]:
1039
+ result.view.len *= length
1040
+
1041
+ result.to_object_func = to_object_func
1042
+ result.to_dtype_func = to_dtype_func
1043
+
1044
+ return result
1045
+
1046
+ @cname('__pyx_memoryview_get_slice_from_memoryview')
1047
+ cdef {{memviewslice_name}} *get_slice_from_memview(memoryview memview,
1048
+ {{memviewslice_name}} *mslice) except NULL:
1049
+ cdef _memoryviewslice obj
1050
+ if isinstance(memview, _memoryviewslice):
1051
+ obj = memview
1052
+ return &obj.from_slice
1053
+ else:
1054
+ slice_copy(memview, mslice)
1055
+ return mslice
1056
+
1057
+ @cname('__pyx_memoryview_slice_copy')
1058
+ cdef void slice_copy(memoryview memview, {{memviewslice_name}} *dst) noexcept:
1059
+ cdef int dim
1060
+ cdef (Py_ssize_t*) shape, strides, suboffsets
1061
+
1062
+ shape = memview.view.shape
1063
+ strides = memview.view.strides
1064
+ suboffsets = memview.view.suboffsets
1065
+
1066
+ dst.memview = <__pyx_memoryview *> memview
1067
+ dst.data = <char *> memview.view.buf
1068
+
1069
+ for dim in range(memview.view.ndim):
1070
+ dst.shape[dim] = shape[dim]
1071
+ dst.strides[dim] = strides[dim]
1072
+ dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1
1073
+
1074
+ @cname('__pyx_memoryview_copy_object')
1075
+ cdef memoryview_copy(memoryview memview):
1076
+ "Create a new memoryview object"
1077
+ cdef {{memviewslice_name}} memviewslice
1078
+ slice_copy(memview, &memviewslice)
1079
+ return memoryview_copy_from_slice(memview, &memviewslice)
1080
+
1081
+ @cname('__pyx_memoryview_copy_object_from_slice')
1082
+ cdef memoryview_copy_from_slice(memoryview memview, {{memviewslice_name}} *memviewslice):
1083
+ """
1084
+ Create a new memoryview object from a given memoryview object and slice.
1085
+ """
1086
+ cdef object (*to_object_func)(char *)
1087
+ cdef int (*to_dtype_func)(char *, object) except 0
1088
+
1089
+ if isinstance(memview, _memoryviewslice):
1090
+ to_object_func = (<_memoryviewslice> memview).to_object_func
1091
+ to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
1092
+ else:
1093
+ to_object_func = NULL
1094
+ to_dtype_func = NULL
1095
+
1096
+ return memoryview_fromslice(memviewslice[0], memview.view.ndim,
1097
+ to_object_func, to_dtype_func,
1098
+ memview.dtype_is_object)
1099
+
1100
+
1101
+ #
1102
+ ### Copy the contents of a memoryview slices
1103
+ #
1104
+ cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) noexcept nogil:
1105
+ return -arg if arg < 0 else arg
1106
+
1107
+ @cname('__pyx_get_best_slice_order')
1108
+ cdef char get_best_order({{memviewslice_name}} *mslice, int ndim) noexcept nogil:
1109
+ """
1110
+ Figure out the best memory access order for a given slice.
1111
+ """
1112
+ cdef int i
1113
+ cdef Py_ssize_t c_stride = 0
1114
+ cdef Py_ssize_t f_stride = 0
1115
+
1116
+ for i in range(ndim - 1, -1, -1):
1117
+ if mslice.shape[i] > 1:
1118
+ c_stride = mslice.strides[i]
1119
+ break
1120
+
1121
+ for i in range(ndim):
1122
+ if mslice.shape[i] > 1:
1123
+ f_stride = mslice.strides[i]
1124
+ break
1125
+
1126
+ if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
1127
+ return 'C'
1128
+ else:
1129
+ return 'F'
1130
+
1131
+ @cython.cdivision(True)
1132
+ cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides,
1133
+ char *dst_data, Py_ssize_t *dst_strides,
1134
+ Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
1135
+ int ndim, size_t itemsize) noexcept nogil:
1136
+ # Note: src_extent is 1 if we're broadcasting
1137
+ # dst_extent always >= src_extent as we don't do reductions
1138
+ cdef Py_ssize_t i
1139
+ cdef Py_ssize_t src_extent = src_shape[0]
1140
+ cdef Py_ssize_t dst_extent = dst_shape[0]
1141
+ cdef Py_ssize_t src_stride = src_strides[0]
1142
+ cdef Py_ssize_t dst_stride = dst_strides[0]
1143
+
1144
+ if ndim == 1:
1145
+ if (src_stride > 0 and dst_stride > 0 and
1146
+ <size_t> src_stride == itemsize == <size_t> dst_stride):
1147
+ memcpy(dst_data, src_data, itemsize * dst_extent)
1148
+ else:
1149
+ for i in range(dst_extent):
1150
+ memcpy(dst_data, src_data, itemsize)
1151
+ src_data += src_stride
1152
+ dst_data += dst_stride
1153
+ else:
1154
+ for i in range(dst_extent):
1155
+ _copy_strided_to_strided(src_data, src_strides + 1,
1156
+ dst_data, dst_strides + 1,
1157
+ src_shape + 1, dst_shape + 1,
1158
+ ndim - 1, itemsize)
1159
+ src_data += src_stride
1160
+ dst_data += dst_stride
1161
+
1162
+ cdef void copy_strided_to_strided({{memviewslice_name}} *src,
1163
+ {{memviewslice_name}} *dst,
1164
+ int ndim, size_t itemsize) noexcept nogil:
1165
+ _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides,
1166
+ src.shape, dst.shape, ndim, itemsize)
1167
+
1168
+ @cname('__pyx_memoryview_slice_get_size')
1169
+ cdef Py_ssize_t slice_get_size({{memviewslice_name}} *src, int ndim) noexcept nogil:
1170
+ "Return the size of the memory occupied by the slice in number of bytes"
1171
+ cdef Py_ssize_t shape, size = src.memview.view.itemsize
1172
+
1173
+ for shape in src.shape[:ndim]:
1174
+ size *= shape
1175
+
1176
+ return size
1177
+
1178
+ @cname('__pyx_fill_contig_strides_array')
1179
+ cdef Py_ssize_t fill_contig_strides_array(
1180
+ Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
1181
+ int ndim, char order) noexcept nogil:
1182
+ """
1183
+ Fill the strides array for a slice with C or F contiguous strides.
1184
+ This is like PyBuffer_FillContiguousStrides, but compatible with py < 2.6
1185
+ """
1186
+ cdef int idx
1187
+
1188
+ if order == 'F':
1189
+ for idx in range(ndim):
1190
+ strides[idx] = stride
1191
+ stride *= shape[idx]
1192
+ else:
1193
+ for idx in range(ndim - 1, -1, -1):
1194
+ strides[idx] = stride
1195
+ stride *= shape[idx]
1196
+
1197
+ return stride
1198
+
1199
+ @cname('__pyx_memoryview_copy_data_to_temp')
1200
+ cdef void *copy_data_to_temp({{memviewslice_name}} *src,
1201
+ {{memviewslice_name}} *tmpslice,
1202
+ char order,
1203
+ int ndim) except NULL nogil:
1204
+ """
1205
+ Copy a direct slice to temporary contiguous memory. The caller should free
1206
+ the result when done.
1207
+ """
1208
+ cdef int i
1209
+ cdef void *result
1210
+
1211
+ cdef size_t itemsize = src.memview.view.itemsize
1212
+ cdef size_t size = slice_get_size(src, ndim)
1213
+
1214
+ result = malloc(size)
1215
+ if not result:
1216
+ _err_no_memory()
1217
+
1218
+ # tmpslice[0] = src
1219
+ tmpslice.data = <char *> result
1220
+ tmpslice.memview = src.memview
1221
+ for i in range(ndim):
1222
+ tmpslice.shape[i] = src.shape[i]
1223
+ tmpslice.suboffsets[i] = -1
1224
+
1225
+ fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, ndim, order)
1226
+
1227
+ # We need to broadcast strides again
1228
+ for i in range(ndim):
1229
+ if tmpslice.shape[i] == 1:
1230
+ tmpslice.strides[i] = 0
1231
+
1232
+ if slice_is_contig(src[0], order, ndim):
1233
+ memcpy(result, src.data, size)
1234
+ else:
1235
+ copy_strided_to_strided(src, tmpslice, ndim, itemsize)
1236
+
1237
+ return result
1238
+
1239
+ # Use 'with gil' functions and avoid 'with gil' blocks, as the code within the blocks
1240
+ # has temporaries that need the GIL to clean up
1241
+ @cname('__pyx_memoryview_err_extents')
1242
+ cdef int _err_extents(int i, Py_ssize_t extent1,
1243
+ Py_ssize_t extent2) except -1 with gil:
1244
+ raise ValueError, f"got differing extents in dimension {i} (got {extent1} and {extent2})"
1245
+
1246
+ @cname('__pyx_memoryview_err_dim')
1247
+ cdef int _err_dim(PyObject *error, str msg, int dim) except -1 with gil:
1248
+ raise <object>error, msg % dim
1249
+
1250
+ @cname('__pyx_memoryview_err')
1251
+ cdef int _err(PyObject *error, str msg) except -1 with gil:
1252
+ raise <object>error, msg
1253
+
1254
+ @cname('__pyx_memoryview_err_no_memory')
1255
+ cdef int _err_no_memory() except -1 with gil:
1256
+ raise MemoryError
1257
+
1258
+
1259
+ @cname('__pyx_memoryview_copy_contents')
1260
+ cdef int memoryview_copy_contents({{memviewslice_name}} src,
1261
+ {{memviewslice_name}} dst,
1262
+ int src_ndim, int dst_ndim,
1263
+ bint dtype_is_object) except -1 nogil:
1264
+ """
1265
+ Copy memory from slice src to slice dst.
1266
+ Check for overlapping memory and verify the shapes.
1267
+ """
1268
+ cdef void *tmpdata = NULL
1269
+ cdef size_t itemsize = src.memview.view.itemsize
1270
+ cdef int i
1271
+ cdef char order = get_best_order(&src, src_ndim)
1272
+ cdef bint broadcasting = False
1273
+ cdef bint direct_copy = False
1274
+ cdef {{memviewslice_name}} tmp
1275
+
1276
+ if src_ndim < dst_ndim:
1277
+ broadcast_leading(&src, src_ndim, dst_ndim)
1278
+ elif dst_ndim < src_ndim:
1279
+ broadcast_leading(&dst, dst_ndim, src_ndim)
1280
+
1281
+ cdef int ndim = max(src_ndim, dst_ndim)
1282
+
1283
+ for i in range(ndim):
1284
+ if src.shape[i] != dst.shape[i]:
1285
+ if src.shape[i] == 1:
1286
+ broadcasting = True
1287
+ src.strides[i] = 0
1288
+ else:
1289
+ _err_extents(i, dst.shape[i], src.shape[i])
1290
+
1291
+ if src.suboffsets[i] >= 0:
1292
+ _err_dim(PyExc_ValueError, "Dimension %d is not direct", i)
1293
+
1294
+ if slices_overlap(&src, &dst, ndim, itemsize):
1295
+ # slices overlap, copy to temp, copy temp to dst
1296
+ if not slice_is_contig(src, order, ndim):
1297
+ order = get_best_order(&dst, ndim)
1298
+
1299
+ tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
1300
+ src = tmp
1301
+
1302
+ if not broadcasting:
1303
+ # See if both slices have equal contiguity, in that case perform a
1304
+ # direct copy. This only works when we are not broadcasting.
1305
+ if slice_is_contig(src, 'C', ndim):
1306
+ direct_copy = slice_is_contig(dst, 'C', ndim)
1307
+ elif slice_is_contig(src, 'F', ndim):
1308
+ direct_copy = slice_is_contig(dst, 'F', ndim)
1309
+
1310
+ if direct_copy:
1311
+ # Contiguous slices with same order
1312
+ refcount_copying(&dst, dtype_is_object, ndim, inc=False)
1313
+ memcpy(dst.data, src.data, slice_get_size(&src, ndim))
1314
+ refcount_copying(&dst, dtype_is_object, ndim, inc=True)
1315
+ free(tmpdata)
1316
+ return 0
1317
+
1318
+ if order == 'F' == get_best_order(&dst, ndim):
1319
+ # see if both slices have Fortran order, transpose them to match our
1320
+ # C-style indexing order
1321
+ transpose_memslice(&src)
1322
+ transpose_memslice(&dst)
1323
+
1324
+ refcount_copying(&dst, dtype_is_object, ndim, inc=False)
1325
+ copy_strided_to_strided(&src, &dst, ndim, itemsize)
1326
+ refcount_copying(&dst, dtype_is_object, ndim, inc=True)
1327
+
1328
+ free(tmpdata)
1329
+ return 0
1330
+
1331
+ @cname('__pyx_memoryview_broadcast_leading')
1332
+ cdef void broadcast_leading({{memviewslice_name}} *mslice,
1333
+ int ndim,
1334
+ int ndim_other) noexcept nogil:
1335
+ cdef int i
1336
+ cdef int offset = ndim_other - ndim
1337
+
1338
+ for i in range(ndim - 1, -1, -1):
1339
+ mslice.shape[i + offset] = mslice.shape[i]
1340
+ mslice.strides[i + offset] = mslice.strides[i]
1341
+ mslice.suboffsets[i + offset] = mslice.suboffsets[i]
1342
+
1343
+ for i in range(offset):
1344
+ mslice.shape[i] = 1
1345
+ mslice.strides[i] = mslice.strides[0]
1346
+ mslice.suboffsets[i] = -1
1347
+
1348
+ #
1349
+ ### Take care of refcounting the objects in slices. Do this separately from any copying,
1350
+ ### to minimize acquiring the GIL
1351
+ #
1352
+
1353
+ @cname('__pyx_memoryview_refcount_copying')
1354
+ cdef void refcount_copying({{memviewslice_name}} *dst, bint dtype_is_object, int ndim, bint inc) noexcept nogil:
1355
+ # incref or decref the objects in the destination slice if the dtype is object
1356
+ if dtype_is_object:
1357
+ refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc)
1358
+
1359
+ @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
1360
+ cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape,
1361
+ Py_ssize_t *strides, int ndim,
1362
+ bint inc) noexcept with gil:
1363
+ refcount_objects_in_slice(data, shape, strides, ndim, inc)
1364
+
1365
+ @cname('__pyx_memoryview_refcount_objects_in_slice')
1366
+ cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape,
1367
+ Py_ssize_t *strides, int ndim, bint inc) noexcept:
1368
+ cdef Py_ssize_t i
1369
+ cdef Py_ssize_t stride = strides[0]
1370
+
1371
+ for i in range(shape[0]):
1372
+ if ndim == 1:
1373
+ if inc:
1374
+ Py_INCREF((<PyObject **> data)[0])
1375
+ else:
1376
+ Py_DECREF((<PyObject **> data)[0])
1377
+ else:
1378
+ refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc)
1379
+
1380
+ data += stride
1381
+
1382
+ #
1383
+ ### Scalar to slice assignment
1384
+ #
1385
+ @cname('__pyx_memoryview_slice_assign_scalar')
1386
+ cdef void slice_assign_scalar({{memviewslice_name}} *dst, int ndim,
1387
+ size_t itemsize, void *item,
1388
+ bint dtype_is_object) noexcept nogil:
1389
+ refcount_copying(dst, dtype_is_object, ndim, inc=False)
1390
+ _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item)
1391
+ refcount_copying(dst, dtype_is_object, ndim, inc=True)
1392
+
1393
+
1394
+ @cname('__pyx_memoryview__slice_assign_scalar')
1395
+ cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape,
1396
+ Py_ssize_t *strides, int ndim,
1397
+ size_t itemsize, void *item) noexcept nogil:
1398
+ cdef Py_ssize_t i
1399
+ cdef Py_ssize_t stride = strides[0]
1400
+ cdef Py_ssize_t extent = shape[0]
1401
+
1402
+ if ndim == 1:
1403
+ for i in range(extent):
1404
+ memcpy(data, item, itemsize)
1405
+ data += stride
1406
+ else:
1407
+ for i in range(extent):
1408
+ _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item)
1409
+ data += stride
1410
+
1411
+
1412
+ ############### BufferFormatFromTypeInfo ###############
1413
+ cdef extern from *:
1414
+ ctypedef struct __Pyx_StructField
1415
+
1416
+ cdef enum:
1417
+ __PYX_BUF_FLAGS_PACKED_STRUCT
1418
+ __PYX_BUF_FLAGS_INTEGER_COMPLEX
1419
+
1420
+ ctypedef struct __Pyx_TypeInfo:
1421
+ char* name
1422
+ const __Pyx_StructField* fields
1423
+ size_t size
1424
+ size_t arraysize[8]
1425
+ int ndim
1426
+ char typegroup
1427
+ char is_unsigned
1428
+ int flags
1429
+
1430
+ ctypedef struct __Pyx_StructField:
1431
+ const __Pyx_TypeInfo* type
1432
+ char* name
1433
+ size_t offset
1434
+
1435
+ ctypedef struct __Pyx_BufFmt_StackElem:
1436
+ const __Pyx_StructField* field
1437
+ size_t parent_offset
1438
+
1439
+ #ctypedef struct __Pyx_BufFmt_Context:
1440
+ # __Pyx_StructField root
1441
+ __Pyx_BufFmt_StackElem* head
1442
+
1443
+ struct __pyx_typeinfo_string:
1444
+ char string[3]
1445
+
1446
+ __pyx_typeinfo_string __Pyx_TypeInfoToFormat(const __Pyx_TypeInfo *)
1447
+
1448
+
1449
+ @cname('__pyx_format_from_typeinfo')
1450
+ cdef bytes format_from_typeinfo(const __Pyx_TypeInfo *type):
1451
+ cdef const __Pyx_StructField *field
1452
+ cdef __pyx_typeinfo_string fmt
1453
+ cdef bytes part, result
1454
+ cdef Py_ssize_t i
1455
+
1456
+ if type.typegroup == 'S':
1457
+ assert type.fields != NULL
1458
+ assert type.fields.type != NULL
1459
+
1460
+ if type.flags & __PYX_BUF_FLAGS_PACKED_STRUCT:
1461
+ alignment = b'^'
1462
+ else:
1463
+ alignment = b''
1464
+
1465
+ parts = [b"T{"]
1466
+ field = type.fields
1467
+
1468
+ while field.type:
1469
+ part = format_from_typeinfo(field.type)
1470
+ parts.append(part + b':' + field.name + b':')
1471
+ field += 1
1472
+
1473
+ result = alignment.join(parts) + b'}'
1474
+ else:
1475
+ fmt = __Pyx_TypeInfoToFormat(type)
1476
+ result = fmt.string
1477
+ if type.arraysize[0]:
1478
+ extents = [f"{type.arraysize[i]}" for i in range(type.ndim)]
1479
+ result = f"({u','.join(extents)})".encode('ascii') + result
1480
+
1481
+ return result