Cython 3.3.0__cp315-cp315-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. Cython/Build/BuildExecutable.py +156 -0
  2. Cython/Build/Cache.py +199 -0
  3. Cython/Build/Cythonize.py +349 -0
  4. Cython/Build/Dependencies.py +1281 -0
  5. Cython/Build/Distutils.py +1 -0
  6. Cython/Build/Inline.py +467 -0
  7. Cython/Build/IpythonMagic.py +559 -0
  8. Cython/Build/SharedModule.py +165 -0
  9. Cython/Build/Tests/TestCyCache.py +195 -0
  10. Cython/Build/Tests/TestCythonizeArgsParser.py +480 -0
  11. Cython/Build/Tests/TestDependencies.py +133 -0
  12. Cython/Build/Tests/TestInline.py +177 -0
  13. Cython/Build/Tests/TestIpythonMagic.py +303 -0
  14. Cython/Build/Tests/TestRecythonize.py +212 -0
  15. Cython/Build/Tests/TestStripLiterals.py +155 -0
  16. Cython/Build/Tests/__init__.py +1 -0
  17. Cython/Build/__init__.py +11 -0
  18. Cython/CodeWriter.py +825 -0
  19. Cython/Compiler/AnalysedTreeTransforms.py +97 -0
  20. Cython/Compiler/Annotate.py +328 -0
  21. Cython/Compiler/AutoDocTransforms.py +320 -0
  22. Cython/Compiler/Buffer.py +679 -0
  23. Cython/Compiler/Builtin.py +1102 -0
  24. Cython/Compiler/CmdLine.py +373 -0
  25. Cython/Compiler/Code.cp315-win_amd64.pyd +0 -0
  26. Cython/Compiler/Code.pxd +154 -0
  27. Cython/Compiler/Code.py +3760 -0
  28. Cython/Compiler/CodeGeneration.py +33 -0
  29. Cython/Compiler/CythonScope.py +208 -0
  30. Cython/Compiler/Dataclass.py +890 -0
  31. Cython/Compiler/DebugFlags.py +24 -0
  32. Cython/Compiler/Errors.py +310 -0
  33. Cython/Compiler/ExprNodes.py +16273 -0
  34. Cython/Compiler/FlowControl.cp315-win_amd64.pyd +0 -0
  35. Cython/Compiler/FlowControl.pxd +112 -0
  36. Cython/Compiler/FlowControl.py +1573 -0
  37. Cython/Compiler/FusedNode.cp315-win_amd64.pyd +0 -0
  38. Cython/Compiler/FusedNode.py +978 -0
  39. Cython/Compiler/Future.py +16 -0
  40. Cython/Compiler/Interpreter.py +57 -0
  41. Cython/Compiler/Lexicon.py +422 -0
  42. Cython/Compiler/LineTable.cp315-win_amd64.pyd +0 -0
  43. Cython/Compiler/LineTable.py +114 -0
  44. Cython/Compiler/Main.py +856 -0
  45. Cython/Compiler/MatchCaseNodes.py +2200 -0
  46. Cython/Compiler/MemoryView.py +930 -0
  47. Cython/Compiler/ModuleNode.py +4548 -0
  48. Cython/Compiler/Naming.py +370 -0
  49. Cython/Compiler/Nodes.py +11304 -0
  50. Cython/Compiler/Optimize.py +5564 -0
  51. Cython/Compiler/Options.py +840 -0
  52. Cython/Compiler/ParseTreeTransforms.pxd +80 -0
  53. Cython/Compiler/ParseTreeTransforms.py +4808 -0
  54. Cython/Compiler/Parsing.cp315-win_amd64.pyd +0 -0
  55. Cython/Compiler/Parsing.pxd +9 -0
  56. Cython/Compiler/Parsing.py +4809 -0
  57. Cython/Compiler/Pipeline.py +439 -0
  58. Cython/Compiler/PyrexTypes.py +6588 -0
  59. Cython/Compiler/Pythran.py +232 -0
  60. Cython/Compiler/Scanning.cp315-win_amd64.pyd +0 -0
  61. Cython/Compiler/Scanning.pxd +70 -0
  62. Cython/Compiler/Scanning.py +720 -0
  63. Cython/Compiler/StringEncoding.cp315-win_amd64.pyd +0 -0
  64. Cython/Compiler/StringEncoding.py +354 -0
  65. Cython/Compiler/Symtab.py +3121 -0
  66. Cython/Compiler/Tests/TestBuffer.py +105 -0
  67. Cython/Compiler/Tests/TestBuiltin.py +196 -0
  68. Cython/Compiler/Tests/TestCmdLine.py +652 -0
  69. Cython/Compiler/Tests/TestCode.py +145 -0
  70. Cython/Compiler/Tests/TestFlowControl.py +65 -0
  71. Cython/Compiler/Tests/TestGrammar.py +202 -0
  72. Cython/Compiler/Tests/TestMemView.py +71 -0
  73. Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
  74. Cython/Compiler/Tests/TestScanning.py +132 -0
  75. Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
  76. Cython/Compiler/Tests/TestStringEncoding.py +20 -0
  77. Cython/Compiler/Tests/TestTreeFragment.py +63 -0
  78. Cython/Compiler/Tests/TestTreePath.py +103 -0
  79. Cython/Compiler/Tests/TestTypes.py +119 -0
  80. Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
  81. Cython/Compiler/Tests/TestVisitor.py +119 -0
  82. Cython/Compiler/Tests/Utils.py +36 -0
  83. Cython/Compiler/Tests/__init__.py +1 -0
  84. Cython/Compiler/TreeFragment.py +279 -0
  85. Cython/Compiler/TreePath.py +303 -0
  86. Cython/Compiler/TypeInference.py +611 -0
  87. Cython/Compiler/TypeSlots.py +1329 -0
  88. Cython/Compiler/UFuncs.py +317 -0
  89. Cython/Compiler/UtilNodes.py +389 -0
  90. Cython/Compiler/UtilityCode.py +354 -0
  91. Cython/Compiler/Version.py +8 -0
  92. Cython/Compiler/Visitor.cp315-win_amd64.pyd +0 -0
  93. Cython/Compiler/Visitor.pxd +52 -0
  94. Cython/Compiler/Visitor.py +914 -0
  95. Cython/Compiler/__init__.py +1 -0
  96. Cython/Coverage.py +448 -0
  97. Cython/Debugger/Cygdb.py +214 -0
  98. Cython/Debugger/DebugWriter.py +82 -0
  99. Cython/Debugger/Tests/TestLibCython.py +280 -0
  100. Cython/Debugger/Tests/__init__.py +1 -0
  101. Cython/Debugger/Tests/cfuncs.c +8 -0
  102. Cython/Debugger/Tests/codefile +49 -0
  103. Cython/Debugger/Tests/test_libcython_in_gdb.py +580 -0
  104. Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
  105. Cython/Debugger/__init__.py +1 -0
  106. Cython/Debugger/libcython.py +1548 -0
  107. Cython/Debugger/libpython.py +2821 -0
  108. Cython/Debugging.py +20 -0
  109. Cython/Distutils/__init__.py +2 -0
  110. Cython/Distutils/build_ext.py +143 -0
  111. Cython/Distutils/extension.py +96 -0
  112. Cython/Distutils/old_build_ext.py +351 -0
  113. Cython/Includes/cpython/__init__.pxd +173 -0
  114. Cython/Includes/cpython/array.pxd +152 -0
  115. Cython/Includes/cpython/bool.pxd +37 -0
  116. Cython/Includes/cpython/buffer.pxd +112 -0
  117. Cython/Includes/cpython/bytearray.pxd +33 -0
  118. Cython/Includes/cpython/bytes.pxd +200 -0
  119. Cython/Includes/cpython/cellobject.pxd +35 -0
  120. Cython/Includes/cpython/ceval.pxd +8 -0
  121. Cython/Includes/cpython/codecs.pxd +121 -0
  122. Cython/Includes/cpython/complex.pxd +60 -0
  123. Cython/Includes/cpython/contextvars.pxd +145 -0
  124. Cython/Includes/cpython/conversion.pxd +36 -0
  125. Cython/Includes/cpython/datetime.pxd +395 -0
  126. Cython/Includes/cpython/descr.pxd +26 -0
  127. Cython/Includes/cpython/dict.pxd +268 -0
  128. Cython/Includes/cpython/exc.pxd +263 -0
  129. Cython/Includes/cpython/fileobject.pxd +57 -0
  130. Cython/Includes/cpython/float.pxd +56 -0
  131. Cython/Includes/cpython/frozendict.pxd +37 -0
  132. Cython/Includes/cpython/function.pxd +65 -0
  133. Cython/Includes/cpython/genobject.pxd +25 -0
  134. Cython/Includes/cpython/getargs.pxd +12 -0
  135. Cython/Includes/cpython/instance.pxd +25 -0
  136. Cython/Includes/cpython/iterator.pxd +36 -0
  137. Cython/Includes/cpython/iterobject.pxd +24 -0
  138. Cython/Includes/cpython/list.pxd +144 -0
  139. Cython/Includes/cpython/long.pxd +180 -0
  140. Cython/Includes/cpython/longintrepr.pxd +14 -0
  141. Cython/Includes/cpython/mapping.pxd +63 -0
  142. Cython/Includes/cpython/marshal.pxd +66 -0
  143. Cython/Includes/cpython/mem.pxd +120 -0
  144. Cython/Includes/cpython/memoryview.pxd +50 -0
  145. Cython/Includes/cpython/method.pxd +49 -0
  146. Cython/Includes/cpython/module.pxd +208 -0
  147. Cython/Includes/cpython/number.pxd +258 -0
  148. Cython/Includes/cpython/object.pxd +430 -0
  149. Cython/Includes/cpython/pycapsule.pxd +143 -0
  150. Cython/Includes/cpython/pylifecycle.pxd +68 -0
  151. Cython/Includes/cpython/pyport.pxd +8 -0
  152. Cython/Includes/cpython/pystate.pxd +95 -0
  153. Cython/Includes/cpython/pythread.pxd +53 -0
  154. Cython/Includes/cpython/ref.pxd +141 -0
  155. Cython/Includes/cpython/sentinel.pxd +17 -0
  156. Cython/Includes/cpython/sequence.pxd +134 -0
  157. Cython/Includes/cpython/set.pxd +119 -0
  158. Cython/Includes/cpython/slice.pxd +70 -0
  159. Cython/Includes/cpython/time.pxd +129 -0
  160. Cython/Includes/cpython/tuple.pxd +72 -0
  161. Cython/Includes/cpython/type.pxd +146 -0
  162. Cython/Includes/cpython/unicode.pxd +639 -0
  163. Cython/Includes/cpython/version.pxd +32 -0
  164. Cython/Includes/cpython/weakref.pxd +78 -0
  165. Cython/Includes/libc/__init__.pxd +1 -0
  166. Cython/Includes/libc/complex.pxd +35 -0
  167. Cython/Includes/libc/errno.pxd +127 -0
  168. Cython/Includes/libc/float.pxd +43 -0
  169. Cython/Includes/libc/limits.pxd +28 -0
  170. Cython/Includes/libc/locale.pxd +46 -0
  171. Cython/Includes/libc/math.pxd +209 -0
  172. Cython/Includes/libc/setjmp.pxd +10 -0
  173. Cython/Includes/libc/signal.pxd +64 -0
  174. Cython/Includes/libc/stddef.pxd +9 -0
  175. Cython/Includes/libc/stdint.pxd +105 -0
  176. Cython/Includes/libc/stdio.pxd +80 -0
  177. Cython/Includes/libc/stdlib.pxd +72 -0
  178. Cython/Includes/libc/string.pxd +50 -0
  179. Cython/Includes/libc/threads.pxd +234 -0
  180. Cython/Includes/libc/time.pxd +52 -0
  181. Cython/Includes/libcpp/__init__.pxd +4 -0
  182. Cython/Includes/libcpp/algorithm.pxd +320 -0
  183. Cython/Includes/libcpp/any.pxd +16 -0
  184. Cython/Includes/libcpp/atomic.pxd +59 -0
  185. Cython/Includes/libcpp/barrier.pxd +22 -0
  186. Cython/Includes/libcpp/bit.pxd +29 -0
  187. Cython/Includes/libcpp/cast.pxd +12 -0
  188. Cython/Includes/libcpp/cmath.pxd +518 -0
  189. Cython/Includes/libcpp/complex.pxd +106 -0
  190. Cython/Includes/libcpp/condition_variable.pxd +322 -0
  191. Cython/Includes/libcpp/deque.pxd +165 -0
  192. Cython/Includes/libcpp/exception.pxd +216 -0
  193. Cython/Includes/libcpp/execution.pxd +15 -0
  194. Cython/Includes/libcpp/forward_list.pxd +63 -0
  195. Cython/Includes/libcpp/functional.pxd +26 -0
  196. Cython/Includes/libcpp/future.pxd +103 -0
  197. Cython/Includes/libcpp/iterator.pxd +34 -0
  198. Cython/Includes/libcpp/latch.pxd +17 -0
  199. Cython/Includes/libcpp/limits.pxd +61 -0
  200. Cython/Includes/libcpp/list.pxd +117 -0
  201. Cython/Includes/libcpp/map.pxd +252 -0
  202. Cython/Includes/libcpp/memory.pxd +115 -0
  203. Cython/Includes/libcpp/mutex.pxd +387 -0
  204. Cython/Includes/libcpp/numbers.pxd +15 -0
  205. Cython/Includes/libcpp/numeric.pxd +131 -0
  206. Cython/Includes/libcpp/optional.pxd +34 -0
  207. Cython/Includes/libcpp/pair.pxd +1 -0
  208. Cython/Includes/libcpp/queue.pxd +25 -0
  209. Cython/Includes/libcpp/random.pxd +166 -0
  210. Cython/Includes/libcpp/semaphore.pxd +43 -0
  211. Cython/Includes/libcpp/set.pxd +228 -0
  212. Cython/Includes/libcpp/shared_mutex.pxd +96 -0
  213. Cython/Includes/libcpp/span.pxd +87 -0
  214. Cython/Includes/libcpp/stack.pxd +11 -0
  215. Cython/Includes/libcpp/stop_token.pxd +117 -0
  216. Cython/Includes/libcpp/string.pxd +355 -0
  217. Cython/Includes/libcpp/string_view.pxd +183 -0
  218. Cython/Includes/libcpp/typeindex.pxd +15 -0
  219. Cython/Includes/libcpp/typeinfo.pxd +10 -0
  220. Cython/Includes/libcpp/unordered_map.pxd +193 -0
  221. Cython/Includes/libcpp/unordered_set.pxd +152 -0
  222. Cython/Includes/libcpp/utility.pxd +30 -0
  223. Cython/Includes/libcpp/vector.pxd +186 -0
  224. Cython/Includes/numpy/math.pxd +150 -0
  225. Cython/Includes/openmp.pxd +50 -0
  226. Cython/Includes/posix/__init__.pxd +1 -0
  227. Cython/Includes/posix/dlfcn.pxd +14 -0
  228. Cython/Includes/posix/fcntl.pxd +86 -0
  229. Cython/Includes/posix/ioctl.pxd +4 -0
  230. Cython/Includes/posix/mman.pxd +101 -0
  231. Cython/Includes/posix/resource.pxd +57 -0
  232. Cython/Includes/posix/select.pxd +21 -0
  233. Cython/Includes/posix/signal.pxd +73 -0
  234. Cython/Includes/posix/stat.pxd +98 -0
  235. Cython/Includes/posix/stdio.pxd +37 -0
  236. Cython/Includes/posix/stdlib.pxd +29 -0
  237. Cython/Includes/posix/strings.pxd +9 -0
  238. Cython/Includes/posix/time.pxd +71 -0
  239. Cython/Includes/posix/types.pxd +30 -0
  240. Cython/Includes/posix/uio.pxd +26 -0
  241. Cython/Includes/posix/unistd.pxd +271 -0
  242. Cython/Includes/posix/wait.pxd +38 -0
  243. Cython/LZSS.cp315-win_amd64.pyd +0 -0
  244. Cython/LZSS.py +184 -0
  245. Cython/Plex/Actions.cp315-win_amd64.pyd +0 -0
  246. Cython/Plex/Actions.pxd +24 -0
  247. Cython/Plex/Actions.py +119 -0
  248. Cython/Plex/DFA.cp315-win_amd64.pyd +0 -0
  249. Cython/Plex/DFA.pxd +14 -0
  250. Cython/Plex/DFA.py +164 -0
  251. Cython/Plex/Errors.py +48 -0
  252. Cython/Plex/Lexicons.py +178 -0
  253. Cython/Plex/Machines.cp315-win_amd64.pyd +0 -0
  254. Cython/Plex/Machines.pxd +36 -0
  255. Cython/Plex/Machines.py +238 -0
  256. Cython/Plex/Regexps.py +535 -0
  257. Cython/Plex/Scanners.cp315-win_amd64.pyd +0 -0
  258. Cython/Plex/Scanners.pxd +45 -0
  259. Cython/Plex/Scanners.py +328 -0
  260. Cython/Plex/Transitions.cp315-win_amd64.pyd +0 -0
  261. Cython/Plex/Transitions.pxd +14 -0
  262. Cython/Plex/Transitions.py +239 -0
  263. Cython/Plex/__init__.py +34 -0
  264. Cython/Runtime/__init__.py +1 -0
  265. Cython/Runtime/refnanny.cp315-win_amd64.pyd +0 -0
  266. Cython/Runtime/refnanny.pyx +237 -0
  267. Cython/Shadow.py +1174 -0
  268. Cython/StringIOTree.cp315-win_amd64.pyd +0 -0
  269. Cython/StringIOTree.py +169 -0
  270. Cython/Tempita/__init__.py +4 -0
  271. Cython/Tempita/_looper.py +154 -0
  272. Cython/Tempita/_tempita.cp315-win_amd64.pyd +0 -0
  273. Cython/Tempita/_tempita.py +1087 -0
  274. Cython/TestUtils.py +472 -0
  275. Cython/Tests/TestCodeWriter.py +128 -0
  276. Cython/Tests/TestCythonUtils.py +202 -0
  277. Cython/Tests/TestJediTyper.py +223 -0
  278. Cython/Tests/TestShadow.py +125 -0
  279. Cython/Tests/TestStringIOTree.py +68 -0
  280. Cython/Tests/TestTestUtils.py +89 -0
  281. Cython/Tests/__init__.py +1 -0
  282. Cython/Tests/xmlrunner.py +390 -0
  283. Cython/Utility/AsyncGen.c +1152 -0
  284. Cython/Utility/Buffer.c +866 -0
  285. Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
  286. Cython/Utility/Builtins.c +1068 -0
  287. Cython/Utility/CConvert.pyx +153 -0
  288. Cython/Utility/CMath.c +104 -0
  289. Cython/Utility/CommonStructures.c +244 -0
  290. Cython/Utility/Complex.c +378 -0
  291. Cython/Utility/Coroutine.c +2344 -0
  292. Cython/Utility/CpdefEnums.pyx +119 -0
  293. Cython/Utility/CppConvert.pyx +282 -0
  294. Cython/Utility/CppSupport.cpp +151 -0
  295. Cython/Utility/CythonFunction.c +2185 -0
  296. Cython/Utility/Dataclasses.c +101 -0
  297. Cython/Utility/Embed.c +129 -0
  298. Cython/Utility/Exceptions.c +1331 -0
  299. Cython/Utility/Exceptions_Cy.pyx +109 -0
  300. Cython/Utility/ExtensionTypes.c +1199 -0
  301. Cython/Utility/FunctionArguments.c +1052 -0
  302. Cython/Utility/FusedFunction.pyx +44 -0
  303. Cython/Utility/ImportExport.c +972 -0
  304. Cython/Utility/MatchCase.c +981 -0
  305. Cython/Utility/MatchCase_Cy.pyx +12 -0
  306. Cython/Utility/MemoryView.pxd +108 -0
  307. Cython/Utility/MemoryView.pyx +1499 -0
  308. Cython/Utility/MemoryView_C.c +1056 -0
  309. Cython/Utility/ModuleSetupCode.c +3319 -0
  310. Cython/Utility/NumpyImportArray.c +46 -0
  311. Cython/Utility/ObjectHandling.c +3404 -0
  312. Cython/Utility/Optimize.c +2564 -0
  313. Cython/Utility/Overflow.c +378 -0
  314. Cython/Utility/Profile.c +736 -0
  315. Cython/Utility/StringTools.c +1534 -0
  316. Cython/Utility/Synchronization.c +438 -0
  317. Cython/Utility/TString.c +369 -0
  318. Cython/Utility/TestCyUtilityLoader.pyx +8 -0
  319. Cython/Utility/TestCythonScope.pyx +75 -0
  320. Cython/Utility/TestUtilityLoader.c +12 -0
  321. Cython/Utility/TypeConversion.c +1588 -0
  322. Cython/Utility/UFuncs.pyx +50 -0
  323. Cython/Utility/UFuncs_C.c +89 -0
  324. Cython/Utility/__init__.py +28 -0
  325. Cython/Utility/arrayarray.h +172 -0
  326. Cython/Utils.cp315-win_amd64.pyd +0 -0
  327. Cython/Utils.py +680 -0
  328. Cython/__init__.py +12 -0
  329. Cython/_shared.cp315-win_amd64.pyd +0 -0
  330. Cython/py.typed +0 -0
  331. cython-3.3.0.dist-info/METADATA +555 -0
  332. cython-3.3.0.dist-info/RECORD +339 -0
  333. cython-3.3.0.dist-info/WHEEL +5 -0
  334. cython-3.3.0.dist-info/entry_points.txt +4 -0
  335. cython-3.3.0.dist-info/top_level.txt +3 -0
  336. cython.py +29 -0
  337. pyximport/__init__.py +4 -0
  338. pyximport/pyxbuild.py +160 -0
  339. pyximport/pyximport.py +482 -0
@@ -0,0 +1,981 @@
1
+ ///////////////////////////// ABCCheck //////////////////////////////
2
+ //@requires: Builtins.c::PyFrozenDict
3
+
4
+ #if PY_VERSION_HEX < 0x030A0000 || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY
5
+ static CYTHON_INLINE int __Pyx_MatchCase_IsExactSequence(PyObject *o) {
6
+ // Is one of the small list of builtin types known to be a sequence.
7
+ if (PyList_CheckExact(o) || PyTuple_CheckExact(o) ||
8
+ Py_IS_TYPE(o, &PyRange_Type) || Py_IS_TYPE(o, &PyMemoryView_Type)) {
9
+ // Use exact type match for these checks. In in the event of inheritance we need to make sure
10
+ // that it isn't a mapping too
11
+ return 1;
12
+ }
13
+ return 0;
14
+ }
15
+
16
+ static CYTHON_INLINE int __Pyx_MatchCase_IsExactMapping(PyObject *o) {
17
+ // dict and frozendict are the only regularly used mapping type.
18
+ // "types.MappingProxyType" also exists but is correctly covered by
19
+ // the isinstance(o, Mapping) check.
20
+ return __Pyx_PyAnyDict_CheckExact(o);
21
+ }
22
+
23
+ static int __Pyx_MatchCase_IsExactNeitherSequenceNorMapping(PyObject *o) {
24
+ if (PyByteArray_Check(o) || PyBytes_Check(o) || PyUnicode_Check(o)) {
25
+ // These types are deliberately excluded from the sequence test
26
+ // even though they look like sequences for most other purposes.
27
+ // Leaving them as inexact checks since they do pass
28
+ // "isinstance(o, collections.abc.Sequence)" so it's very hard to
29
+ // reason about their subclasses.
30
+ return 1;
31
+ }
32
+ // No-exhaustive list of other common builtin types as an optimization.
33
+ if (o == Py_None || PyLong_CheckExact(o) || PyFloat_CheckExact(o) ||
34
+ Py_TYPE(o) == &PyBool_Type || Py_TYPE(o) == &PySlice_Type ||
35
+ PyAnySet_CheckExact(o) || PyComplex_CheckExact(o)) {
36
+ return 1;
37
+ }
38
+
39
+ return 0;
40
+ }
41
+
42
+ // sequence_mapping_temp: For Python 3.10 testing sequences and mappings are
43
+ // really quick and this is ignored. For lower versions of Python they're
44
+ // slow, especially in the "fail" case.
45
+ // Therefore, we store an int temp to avoid duplicating tests.
46
+ // The bits of it in order are:
47
+ // 0. definitely a sequence
48
+ // 1. definitely a mapping
49
+ // - note that both of the above can be true when
50
+ // the type is registered with both abc types (not via inheritance)
51
+ // and in this case we return true for both IsSequence or IsMapping
52
+ // (which seems like the best handling of an ambiguous situation)
53
+ // 2. definitely not a sequence
54
+ // 3. definitely not a mapping
55
+
56
+ #define __PYX_DEFINITELY_SEQUENCE_FLAG 1U
57
+ #define __PYX_DEFINITELY_MAPPING_FLAG (1U<<1)
58
+ #define __PYX_DEFINITELY_NOT_SEQUENCE_FLAG (1U<<2)
59
+ #define __PYX_DEFINITELY_NOT_MAPPING_FLAG (1U<<3)
60
+ #define __PYX_SEQUENCE_MAPPING_ERROR (1U<<4) // only used by the ABCCheck function
61
+
62
+ static int __Pyx_MatchCase_InitAbcType(PyObject *abc_module, PyObject **abc_type, PyObject *name) {
63
+ if (*abc_type) return 0;
64
+ *abc_type = PyObject_GetAttr(abc_module, name);
65
+ return *abc_type ? 0 : -1;
66
+ }
67
+
68
+ // The result is defined using the specification for sequence_mapping_temp
69
+ // (detailed in "is_sequence").
70
+ static unsigned int __Pyx_MatchCase_ABCCheck(PyObject *o, int sequence_first, int definitely_not_sequence, int definitely_not_mapping) {
71
+ // In Python 3.10+, objects can have their sequence bit set or their mapping bit set
72
+ // but not both. Practically, this translates to "which type is registered first".
73
+ // In Python < 3.10 we can only determine this if they're direct bases (by looking
74
+ // at the MRO order). If they're registered manually then we can't tell.
75
+
76
+ PyObject *abc_module=NULL, *sequence_type=NULL, *mapping_type=NULL;
77
+ PyObject *mro;
78
+ int sequence_result=0, mapping_result=0;
79
+ unsigned int result = 0;
80
+
81
+ if (sequence_first && definitely_not_sequence) {
82
+ return __PYX_DEFINITELY_NOT_SEQUENCE_FLAG;
83
+ }
84
+ if (!sequence_first && definitely_not_mapping) {
85
+ return __PYX_DEFINITELY_NOT_MAPPING_FLAG;
86
+ }
87
+
88
+ abc_module = PyImport_ImportModule("collections.abc");
89
+ if (!abc_module) {
90
+ return __PYX_SEQUENCE_MAPPING_ERROR;
91
+ }
92
+ if (sequence_first) {
93
+ if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &sequence_type, PYIDENT("Sequence")) == -1)) {
94
+ result = __PYX_SEQUENCE_MAPPING_ERROR;
95
+ goto end;
96
+ }
97
+ sequence_result = PyObject_IsInstance(o, sequence_type);
98
+ if (sequence_result <= 0) {
99
+ result = sequence_result < 0 ? __PYX_SEQUENCE_MAPPING_ERROR : __PYX_DEFINITELY_NOT_SEQUENCE_FLAG;
100
+ goto end;
101
+ }
102
+ // else sequence_result==1 but wait to see what mapping is
103
+ }
104
+ if (!definitely_not_mapping) {
105
+ if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &mapping_type, PYIDENT("Mapping")) == -1)) {
106
+ result = __PYX_SEQUENCE_MAPPING_ERROR;
107
+ goto end;
108
+ }
109
+ mapping_result = PyObject_IsInstance(o, mapping_type);
110
+ if (unlikely(mapping_result < 0)) {
111
+ result = __PYX_SEQUENCE_MAPPING_ERROR;
112
+ goto end;
113
+ } else if (mapping_result == 0 && !sequence_first) {
114
+ result = __PYX_DEFINITELY_NOT_MAPPING_FLAG;
115
+ goto end;
116
+ } // else mapping_result == 1
117
+ }
118
+ if (!sequence_first && !definitely_not_sequence) {
119
+ if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &sequence_type, PYIDENT("Sequence")) == -1)) {
120
+ result = __PYX_SEQUENCE_MAPPING_ERROR;
121
+ goto end;
122
+ }
123
+ sequence_result = PyObject_IsInstance(o, sequence_type);
124
+ if (unlikely(sequence_result < 0)) {
125
+ result = __PYX_SEQUENCE_MAPPING_ERROR;
126
+ goto end;
127
+ }
128
+ }
129
+ result |= (sequence_result ? __PYX_DEFINITELY_SEQUENCE_FLAG : __PYX_DEFINITELY_NOT_SEQUENCE_FLAG);
130
+ result |= (mapping_result ? __PYX_DEFINITELY_MAPPING_FLAG : __PYX_DEFINITELY_NOT_MAPPING_FLAG);
131
+ if (result != (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_MAPPING_FLAG)) {
132
+ goto end;
133
+ }
134
+
135
+ // It's an instance of both types. Look up the MRO order.
136
+ // In event of failure treat it as "could be either"
137
+ mro = PyObject_GetAttrString((PyObject*)Py_TYPE(o), "__mro__");
138
+ Py_ssize_t i, mro_size;
139
+ if (!mro) {
140
+ PyErr_Clear();
141
+ goto end;
142
+ }
143
+ if (!PyTuple_Check(mro)) {
144
+ Py_DECREF(mro);
145
+ goto end;
146
+ }
147
+ mro_size = __Pyx_PyTuple_GET_SIZE(mro);
148
+ #if !CYTHON_ASSUME_SAFE_SIZE
149
+ if (unlikely(mro_size == -1)) {
150
+ goto loop_error;
151
+ }
152
+ #endif
153
+ for (i=1; i < mro_size; ++i) {
154
+ int is_subclass_sequence, is_subclass_mapping;
155
+ PyObject *mro_item = __Pyx_PyTuple_GET_ITEM(mro, i);
156
+ #if !CYTHON_ASSUME_SAFE_MACROS
157
+ if (unlikely(!mro_item)) goto loop_error;
158
+ #endif
159
+ is_subclass_sequence = PyObject_IsSubclass(mro_item, sequence_type);
160
+ if (is_subclass_sequence < 0) goto loop_error;
161
+ is_subclass_mapping = PyObject_IsSubclass(mro_item, mapping_type);
162
+ if (is_subclass_mapping < 0) goto loop_error;
163
+ if (is_subclass_sequence && !is_subclass_mapping) {
164
+ result = (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
165
+ break;
166
+ } else if (is_subclass_mapping && !is_subclass_sequence) {
167
+ result = (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_MAPPING_FLAG);
168
+ break;
169
+ }
170
+ }
171
+ // If we get to the end of the loop without breaking then neither type is in
172
+ // the MRO, so they've both been registered manually. We don't know which was
173
+ // registered first so accept the object as either as a compromise.
174
+ loop_error_recovery:
175
+ Py_DECREF(mro);
176
+
177
+ end:
178
+ Py_XDECREF(abc_module);
179
+ Py_XDECREF(sequence_type);
180
+ Py_XDECREF(mapping_type);
181
+ return result;
182
+
183
+ loop_error:
184
+ PyErr_Clear();
185
+ goto loop_error_recovery;
186
+ }
187
+ #endif
188
+
189
+ ///////////////////////////// IsSequence.proto //////////////////////
190
+
191
+ static int __Pyx_MatchCase_IsSequence(PyObject *o, unsigned int *sequence_mapping_temp); /* proto */
192
+
193
+ //////////////////////////// IsSequence /////////////////////////
194
+ //@requires: ABCCheck
195
+
196
+ static int __Pyx_MatchCase_IsSequence(PyObject *o, unsigned int *sequence_mapping_temp) {
197
+ #if PY_VERSION_HEX >= 0x030A0000 && !(CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY)
198
+ CYTHON_UNUSED_VAR(sequence_mapping_temp);
199
+ return __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_SEQUENCE);
200
+ #else
201
+ #if CYTHON_COMPILING_IN_LIMITED_API
202
+ // In the Limited API we have runtime access to Py_TPFLAGS_SEQUENCE
203
+ // by looking it up on module init so it's still worth attempting
204
+ // the fast path.
205
+ if (__Pyx_Runtime_TPFLAGS_SEQUENCE) {
206
+ return __Pyx_PyType_HasFeature(Py_TYPE(o), __Pyx_Runtime_TPFLAGS_SEQUENCE);
207
+ }
208
+ #elif defined(Py_TPFLAGS_SEQUENCE)
209
+ // Elsewhere *we* define Py_TPFLAGS_SEQUENCE but that doesn't necessarily
210
+ // mean other types use it, so only success is meaningful.
211
+ if (__Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_SEQUENCE)) {
212
+ return 1;
213
+ }
214
+ #endif
215
+ // Py_TPFLAGS_SEQUENCE doesn't exit.
216
+ PyObject *o_module_name;
217
+ unsigned int abc_result, dummy=0;
218
+
219
+ if (sequence_mapping_temp) {
220
+ // maybe we already know the answer
221
+ if (*sequence_mapping_temp & __PYX_DEFINITELY_SEQUENCE_FLAG) {
222
+ return 1;
223
+ }
224
+ if (*sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG) {
225
+ return 0;
226
+ }
227
+ } else {
228
+ // Probably quicker to just assign it and not check from here.
229
+ sequence_mapping_temp = &dummy;
230
+ }
231
+
232
+ // Start by checking a known list of types.
233
+ if (__Pyx_MatchCase_IsExactSequence(o)) {
234
+ *sequence_mapping_temp |= (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
235
+ return 1;
236
+ }
237
+ if (__Pyx_MatchCase_IsExactMapping(o)) {
238
+ *sequence_mapping_temp |= (__PYX_DEFINITELY_MAPPING_FLAG | __PYX_DEFINITELY_NOT_SEQUENCE_FLAG);
239
+ return 0;
240
+ }
241
+ if (__Pyx_MatchCase_IsExactNeitherSequenceNorMapping(o)) {
242
+ *sequence_mapping_temp |= (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
243
+ return 0;
244
+ }
245
+
246
+ abc_result = __Pyx_MatchCase_ABCCheck(
247
+ o, 1,
248
+ *sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG,
249
+ *sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG
250
+ );
251
+ if (abc_result & __PYX_SEQUENCE_MAPPING_ERROR) {
252
+ return -1;
253
+ }
254
+ *sequence_mapping_temp = abc_result;
255
+ if (*sequence_mapping_temp & __PYX_DEFINITELY_SEQUENCE_FLAG) {
256
+ return 1;
257
+ }
258
+
259
+ // array.array is a more complicated check (and unfortunately isn't covered by
260
+ // collections.abc.Sequence on Python <3.10).
261
+ // Do the test by checking the module name, and then importing/testing the class.
262
+ // It also doesn't give perfect results for classes that inherit from both array.array
263
+ // and a mapping.
264
+ #if !CYTHON_COMPILING_IN_LIMITED_API || __PYX_LIMITED_VERSION_HEX < 0x030A0000
265
+ #if CYTHON_COMPILING_IN_LIMITED_API
266
+ if (__Pyx_get_runtime_version() < 0x030A0000)
267
+ #endif
268
+ {
269
+ o_module_name = PyObject_GetAttrString((PyObject*)Py_TYPE(o), "__module__");
270
+ if (!o_module_name) {
271
+ return -1;
272
+ }
273
+ if (PyUnicode_Check(o_module_name) && PyUnicode_CompareWithASCIIString(o_module_name, "array") == 0)
274
+ {
275
+ int is_array;
276
+ PyObject *array_module, *array_object;
277
+ Py_DECREF(o_module_name);
278
+ array_module = PyImport_ImportModule("array");
279
+ if (!array_module) {
280
+ PyErr_Clear();
281
+ return 0; // treat these tests as "soft" and don't cause an exception
282
+ }
283
+ array_object = PyObject_GetAttrString(array_module, "array");
284
+ Py_DECREF(array_module);
285
+ if (!array_object) {
286
+ PyErr_Clear();
287
+ return 0;
288
+ }
289
+ is_array = PyObject_IsInstance(o, array_object);
290
+ Py_DECREF(array_object);
291
+ if (is_array) {
292
+ *sequence_mapping_temp |= __PYX_DEFINITELY_SEQUENCE_FLAG;
293
+ return 1;
294
+ }
295
+ PyErr_Clear();
296
+ } else {
297
+ Py_DECREF(o_module_name);
298
+ }
299
+ }
300
+ #else
301
+ CYTHON_UNUSED_VAR(o_module_name);
302
+ #endif
303
+ *sequence_mapping_temp |= __PYX_DEFINITELY_NOT_SEQUENCE_FLAG;
304
+ return 0;
305
+ #endif
306
+ }
307
+
308
+ ////////////////////// OtherSequenceSliceToList.proto //////////////////////
309
+
310
+ static PyObject *__Pyx_MatchCase_OtherSequenceSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end); /* proto */
311
+
312
+ ////////////////////// OtherSequenceSliceToList //////////////////////////
313
+
314
+ // This is substantially based off ceval unpack_iterable.
315
+ // It's also pretty similar to itertools.islice.
316
+ // Indices must be positive - there's no wraparound or boundschecking.
317
+
318
+ static PyObject *__Pyx_MatchCase_OtherSequenceSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end) {
319
+ Py_ssize_t total = end-start;
320
+ Py_ssize_t i;
321
+ PyObject *list;
322
+ ssizeargfunc slot;
323
+
324
+ list = PyList_New(total);
325
+ if (!list) {
326
+ return NULL;
327
+ }
328
+
329
+ slot = __Pyx_PyObject_TryGetSubSlot(x, tp_as_sequence, sq_item, ssizeargfunc);
330
+ if (!slot) {
331
+ #if !CYTHON_COMPILING_IN_LIMITED_API && !defined(PySequence_ITEM)
332
+ // PyPy (and maybe others?) implements PySequence_ITEM as a function. In this case.
333
+ // it's slightly more efficient than using PySequence_GetItem since it skips negative indices.
334
+ slot = PySequence_ITEM;
335
+ #else
336
+ slot = PySequence_GetItem;
337
+ #endif
338
+ }
339
+
340
+ for (i=start; i<end; ++i) {
341
+ PyObject *obj = slot(x, i);
342
+ if (unlikely(!obj) || unlikely(__Pyx_PyList_SET_ITEM(list, i-start, obj) == -1)) {
343
+ Py_DECREF(list);
344
+ return NULL;
345
+ }
346
+ }
347
+ return list;
348
+ }
349
+
350
+ ////////////////////// TupleSliceToList.proto //////////////////////
351
+
352
+ static PyObject *__Pyx_MatchCase_TupleSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end); /* proto */
353
+
354
+ ////////////////////// TupleSliceToList //////////////////////////
355
+ //@requires: OtherSequenceSliceToList
356
+ //@requires: ObjectHandling.c::ListFromArray
357
+
358
+ // Indices must be positive - there's no wraparound or boundschecking.
359
+
360
+ static PyObject *__Pyx_MatchCase_TupleSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end) {
361
+ #if !CYTHON_COMPILING_IN_CPYTHON
362
+ return __Pyx_MatchCase_OtherSequenceSliceToList(x, start, end);
363
+ #else
364
+ PyObject **array;
365
+
366
+ (void)__Pyx_MatchCase_OtherSequenceSliceToList; // clear unused warning
367
+
368
+ array = &PyTuple_GET_ITEM(x, 0);
369
+ return __Pyx_PyList_FromArray(array+start, end-start);
370
+ #endif
371
+ }
372
+
373
+ ////////////////////////// UnknownTypeSliceToList.proto //////////////////////
374
+
375
+ static PyObject *__Pyx_MatchCase_UnknownTypeSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end); /* proto */
376
+
377
+ ////////////////////////// UnknownTypeSliceToList.proto //////////////////////
378
+ //@requires: TupleSliceToList
379
+ //@requires: OtherSequenceSliceToList
380
+
381
+ static PyObject *__Pyx_MatchCase_UnknownTypeSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end) {
382
+ if (PyList_CheckExact(x)) {
383
+ return PyList_GetSlice(x, start, end);
384
+ }
385
+ #if !CYTHON_COMPILING_IN_CPYTHON
386
+ // since __Pyx_MatchCase_TupleToList only does anything special in CPython, skip the check otherwise
387
+ if (PyTuple_CheckExact(x)) {
388
+ return __Pyx_MatchCase_TupleSliceToList(x, start, end);
389
+ }
390
+ #else
391
+ (void)__Pyx_MatchCase_TupleSliceToList;
392
+ #endif
393
+ return __Pyx_MatchCase_OtherSequenceSliceToList(x, start, end);
394
+ }
395
+
396
+ ///////////////////////////// IsMapping.proto //////////////////////
397
+
398
+ static int __Pyx_MatchCase_IsMapping(PyObject *o, unsigned int *sequence_mapping_temp); /* proto */
399
+
400
+ //////////////////////////// IsMapping /////////////////////////
401
+ //@requires: ABCCheck
402
+
403
+ static int __Pyx_MatchCase_IsMapping(PyObject *o, unsigned int *sequence_mapping_temp) {
404
+ #if PY_VERSION_HEX >= 0x030A0000 && !(CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY)
405
+ CYTHON_UNUSED_VAR(sequence_mapping_temp);
406
+ return __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_MAPPING);
407
+ #else
408
+ #if CYTHON_COMPILING_IN_LIMITED_API
409
+ // In the Limited API we have runtime access to Py_TPFLAGS_MAPPING
410
+ // by looking it up on module init so it's still worth attempting
411
+ // the fast path.
412
+ if (__Pyx_Runtime_TPFLAGS_MAPPING) {
413
+ return __Pyx_PyType_HasFeature(Py_TYPE(o), __Pyx_Runtime_TPFLAGS_MAPPING);
414
+ }
415
+ #elif defined(Py_TPFLAGS_MAPPING)
416
+ // Elsewhere *we* define Py_TPFLAGS_SEQUENCE but that doesn't necessarily
417
+ // mean other types use it, so only success is meaningful.
418
+ if (__Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_MAPPING)) {
419
+ return 1;
420
+ }
421
+ #endif
422
+ unsigned int abc_result, dummy=0;
423
+ if (sequence_mapping_temp) {
424
+ // do we already know the answer?
425
+ if (*sequence_mapping_temp & __PYX_DEFINITELY_MAPPING_FLAG) {
426
+ return 1;
427
+ } else if (*sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG) {
428
+ return 0;
429
+ }
430
+ } else {
431
+ sequence_mapping_temp = &dummy; // just so we can assign freely without checking
432
+ }
433
+
434
+ if (__Pyx_MatchCase_IsExactMapping(o)) {
435
+ *sequence_mapping_temp |= (__PYX_DEFINITELY_MAPPING_FLAG | __PYX_DEFINITELY_NOT_SEQUENCE_FLAG);
436
+ return 1;
437
+ }
438
+ if (__Pyx_MatchCase_IsExactSequence(o)) {
439
+ *sequence_mapping_temp |= (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
440
+ return 0;
441
+ }
442
+ if (__Pyx_MatchCase_IsExactNeitherSequenceNorMapping(o)) {
443
+ *sequence_mapping_temp |= (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
444
+ return 0;
445
+ }
446
+
447
+ // otherwise check against collections.abc.Mapping
448
+ abc_result = __Pyx_MatchCase_ABCCheck(
449
+ o, 0,
450
+ *sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG,
451
+ *sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG
452
+ );
453
+ if (abc_result & __PYX_SEQUENCE_MAPPING_ERROR) {
454
+ return -1;
455
+ }
456
+ *sequence_mapping_temp = abc_result;
457
+ return *sequence_mapping_temp & __PYX_DEFINITELY_MAPPING_FLAG;
458
+ #endif
459
+ }
460
+
461
+ //////////////////////// MappingKeyCheck.proto /////////////////////////
462
+
463
+ static int __Pyx_MatchCase_CheckMappingDuplicateKeys(PyObject *keys[], Py_ssize_t nFixedKeys, Py_ssize_t nKeys);
464
+
465
+ //////////////////////// MappingKeyCheck ///////////////////////////////
466
+
467
+ static int __Pyx_MatchCase_CheckMappingDuplicateKeys(PyObject *keys[], Py_ssize_t nFixedKeys, Py_ssize_t nKeys) {
468
+ // Inputs are arrays, and typically fairly small. It may be more efficient to
469
+ // loop over the array than create a set.
470
+
471
+ // The CPython implementation (match_keys in ceval.c) does this concurrently with
472
+ // taking the keys out of the dictionary. I'm choosing to do it separately since the
473
+ // majority of the time the keys will be known at compile-time so Cython can skip
474
+ // this step completely.
475
+ // The step is also skipped when there's only a single key.
476
+
477
+ PyObject *var_keys_set;
478
+ PyObject *key;
479
+ Py_ssize_t n;
480
+ int contains;
481
+
482
+ var_keys_set = PySet_New(NULL);
483
+ if (!var_keys_set) return -1;
484
+
485
+ for (n=nFixedKeys; n < nKeys; ++n) {
486
+ key = keys[n];
487
+ contains = PySet_Contains(var_keys_set, key);
488
+ if (contains < 0) {
489
+ goto bad;
490
+ } else if (contains == 1) {
491
+ goto raise_error;
492
+ } else {
493
+ if (PySet_Add(var_keys_set, key)) {
494
+ goto bad;
495
+ }
496
+ }
497
+ }
498
+ for (n=0; n < nFixedKeys; ++n) {
499
+ key = keys[n];
500
+ contains = PySet_Contains(var_keys_set, key);
501
+ if (contains < 0) {
502
+ goto bad;
503
+ } else if (contains == 1) {
504
+ goto raise_error;
505
+ }
506
+ }
507
+ Py_DECREF(var_keys_set);
508
+ return 0;
509
+
510
+ raise_error:
511
+ PyErr_Format(PyExc_ValueError,
512
+ "mapping pattern checks duplicate key (%R)", key);
513
+ bad:
514
+ Py_DECREF(var_keys_set);
515
+ return -1;
516
+ }
517
+
518
+ /////////////////////////// ExtractExactDict.proto ////////////////
519
+
520
+ // The subjects array is a list of PyObject** to subjects to be filled. They may be NULL
521
+ // in which case they're ignored.
522
+ //
523
+ // This is a specialized version for when we have an exact (frozen)dict (which is likely to be pretty common)
524
+
525
+ #if CYTHON_REFNANNY
526
+ #define __Pyx_MatchCase_Mapping_ExtractDict(...) __Pyx__MatchCase_Mapping_ExtractDict(__pyx_refnanny, __VA_ARGS__)
527
+ #else
528
+ #define __Pyx_MatchCase_Mapping_ExtractDict(...) __Pyx__MatchCase_Mapping_ExtractDict(NULL, __VA_ARGS__)
529
+ #endif
530
+ static CYTHON_INLINE int __Pyx__MatchCase_Mapping_ExtractDict(void *__pyx_refnanny, PyObject *dict, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]); /* proto */
531
+
532
+ /////////////////////////// ExtractExactDict ////////////////
533
+
534
+ static CYTHON_INLINE int __Pyx__MatchCase_Mapping_ExtractDict(void *__pyx_refnanny, PyObject *dict, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]) {
535
+ #if !CYTHON_REFNANNY
536
+ CYTHON_UNUSED_VAR(__pyx_refnanny);
537
+ #endif
538
+
539
+ Py_ssize_t i;
540
+ Py_ssize_t size;
541
+ size = PyDict_Size(dict);
542
+ if (size < nKeys) {
543
+ return size == -1 ? -1: 0;
544
+ }
545
+
546
+ for (i=0; i<nKeys; ++i) {
547
+ PyObject *key = keys[i];
548
+ PyObject **subject = subjects[i];
549
+ if (!subject) {
550
+ int contains = PyDict_Contains(dict, key);
551
+ if (contains <= 0) {
552
+ return contains; // any subjects that were already set will be cleaned up externally
553
+ }
554
+ } else {
555
+ PyObject *value;
556
+ int getref_result = __Pyx_PyDict_GetItemRef(dict, key, &value);
557
+ if (getref_result != 1) {
558
+ return getref_result; // any subjects that were already set will be cleaned up externally
559
+ }
560
+ __Pyx_GOTREF(value);
561
+ __Pyx_XDECREF_SET(*subject, value);
562
+ }
563
+ }
564
+ return 1; // success
565
+ }
566
+
567
+ ///////////////////////// ExtractNonDict.proto ////////////////////////////////
568
+
569
+ // The subjects array is a list of PyObject** to subjects to be filled. They may be NULL
570
+ // in which case they're ignored.
571
+ //
572
+ // This is a specialized version for the rarer case when the type isn't an exact dict.
573
+
574
+ #if CYTHON_REFNANNY
575
+ #define __Pyx_MatchCase_Mapping_ExtractNonDict(...) __Pyx__MatchCase_Mapping_ExtractNonDict(__pyx_refnanny, __VA_ARGS__)
576
+ #else
577
+ #define __Pyx_MatchCase_Mapping_ExtractNonDict(...) __Pyx__MatchCase_Mapping_ExtractNonDict(NULL, __VA_ARGS__)
578
+ #endif
579
+ static CYTHON_INLINE int __Pyx__MatchCase_Mapping_ExtractNonDict(void *__pyx_refnanny, PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]); /* proto */
580
+
581
+ ///////////////////////// ExtractNonDict //////////////////////////////////////
582
+ //@requires: ObjectHandling.c::PyObjectCall2Args
583
+
584
+ // largely adapted from match_keys in CPython ceval.c
585
+
586
+ static int __Pyx__MatchCase_Mapping_ExtractNonDict(void *__pyx_refnanny, PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]) {
587
+ PyObject *dummy=NULL, *get=NULL;
588
+ Py_ssize_t i, size;
589
+ int result = 0;
590
+ #if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL
591
+ PyObject *get_method = NULL, *get_self = NULL;
592
+ #endif
593
+
594
+ #if !CYTHON_REFNANNY
595
+ CYTHON_UNUSED_VAR(__pyx_refnanny);
596
+ #endif
597
+
598
+ // Length check is undocumented but does take place in CPython and is probably worthwhile.
599
+ size = PyObject_Length(mapping);
600
+ if (size < nKeys) {
601
+ return size == -1 ? -1: 0;
602
+ }
603
+
604
+ dummy = PyObject_CallObject((PyObject *)&PyBaseObject_Type, NULL);
605
+ if (!dummy) {
606
+ return -1;
607
+ }
608
+ get = PyObject_GetAttr(mapping, PYIDENT("get"));
609
+ if (!get) {
610
+ result = -1;
611
+ goto end;
612
+ }
613
+ #if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL
614
+ if (likely(PyMethod_Check(get))) {
615
+ // both of these are borrowed
616
+ get_method = PyMethod_GET_FUNCTION(get);
617
+ get_self = PyMethod_GET_SELF(get);
618
+ }
619
+ #endif
620
+
621
+ for (i=0; i<nKeys; ++i) {
622
+ PyObject **subject;
623
+ PyObject *value = NULL;
624
+ PyObject *key = keys[i];
625
+
626
+ // TODO - there's an optimization here (although it deviates from the strict definition of pattern matching).
627
+ // If we don't need the values then we can call PyObject_Contains instead of "get". If we don't need *any*
628
+ // of the values then we can skip initialization "get" and "dummy"
629
+ #if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL
630
+ if (likely(get_method)) {
631
+ PyObject *args[] = { get_self, key, dummy };
632
+ value = PyObject_Vectorcall(get_method, args, 3, NULL);
633
+ }
634
+ else
635
+ #endif
636
+ {
637
+ value = __Pyx_PyObject_Call2Args(get, key, dummy);
638
+ }
639
+ if (!value) {
640
+ result = -1;
641
+ goto end;
642
+ } else if (value == dummy) {
643
+ Py_DECREF(value);
644
+ goto end; // failed to match.
645
+ } else {
646
+ subject = subjects[i];
647
+ if (subject) {
648
+ __Pyx_XDECREF_SET(*subject, value);
649
+ __Pyx_GOTREF(*subject);
650
+ } else {
651
+ Py_DECREF(value);
652
+ }
653
+ }
654
+ }
655
+ result = 1;
656
+
657
+ end:
658
+ Py_XDECREF(dummy);
659
+ Py_XDECREF(get);
660
+ return result;
661
+ }
662
+
663
+ ///////////////////////// ExtractGeneric.proto ////////////////////////////////
664
+
665
+ #if CYTHON_REFNANNY
666
+ #define __Pyx_MatchCase_Mapping_Extract(...) __Pyx__MatchCase_Mapping_Extract(__pyx_refnanny, __VA_ARGS__)
667
+ #else
668
+ #define __Pyx_MatchCase_Mapping_Extract(...) __Pyx__MatchCase_Mapping_Extract(NULL, __VA_ARGS__)
669
+ #endif
670
+ static CYTHON_INLINE int __Pyx__MatchCase_Mapping_Extract(void *__pyx_refnanny, PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]); /* proto */
671
+
672
+ ////////////////////// ExtractGeneric //////////////////////////////////////
673
+ //@requires: ExtractExactDict
674
+ //@requires: ExtractNonDict
675
+ //@requires: Builtins.c::PyFrozenDict
676
+
677
+ static CYTHON_INLINE int __Pyx__MatchCase_Mapping_Extract(void *__pyx_refnanny, PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]) {
678
+ if (__Pyx_PyAnyDict_CheckExact(mapping)) {
679
+ return __Pyx__MatchCase_Mapping_ExtractDict(__pyx_refnanny, mapping, keys, nKeys, subjects);
680
+ } else {
681
+ return __Pyx__MatchCase_Mapping_ExtractNonDict(__pyx_refnanny, mapping, keys, nKeys, subjects);
682
+ }
683
+ }
684
+
685
+ ///////////////////////////// DoubleStarCapture.proto //////////////////////
686
+
687
+ static PyObject* __Pyx_MatchCase_DoubleStarCapture{{tag}}(PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys); /* proto */
688
+
689
+ //////////////////////////// DoubleStarCapture //////////////////////////////
690
+ //@requires: Builtins.c::PyFrozenDict
691
+
692
+ // The implementation is largely copied from the original COPY_DICT_WITHOUT_KEYS opcode
693
+ // implementation of CPython
694
+ // https://github.com/python/cpython/blob/145bf269df3530176f6ebeab1324890ef7070bf8/Python/ceval.c#L3977
695
+ // (now removed in favour of building the same thing from a combination of opcodes)
696
+ // The differences are:
697
+ // 1. We use an array of keys rather than a tuple of keys
698
+ // 2. We add a shortcut for when there will be no left over keys (because I guess it's pretty common)
699
+ //
700
+ // Tempita variable 'tag' can be "NonDict", "ExactDict", "ExactFrozenDict" or empty
701
+
702
+ static PyObject* __Pyx_MatchCase_DoubleStarCapture{{tag}}(PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys) {
703
+ PyObject *dict_out;
704
+ Py_ssize_t i, size;
705
+
706
+ // shortcut for when there are no left-over keys
707
+ {{if tag=="ExactDict" or tag=="ExactFrozenDict"}}
708
+ if ((1))
709
+ {{else}}
710
+ if (__Pyx_PyAnyDict_CheckExact(mapping))
711
+ {{endif}}
712
+ {
713
+ size = PyDict_Size(mapping);
714
+ } else {
715
+ size = PyObject_Length(mapping);
716
+ }
717
+ if (unlikely(size == -1)) return NULL;
718
+ if (size == nKeys) {
719
+ return PyDict_New();
720
+ }
721
+
722
+ {{if tag=="ExactDict"}}
723
+ dict_out = PyDict_Copy(mapping);
724
+ {{else}}
725
+ dict_out = PyDict_New();
726
+ {{endif}}
727
+ if (!dict_out) {
728
+ return NULL;
729
+ }
730
+ {{if tag!="ExactDict"}}
731
+ if (PyDict_Update(dict_out, mapping)) {
732
+ Py_DECREF(dict_out);
733
+ return NULL;
734
+ }
735
+ {{endif}}
736
+
737
+ for (i=0; i<nKeys; ++i) {
738
+ if (PyDict_DelItem(dict_out, keys[i])) {
739
+ Py_DECREF(dict_out);
740
+ return NULL;
741
+ }
742
+ }
743
+ return dict_out;
744
+ }
745
+
746
+ ////////////////////////////// ClassPositionalPatterns.proto ////////////////////////
747
+
748
+ #if CYTHON_REFNANNY
749
+ #define __Pyx_MatchCase_ClassPositional(...) __Pyx__MatchCase_ClassPositional(__pyx_refnanny, __VA_ARGS__)
750
+ #else
751
+ #define __Pyx_MatchCase_ClassPositional(...) __Pyx__MatchCase_ClassPositional(NULL, __VA_ARGS__)
752
+ #endif
753
+ static int __Pyx__MatchCase_ClassPositional(void *__pyx_refnanny, PyObject *subject, PyObject *type, PyObject *fixed_names[], Py_ssize_t n_fixed, int match_self, PyObject **subjects[], Py_ssize_t n_subjects); /* proto */
754
+
755
+ /////////////////////////// ClassPositionalPatterns //////////////////////////////
756
+ //@requires: ObjectHandling.c::RaiseErrorWithObjectTypes
757
+ //@requires: ObjectHandling.c::RaiseErrorWithObjectType
758
+ //@requires: ObjectHandling.c::RaiseErrorWithTypeAndVarargs
759
+ //@requires: Builtins.c::PyFrozenDict
760
+
761
+ static int __Pyx_MatchCase_ClassCheckDuplicateAttrs(PyTypeObject *type, PyObject *fixed_names[], Py_ssize_t n_fixed, PyObject *match_args, Py_ssize_t num_args) {
762
+ // a lot of the basic logic of this is shared with __Pyx_MatchCase_CheckMappingDuplicateKeys
763
+ // but they take different input types so it isn't easy to actually share the code.
764
+
765
+ // Inputs are tuples, and typically fairly small. It may be more efficient to
766
+ // loop over the tuple than create a set.
767
+
768
+ PyObject *attrs_set;
769
+ PyObject *attr = NULL;
770
+ Py_ssize_t n, match_args_size;
771
+ int contains;
772
+
773
+ match_args_size = __Pyx_PyTuple_GET_SIZE(match_args);
774
+ if (n_fixed == 0 && match_args_size == 1) {
775
+ // Trivial cases where there can be no duplicates.
776
+ // (In the match_args_size == 0 trivial case, this function is never called).
777
+ return 0;
778
+ }
779
+ #if !CYTHON_ASSUME_SAFE_SIZE
780
+ if (unlikely(match_args_size < 0)) return -1;
781
+ #endif
782
+
783
+ attrs_set = PySet_New(NULL);
784
+ if (unlikely(!attrs_set)) return -1;
785
+
786
+ num_args = match_args_size < num_args ? match_args_size : num_args;
787
+ for (n=0; n < num_args; ++n) {
788
+ attr = __Pyx_PyTuple_GET_ITEM(match_args, n);
789
+ #if !CYTHON_ASSUME_SAFE_MACROS
790
+ if (unlikely(!attr)) goto bad;
791
+ #endif
792
+ contains = PySet_Contains(attrs_set, attr);
793
+ if (contains < 0) {
794
+ goto bad;
795
+ } else if (contains == 1) {
796
+ goto raise_error;
797
+ } else {
798
+ if (PySet_Add(attrs_set, attr)) {
799
+ goto bad;
800
+ }
801
+ }
802
+ }
803
+ for (n=0; n < n_fixed; ++n) {
804
+ attr = fixed_names[n];
805
+ contains = PySet_Contains(attrs_set, attr);
806
+ if (contains < 0) {
807
+ goto bad;
808
+ } else if (contains == 1) {
809
+ goto raise_error;
810
+ }
811
+ }
812
+ Py_DECREF(attrs_set);
813
+ return 0;
814
+
815
+ raise_error:
816
+ __Pyx_RaiseErrorWithTypeAndVarargs(
817
+ PyExc_TypeError,
818
+ __Pyx_FMT_TYPENAME "() got multiple sub-patterns for attribute %R",
819
+ type, attr
820
+ );
821
+ bad:
822
+ Py_DECREF(attrs_set);
823
+ return -1;
824
+ }
825
+
826
+ // Adapted from ceval.c "match_class" in CPython
827
+ //
828
+ // The argument match_self can equal 1 for "known to be true"
829
+ // 0 for "known to be false"
830
+ // -1 for "unknown", runtime test
831
+ // n_subjects is >= 0 otherwise this function will be skipped
832
+ static int __Pyx__MatchCase_ClassPositional(void *__pyx_refnanny, PyObject *subject, PyObject *type_o, PyObject *fixed_names[], Py_ssize_t n_fixed, int match_self, PyObject **subjects[], Py_ssize_t n_subjects)
833
+ {
834
+ PyObject *match_args = NULL;
835
+ Py_ssize_t allowed, i;
836
+ int result;
837
+
838
+ assert(PyType_Check(type_o));
839
+
840
+ PyTypeObject *type = (PyTypeObject*)type_o;
841
+
842
+ #if !CYTHON_REFNANNY
843
+ CYTHON_UNUSED_VAR(__pyx_refnanny);
844
+ #endif
845
+
846
+ if (match_self != 1) {
847
+ #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000
848
+ if (PyObject_GetOptionalAttr(type_o, PYIDENT("__match_args__"), &match_args) == -1) {
849
+ return -1;
850
+ }
851
+ #else
852
+ match_args = PyObject_GetAttr(type_o, PYIDENT("__match_args__"));
853
+ if (!match_args) {
854
+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
855
+ PyErr_Clear();
856
+ } else {
857
+ return -1;
858
+ }
859
+ }
860
+ #endif
861
+ }
862
+ if (match_args) {
863
+ match_self = 0;
864
+ if (!PyTuple_CheckExact(match_args)) {
865
+ __Pyx_RaiseTypeErrorWithTypes(
866
+ __Pyx_FMT_TYPENAME ".__match_args__ must be a tuple (got " __Pyx_FMT_TYPENAME ")",
867
+ type, Py_TYPE(match_args));
868
+ Py_DECREF(match_args);
869
+ return -1;
870
+ }
871
+ } else if (!match_args && match_self == -1) {
872
+ // Mysteriously, this private flag seems to have ended up defined in the Limited API
873
+ #if defined(_Py_TPFLAGS_MATCH_SELF) && !CYTHON_COMPILING_IN_PYPY && !(CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000)
874
+ match_self = PyType_HasFeature(type, _Py_TPFLAGS_MATCH_SELF);
875
+ #else
876
+ // probably an earlier version of Python. Go off the known list in the specification
877
+ match_self = ((PyType_GetFlags(type) &
878
+ // long should capture bool too
879
+ (Py_TPFLAGS_LONG_SUBCLASS | Py_TPFLAGS_LIST_SUBCLASS | Py_TPFLAGS_TUPLE_SUBCLASS |
880
+ Py_TPFLAGS_BYTES_SUBCLASS | Py_TPFLAGS_UNICODE_SUBCLASS | Py_TPFLAGS_DICT_SUBCLASS
881
+ )) ||
882
+ PyType_IsSubtype(type, &PyByteArray_Type) ||
883
+ PyType_IsSubtype(type, &PyFloat_Type) ||
884
+ PyType_IsSubtype(type, &PyFrozenSet_Type)
885
+ #if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030F0000
886
+ || PyType_IsSubtype(type, __Pyx_PyFrozenDict_TypePtr)
887
+ #endif
888
+ );
889
+ #endif
890
+ }
891
+
892
+ if (match_self) {
893
+ allowed = 1;
894
+ } else if (match_args) {
895
+ allowed = __Pyx_PyTuple_GET_SIZE(match_args);
896
+ #if !CYTHON_ASSUME_SAFE_SIZE
897
+ if (unlikely(allowed < 0)) goto end;
898
+ #endif
899
+ } else {
900
+ allowed = 0;
901
+ }
902
+ if (unlikely(allowed < n_subjects)) {
903
+ const char *plural = (allowed == 1) ? "" : "s";
904
+ __Pyx_RaiseErrorWithTypeAndVarargs(
905
+ PyExc_TypeError,
906
+ __Pyx_FMT_TYPENAME "() accepts %d positional sub-pattern%s (%d given)",
907
+ type, allowed, plural, n_subjects
908
+ );
909
+ Py_XDECREF(match_args);
910
+ return -1;
911
+ }
912
+ if (match_self) {
913
+ PyObject **self_subject = subjects[0];
914
+ if (self_subject) {
915
+ // Easy. Copy the subject itself, and move on to kwargs.
916
+ __Pyx_XDECREF_SET(*self_subject, subject);
917
+ __Pyx_INCREF(*self_subject);
918
+ }
919
+ result = 1;
920
+ goto end_match_self;
921
+ }
922
+ // next stage is to check for duplicate attributes.
923
+ if (__Pyx_MatchCase_ClassCheckDuplicateAttrs(type, fixed_names, n_fixed, match_args, n_subjects)) {
924
+ result = -1;
925
+ goto end;
926
+ }
927
+
928
+ for (i = 0; i < n_subjects; i++) {
929
+ PyObject *attr;
930
+ PyObject **subject_i;
931
+ PyObject *name = __Pyx_PyTuple_GET_ITEM(match_args, i);
932
+ #if !CYTHON_ASSUME_SAFE_MACROS
933
+ if (unlikely(!name)) {
934
+ result = -1;
935
+ goto end;
936
+ }
937
+ #endif
938
+ if (!PyUnicode_CheckExact(name)) {
939
+ __Pyx_RaiseTypeErrorWithObjectType(
940
+ "__match_args__ elements must be strings (got " __Pyx_FMT_TYPENAME ")",
941
+ name);
942
+ result = -1;
943
+ goto end;
944
+ }
945
+
946
+ attr = PyObject_GetAttr(subject, name);
947
+ if (attr == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
948
+ PyErr_Clear();
949
+ result = 0;
950
+ goto end;
951
+ }
952
+ subject_i = subjects[i];
953
+ if (subject_i) {
954
+ __Pyx_XDECREF_SET(*subject_i, attr);
955
+ __Pyx_GOTREF(attr);
956
+ } else {
957
+ Py_DECREF(attr);
958
+ }
959
+ }
960
+ result = 1;
961
+
962
+ end:
963
+ Py_DECREF(match_args);
964
+ end_match_self: // because match_args isn't set
965
+ return result;
966
+ }
967
+
968
+ //////////////////////// MatchClassTypeGuard.proto /////////////////////////////
969
+
970
+ static PyObject* __Pyx_MatchCase_TypeGuard(PyObject* type); /* proto */
971
+
972
+ //////////////////////// MatchClassTypeGuard /////////////////////////////
973
+
974
+ static PyObject* __Pyx_MatchCase_TypeGuard(PyObject* type) {
975
+ if (!PyType_Check(type)) {
976
+ PyErr_Format(PyExc_TypeError, "called match pattern must be a type");
977
+ return NULL;
978
+ }
979
+ Py_INCREF(type);
980
+ return type;
981
+ }