Cython 3.1.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. Cython/Build/BuildExecutable.py +169 -0
  2. Cython/Build/Cache.py +199 -0
  3. Cython/Build/Cythonize.py +250 -0
  4. Cython/Build/Dependencies.py +1275 -0
  5. Cython/Build/Distutils.py +1 -0
  6. Cython/Build/Inline.py +342 -0
  7. Cython/Build/IpythonMagic.py +560 -0
  8. Cython/Build/Tests/TestCyCache.py +119 -0
  9. Cython/Build/Tests/TestCythonizeArgsParser.py +481 -0
  10. Cython/Build/Tests/TestDependencies.py +133 -0
  11. Cython/Build/Tests/TestInline.py +112 -0
  12. Cython/Build/Tests/TestIpythonMagic.py +287 -0
  13. Cython/Build/Tests/TestRecythonize.py +212 -0
  14. Cython/Build/Tests/TestStripLiterals.py +155 -0
  15. Cython/Build/Tests/__init__.py +1 -0
  16. Cython/Build/__init__.py +8 -0
  17. Cython/CodeWriter.py +811 -0
  18. Cython/Compiler/AnalysedTreeTransforms.py +97 -0
  19. Cython/Compiler/Annotate.py +326 -0
  20. Cython/Compiler/AutoDocTransforms.py +314 -0
  21. Cython/Compiler/Buffer.py +680 -0
  22. Cython/Compiler/Builtin.py +862 -0
  23. Cython/Compiler/CmdLine.py +243 -0
  24. Cython/Compiler/Code.pxd +145 -0
  25. Cython/Compiler/Code.py +3328 -0
  26. Cython/Compiler/CodeGeneration.py +33 -0
  27. Cython/Compiler/CythonScope.py +179 -0
  28. Cython/Compiler/Dataclass.py +868 -0
  29. Cython/Compiler/DebugFlags.py +21 -0
  30. Cython/Compiler/Errors.py +295 -0
  31. Cython/Compiler/ExprNodes.py +15051 -0
  32. Cython/Compiler/FlowControl.pxd +97 -0
  33. Cython/Compiler/FlowControl.py +1438 -0
  34. Cython/Compiler/FusedNode.py +998 -0
  35. Cython/Compiler/Future.py +16 -0
  36. Cython/Compiler/Interpreter.py +57 -0
  37. Cython/Compiler/Lexicon.py +340 -0
  38. Cython/Compiler/LineTable.py +114 -0
  39. Cython/Compiler/Main.py +779 -0
  40. Cython/Compiler/MatchCaseNodes.py +259 -0
  41. Cython/Compiler/MemoryView.py +860 -0
  42. Cython/Compiler/ModuleNode.py +4065 -0
  43. Cython/Compiler/Naming.py +369 -0
  44. Cython/Compiler/Nodes.py +10557 -0
  45. Cython/Compiler/Optimize.py +5269 -0
  46. Cython/Compiler/Options.py +828 -0
  47. Cython/Compiler/ParseTreeTransforms.pxd +78 -0
  48. Cython/Compiler/ParseTreeTransforms.py +4441 -0
  49. Cython/Compiler/Parsing.pxd +9 -0
  50. Cython/Compiler/Parsing.py +4797 -0
  51. Cython/Compiler/Pipeline.py +425 -0
  52. Cython/Compiler/PyrexTypes.py +5572 -0
  53. Cython/Compiler/Pythran.py +223 -0
  54. Cython/Compiler/Scanning.pxd +40 -0
  55. Cython/Compiler/Scanning.py +574 -0
  56. Cython/Compiler/StringEncoding.py +347 -0
  57. Cython/Compiler/Symtab.py +2998 -0
  58. Cython/Compiler/Tests/TestBuffer.py +105 -0
  59. Cython/Compiler/Tests/TestBuiltin.py +72 -0
  60. Cython/Compiler/Tests/TestCmdLine.py +573 -0
  61. Cython/Compiler/Tests/TestCode.py +86 -0
  62. Cython/Compiler/Tests/TestFlowControl.py +65 -0
  63. Cython/Compiler/Tests/TestGrammar.py +202 -0
  64. Cython/Compiler/Tests/TestMemView.py +71 -0
  65. Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
  66. Cython/Compiler/Tests/TestScanning.py +134 -0
  67. Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
  68. Cython/Compiler/Tests/TestStringEncoding.py +33 -0
  69. Cython/Compiler/Tests/TestTreeFragment.py +63 -0
  70. Cython/Compiler/Tests/TestTreePath.py +93 -0
  71. Cython/Compiler/Tests/TestTypes.py +75 -0
  72. Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
  73. Cython/Compiler/Tests/TestVisitor.py +61 -0
  74. Cython/Compiler/Tests/Utils.py +36 -0
  75. Cython/Compiler/Tests/__init__.py +1 -0
  76. Cython/Compiler/TreeFragment.py +278 -0
  77. Cython/Compiler/TreePath.py +290 -0
  78. Cython/Compiler/TypeInference.py +584 -0
  79. Cython/Compiler/TypeSlots.py +1181 -0
  80. Cython/Compiler/UFuncs.py +311 -0
  81. Cython/Compiler/UtilNodes.py +387 -0
  82. Cython/Compiler/UtilityCode.py +274 -0
  83. Cython/Compiler/Version.py +8 -0
  84. Cython/Compiler/Visitor.pxd +53 -0
  85. Cython/Compiler/Visitor.py +861 -0
  86. Cython/Compiler/__init__.py +1 -0
  87. Cython/Coverage.py +443 -0
  88. Cython/Debugger/Cygdb.py +179 -0
  89. Cython/Debugger/DebugWriter.py +82 -0
  90. Cython/Debugger/Tests/TestLibCython.py +275 -0
  91. Cython/Debugger/Tests/__init__.py +1 -0
  92. Cython/Debugger/Tests/cfuncs.c +8 -0
  93. Cython/Debugger/Tests/codefile +49 -0
  94. Cython/Debugger/Tests/test_libcython_in_gdb.py +578 -0
  95. Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
  96. Cython/Debugger/__init__.py +1 -0
  97. Cython/Debugger/libcython.py +1549 -0
  98. Cython/Debugger/libpython.py +2821 -0
  99. Cython/Debugging.py +20 -0
  100. Cython/Distutils/__init__.py +2 -0
  101. Cython/Distutils/build_ext.py +137 -0
  102. Cython/Distutils/extension.py +96 -0
  103. Cython/Distutils/old_build_ext.py +351 -0
  104. Cython/Includes/cpython/__init__.pxd +173 -0
  105. Cython/Includes/cpython/array.pxd +174 -0
  106. Cython/Includes/cpython/bool.pxd +37 -0
  107. Cython/Includes/cpython/buffer.pxd +112 -0
  108. Cython/Includes/cpython/bytearray.pxd +33 -0
  109. Cython/Includes/cpython/bytes.pxd +200 -0
  110. Cython/Includes/cpython/cellobject.pxd +35 -0
  111. Cython/Includes/cpython/ceval.pxd +8 -0
  112. Cython/Includes/cpython/codecs.pxd +121 -0
  113. Cython/Includes/cpython/complex.pxd +55 -0
  114. Cython/Includes/cpython/contextvars.pxd +141 -0
  115. Cython/Includes/cpython/conversion.pxd +36 -0
  116. Cython/Includes/cpython/datetime.pxd +384 -0
  117. Cython/Includes/cpython/descr.pxd +26 -0
  118. Cython/Includes/cpython/dict.pxd +187 -0
  119. Cython/Includes/cpython/exc.pxd +263 -0
  120. Cython/Includes/cpython/fileobject.pxd +57 -0
  121. Cython/Includes/cpython/float.pxd +47 -0
  122. Cython/Includes/cpython/function.pxd +65 -0
  123. Cython/Includes/cpython/genobject.pxd +25 -0
  124. Cython/Includes/cpython/getargs.pxd +12 -0
  125. Cython/Includes/cpython/instance.pxd +25 -0
  126. Cython/Includes/cpython/iterator.pxd +36 -0
  127. Cython/Includes/cpython/iterobject.pxd +24 -0
  128. Cython/Includes/cpython/list.pxd +92 -0
  129. Cython/Includes/cpython/long.pxd +149 -0
  130. Cython/Includes/cpython/longintrepr.pxd +19 -0
  131. Cython/Includes/cpython/mapping.pxd +63 -0
  132. Cython/Includes/cpython/marshal.pxd +66 -0
  133. Cython/Includes/cpython/mem.pxd +120 -0
  134. Cython/Includes/cpython/memoryview.pxd +50 -0
  135. Cython/Includes/cpython/method.pxd +49 -0
  136. Cython/Includes/cpython/module.pxd +208 -0
  137. Cython/Includes/cpython/number.pxd +258 -0
  138. Cython/Includes/cpython/object.pxd +433 -0
  139. Cython/Includes/cpython/pycapsule.pxd +143 -0
  140. Cython/Includes/cpython/pylifecycle.pxd +68 -0
  141. Cython/Includes/cpython/pyport.pxd +8 -0
  142. Cython/Includes/cpython/pystate.pxd +95 -0
  143. Cython/Includes/cpython/pythread.pxd +53 -0
  144. Cython/Includes/cpython/ref.pxd +67 -0
  145. Cython/Includes/cpython/sequence.pxd +134 -0
  146. Cython/Includes/cpython/set.pxd +119 -0
  147. Cython/Includes/cpython/slice.pxd +70 -0
  148. Cython/Includes/cpython/time.pxd +129 -0
  149. Cython/Includes/cpython/tuple.pxd +72 -0
  150. Cython/Includes/cpython/type.pxd +53 -0
  151. Cython/Includes/cpython/unicode.pxd +639 -0
  152. Cython/Includes/cpython/version.pxd +32 -0
  153. Cython/Includes/cpython/weakref.pxd +42 -0
  154. Cython/Includes/libc/__init__.pxd +1 -0
  155. Cython/Includes/libc/complex.pxd +35 -0
  156. Cython/Includes/libc/errno.pxd +127 -0
  157. Cython/Includes/libc/float.pxd +43 -0
  158. Cython/Includes/libc/limits.pxd +28 -0
  159. Cython/Includes/libc/locale.pxd +46 -0
  160. Cython/Includes/libc/math.pxd +209 -0
  161. Cython/Includes/libc/setjmp.pxd +10 -0
  162. Cython/Includes/libc/signal.pxd +64 -0
  163. Cython/Includes/libc/stddef.pxd +9 -0
  164. Cython/Includes/libc/stdint.pxd +105 -0
  165. Cython/Includes/libc/stdio.pxd +80 -0
  166. Cython/Includes/libc/stdlib.pxd +72 -0
  167. Cython/Includes/libc/string.pxd +50 -0
  168. Cython/Includes/libc/time.pxd +47 -0
  169. Cython/Includes/libcpp/__init__.pxd +4 -0
  170. Cython/Includes/libcpp/algorithm.pxd +320 -0
  171. Cython/Includes/libcpp/any.pxd +16 -0
  172. Cython/Includes/libcpp/atomic.pxd +59 -0
  173. Cython/Includes/libcpp/bit.pxd +29 -0
  174. Cython/Includes/libcpp/cast.pxd +12 -0
  175. Cython/Includes/libcpp/cmath.pxd +518 -0
  176. Cython/Includes/libcpp/complex.pxd +106 -0
  177. Cython/Includes/libcpp/deque.pxd +165 -0
  178. Cython/Includes/libcpp/execution.pxd +15 -0
  179. Cython/Includes/libcpp/forward_list.pxd +63 -0
  180. Cython/Includes/libcpp/functional.pxd +26 -0
  181. Cython/Includes/libcpp/iterator.pxd +34 -0
  182. Cython/Includes/libcpp/limits.pxd +61 -0
  183. Cython/Includes/libcpp/list.pxd +117 -0
  184. Cython/Includes/libcpp/map.pxd +252 -0
  185. Cython/Includes/libcpp/memory.pxd +115 -0
  186. Cython/Includes/libcpp/numbers.pxd +15 -0
  187. Cython/Includes/libcpp/numeric.pxd +131 -0
  188. Cython/Includes/libcpp/optional.pxd +34 -0
  189. Cython/Includes/libcpp/pair.pxd +1 -0
  190. Cython/Includes/libcpp/queue.pxd +25 -0
  191. Cython/Includes/libcpp/random.pxd +166 -0
  192. Cython/Includes/libcpp/set.pxd +228 -0
  193. Cython/Includes/libcpp/stack.pxd +11 -0
  194. Cython/Includes/libcpp/string.pxd +333 -0
  195. Cython/Includes/libcpp/typeindex.pxd +15 -0
  196. Cython/Includes/libcpp/typeinfo.pxd +10 -0
  197. Cython/Includes/libcpp/unordered_map.pxd +193 -0
  198. Cython/Includes/libcpp/unordered_set.pxd +152 -0
  199. Cython/Includes/libcpp/utility.pxd +30 -0
  200. Cython/Includes/libcpp/vector.pxd +167 -0
  201. Cython/Includes/openmp.pxd +50 -0
  202. Cython/Includes/posix/__init__.pxd +1 -0
  203. Cython/Includes/posix/dlfcn.pxd +14 -0
  204. Cython/Includes/posix/fcntl.pxd +86 -0
  205. Cython/Includes/posix/ioctl.pxd +4 -0
  206. Cython/Includes/posix/mman.pxd +101 -0
  207. Cython/Includes/posix/resource.pxd +57 -0
  208. Cython/Includes/posix/select.pxd +21 -0
  209. Cython/Includes/posix/signal.pxd +73 -0
  210. Cython/Includes/posix/stat.pxd +98 -0
  211. Cython/Includes/posix/stdio.pxd +37 -0
  212. Cython/Includes/posix/stdlib.pxd +29 -0
  213. Cython/Includes/posix/strings.pxd +9 -0
  214. Cython/Includes/posix/time.pxd +71 -0
  215. Cython/Includes/posix/types.pxd +30 -0
  216. Cython/Includes/posix/uio.pxd +26 -0
  217. Cython/Includes/posix/unistd.pxd +271 -0
  218. Cython/Includes/posix/wait.pxd +38 -0
  219. Cython/Plex/Actions.pxd +24 -0
  220. Cython/Plex/Actions.py +119 -0
  221. Cython/Plex/DFA.pxd +14 -0
  222. Cython/Plex/DFA.py +164 -0
  223. Cython/Plex/Errors.py +48 -0
  224. Cython/Plex/Lexicons.py +178 -0
  225. Cython/Plex/Machines.pxd +36 -0
  226. Cython/Plex/Machines.py +238 -0
  227. Cython/Plex/Regexps.py +539 -0
  228. Cython/Plex/Scanners.pxd +47 -0
  229. Cython/Plex/Scanners.py +360 -0
  230. Cython/Plex/Transitions.pxd +14 -0
  231. Cython/Plex/Transitions.py +239 -0
  232. Cython/Plex/__init__.py +34 -0
  233. Cython/Runtime/__init__.py +1 -0
  234. Cython/Runtime/refnanny.pyx +261 -0
  235. Cython/Shadow.py +656 -0
  236. Cython/Shadow.pyi +521 -0
  237. Cython/StringIOTree.py +170 -0
  238. Cython/Tempita/__init__.py +4 -0
  239. Cython/Tempita/_looper.py +154 -0
  240. Cython/Tempita/_tempita.py +1091 -0
  241. Cython/TestUtils.py +417 -0
  242. Cython/Tests/TestCodeWriter.py +128 -0
  243. Cython/Tests/TestCythonUtils.py +202 -0
  244. Cython/Tests/TestJediTyper.py +223 -0
  245. Cython/Tests/TestShadow.py +114 -0
  246. Cython/Tests/TestStringIOTree.py +67 -0
  247. Cython/Tests/TestTestUtils.py +90 -0
  248. Cython/Tests/__init__.py +1 -0
  249. Cython/Tests/xmlrunner.py +390 -0
  250. Cython/Utility/AsyncGen.c +1263 -0
  251. Cython/Utility/Buffer.c +875 -0
  252. Cython/Utility/Builtins.c +660 -0
  253. Cython/Utility/CConvert.pyx +134 -0
  254. Cython/Utility/CMath.c +95 -0
  255. Cython/Utility/CommonStructures.c +139 -0
  256. Cython/Utility/Complex.c +378 -0
  257. Cython/Utility/Coroutine.c +2413 -0
  258. Cython/Utility/CpdefEnums.pyx +108 -0
  259. Cython/Utility/CppConvert.pyx +279 -0
  260. Cython/Utility/CppSupport.cpp +133 -0
  261. Cython/Utility/CythonFunction.c +1851 -0
  262. Cython/Utility/Dataclasses.c +185 -0
  263. Cython/Utility/Dataclasses.py +112 -0
  264. Cython/Utility/Embed.c +125 -0
  265. Cython/Utility/Exceptions.c +1017 -0
  266. Cython/Utility/ExtensionTypes.c +797 -0
  267. Cython/Utility/FunctionArguments.c +573 -0
  268. Cython/Utility/ImportExport.c +912 -0
  269. Cython/Utility/MemoryView.pyx +1478 -0
  270. Cython/Utility/MemoryView_C.c +992 -0
  271. Cython/Utility/ModuleSetupCode.c +2501 -0
  272. Cython/Utility/NumpyImportArray.c +46 -0
  273. Cython/Utility/ObjectHandling.c +3054 -0
  274. Cython/Utility/Optimize.c +1533 -0
  275. Cython/Utility/Overflow.c +404 -0
  276. Cython/Utility/Printing.c +86 -0
  277. Cython/Utility/Profile.c +660 -0
  278. Cython/Utility/StringTools.c +1206 -0
  279. Cython/Utility/TestCyUtilityLoader.pyx +8 -0
  280. Cython/Utility/TestCythonScope.pyx +75 -0
  281. Cython/Utility/TestUtilityLoader.c +12 -0
  282. Cython/Utility/TypeConversion.c +1329 -0
  283. Cython/Utility/UFuncs.pyx +50 -0
  284. Cython/Utility/UFuncs_C.c +89 -0
  285. Cython/Utility/__init__.py +28 -0
  286. Cython/Utility/arrayarray.h +143 -0
  287. Cython/Utils.py +687 -0
  288. Cython/__init__.py +10 -0
  289. Cython/__init__.pyi +7 -0
  290. Cython/py.typed +0 -0
  291. Cython-3.1.0a1.dist-info/COPYING.txt +19 -0
  292. Cython-3.1.0a1.dist-info/LICENSE.txt +176 -0
  293. Cython-3.1.0a1.dist-info/METADATA +67 -0
  294. Cython-3.1.0a1.dist-info/RECORD +301 -0
  295. Cython-3.1.0a1.dist-info/WHEEL +5 -0
  296. Cython-3.1.0a1.dist-info/entry_points.txt +4 -0
  297. Cython-3.1.0a1.dist-info/top_level.txt +3 -0
  298. cython.py +29 -0
  299. pyximport/__init__.py +4 -0
  300. pyximport/pyxbuild.py +160 -0
  301. pyximport/pyximport.py +482 -0
@@ -0,0 +1,797 @@
1
+ /////////////// FixUpExtensionType.proto ///////////////
2
+
3
+ #if CYTHON_USE_TYPE_SPECS
4
+ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); /*proto*/
5
+ #endif
6
+
7
+ /////////////// FixUpExtensionType ///////////////
8
+ //@requires:ModuleSetupCode.c::IncludeStructmemberH
9
+ //@requires:StringTools.c::IncludeStringH
10
+
11
+ #if CYTHON_USE_TYPE_SPECS
12
+ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) {
13
+ #if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API
14
+ CYTHON_UNUSED_VAR(spec);
15
+ CYTHON_UNUSED_VAR(type);
16
+ #else
17
+ // Set tp_weakreflist, tp_dictoffset, tp_vectorcalloffset
18
+ // Copied and adapted from https://bugs.python.org/issue38140
19
+ const PyType_Slot *slot = spec->slots;
20
+ while (slot && slot->slot && slot->slot != Py_tp_members)
21
+ slot++;
22
+ if (slot && slot->slot == Py_tp_members) {
23
+ int changed = 0;
24
+ #if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON)
25
+ const
26
+ #endif
27
+ PyMemberDef *memb = (PyMemberDef*) slot->pfunc;
28
+ while (memb && memb->name) {
29
+ if (memb->name[0] == '_' && memb->name[1] == '_') {
30
+ #if PY_VERSION_HEX < 0x030900b1
31
+ if (strcmp(memb->name, "__weaklistoffset__") == 0) {
32
+ // The PyMemberDef must be a Py_ssize_t and readonly.
33
+ assert(memb->type == T_PYSSIZET);
34
+ assert(memb->flags == READONLY);
35
+ type->tp_weaklistoffset = memb->offset;
36
+ // FIXME: is it even worth calling PyType_Modified() here?
37
+ changed = 1;
38
+ }
39
+ else if (strcmp(memb->name, "__dictoffset__") == 0) {
40
+ // The PyMemberDef must be a Py_ssize_t and readonly.
41
+ assert(memb->type == T_PYSSIZET);
42
+ assert(memb->flags == READONLY);
43
+ type->tp_dictoffset = memb->offset;
44
+ // FIXME: is it even worth calling PyType_Modified() here?
45
+ changed = 1;
46
+ }
47
+ #if CYTHON_METH_FASTCALL
48
+ else if (strcmp(memb->name, "__vectorcalloffset__") == 0) {
49
+ // The PyMemberDef must be a Py_ssize_t and readonly.
50
+ assert(memb->type == T_PYSSIZET);
51
+ assert(memb->flags == READONLY);
52
+ #if PY_VERSION_HEX >= 0x030800b4
53
+ type->tp_vectorcall_offset = memb->offset;
54
+ #else
55
+ type->tp_print = (printfunc) memb->offset;
56
+ #endif
57
+ // FIXME: is it even worth calling PyType_Modified() here?
58
+ changed = 1;
59
+ }
60
+ #endif
61
+ #else
62
+ if ((0));
63
+ #endif
64
+ #if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON
65
+ else if (strcmp(memb->name, "__module__") == 0) {
66
+ // PyType_FromSpec() in CPython <= 3.9b1 overwrites this field with a constant string.
67
+ // See https://bugs.python.org/issue40703
68
+ PyObject *descr;
69
+ // The PyMemberDef must be an object and normally readable, possibly writable.
70
+ assert(memb->type == T_OBJECT);
71
+ assert(memb->flags == 0 || memb->flags == READONLY);
72
+ descr = PyDescr_NewMember(type, memb);
73
+ if (unlikely(!descr))
74
+ return -1;
75
+ if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) {
76
+ Py_DECREF(descr);
77
+ return -1;
78
+ }
79
+ Py_DECREF(descr);
80
+ changed = 1;
81
+ }
82
+ #endif
83
+ }
84
+ memb++;
85
+ }
86
+ if (changed)
87
+ PyType_Modified(type);
88
+ }
89
+ #endif
90
+ return 0;
91
+ }
92
+ #endif
93
+
94
+
95
+ /////////////// ValidateBasesTuple.proto ///////////////
96
+
97
+ #if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS
98
+ static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases); /*proto*/
99
+ #endif
100
+
101
+ /////////////// ValidateBasesTuple ///////////////
102
+
103
+ #if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS
104
+ static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) {
105
+ // Loop over all bases (except the first) and check that those
106
+ // really are heap types. Otherwise, it would not be safe to
107
+ // subclass them.
108
+ //
109
+ // We also check tp_dictoffset: it is unsafe to inherit
110
+ // tp_dictoffset from a base class because the object structures
111
+ // would not be compatible. So, if our extension type doesn't set
112
+ // tp_dictoffset (i.e. there is no __dict__ attribute in the object
113
+ // structure), we need to check that none of the base classes sets
114
+ // it either.
115
+ Py_ssize_t i, n;
116
+ #if CYTHON_ASSUME_SAFE_SIZE
117
+ n = PyTuple_GET_SIZE(bases);
118
+ #else
119
+ n = PyTuple_Size(bases);
120
+ if (unlikely(n < 0)) return -1;
121
+ #endif
122
+ for (i = 1; i < n; i++) /* Skip first base */
123
+ {
124
+ PyTypeObject *b;
125
+ #if CYTHON_AVOID_BORROWED_REFS
126
+ PyObject *b0 = PySequence_GetItem(bases, i);
127
+ if (!b0) return -1;
128
+ #elif CYTHON_ASSUME_SAFE_MACROS
129
+ PyObject *b0 = PyTuple_GET_ITEM(bases, i);
130
+ #else
131
+ PyObject *b0 = PyTuple_GetItem(bases, i);
132
+ if (!b0) return -1;
133
+ #endif
134
+ b = (PyTypeObject*) b0;
135
+ if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE))
136
+ {
137
+ __Pyx_TypeName b_name = __Pyx_PyType_GetName(b);
138
+ PyErr_Format(PyExc_TypeError,
139
+ "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name);
140
+ __Pyx_DECREF_TypeName(b_name);
141
+ #if CYTHON_AVOID_BORROWED_REFS
142
+ Py_DECREF(b0);
143
+ #endif
144
+ return -1;
145
+ }
146
+ if (dictoffset == 0)
147
+ {
148
+ Py_ssize_t b_dictoffset = 0;
149
+ #if CYTHON_USE_TYPE_SLOTS
150
+ b_dictoffset = b->tp_dictoffset;
151
+ #else
152
+ PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__");
153
+ if (!py_b_dictoffset) goto dictoffset_return;
154
+ b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset);
155
+ Py_DECREF(py_b_dictoffset);
156
+ if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return;
157
+ #endif
158
+ if (b_dictoffset) {
159
+ {
160
+ __Pyx_TypeName b_name = __Pyx_PyType_GetName(b);
161
+ PyErr_Format(PyExc_TypeError,
162
+ "extension type '%.200s' has no __dict__ slot, "
163
+ "but base type '" __Pyx_FMT_TYPENAME "' has: "
164
+ "either add 'cdef dict __dict__' to the extension type "
165
+ "or add '__slots__ = [...]' to the base type",
166
+ type_name, b_name);
167
+ __Pyx_DECREF_TypeName(b_name);
168
+ }
169
+ #if !CYTHON_USE_TYPE_SLOTS
170
+ dictoffset_return:
171
+ #endif
172
+ #if CYTHON_AVOID_BORROWED_REFS
173
+ Py_DECREF(b0);
174
+ #endif
175
+ return -1;
176
+ }
177
+ }
178
+ #if CYTHON_AVOID_BORROWED_REFS
179
+ Py_DECREF(b0);
180
+ #endif
181
+ }
182
+ return 0;
183
+ }
184
+ #endif
185
+
186
+
187
+ /////////////// PyType_Ready.proto ///////////////
188
+
189
+ // unused when using type specs
190
+ CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t);/*proto*/
191
+
192
+ /////////////// PyType_Ready ///////////////
193
+ //@requires: ObjectHandling.c::PyObjectCallMethod0
194
+ //@requires: ValidateBasesTuple
195
+
196
+ // Wrapper around PyType_Ready() with some runtime checks and fixes
197
+ // to deal with multiple inheritance.
198
+ static int __Pyx_PyType_Ready(PyTypeObject *t) {
199
+
200
+ // FIXME: is this really suitable for CYTHON_COMPILING_IN_LIMITED_API?
201
+ #if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION)
202
+ // avoid C warning about unused helper function
203
+ (void)__Pyx_PyObject_CallMethod0;
204
+ #if CYTHON_USE_TYPE_SPECS
205
+ (void)__Pyx_validate_bases_tuple;
206
+ #endif
207
+
208
+ return PyType_Ready(t);
209
+
210
+ #else
211
+ int r;
212
+ PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*);
213
+ if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1))
214
+ return -1;
215
+
216
+ #if !defined(PYSTON_MAJOR_VERSION)
217
+ {
218
+ // Make sure GC does not pick up our non-heap type as heap type with this hack!
219
+ // For details, see https://github.com/cython/cython/issues/3603
220
+ int gc_was_enabled;
221
+ #if PY_VERSION_HEX >= 0x030A00b1
222
+ // finally added in Py3.10 :)
223
+ gc_was_enabled = PyGC_Disable();
224
+ (void)__Pyx_PyObject_CallMethod0;
225
+
226
+ #else
227
+ // Call gc.disable() as a backwards compatible fallback, but only if needed.
228
+ PyObject *ret, *py_status;
229
+ PyObject *gc = NULL;
230
+ #if (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400) && \
231
+ !CYTHON_COMPILING_IN_GRAAL
232
+ // https://foss.heptapod.net/pypy/pypy/-/issues/3385
233
+ gc = PyImport_GetModule(PYUNICODE("gc"));
234
+ #endif
235
+ if (unlikely(!gc)) gc = PyImport_Import(PYUNICODE("gc"));
236
+ if (unlikely(!gc)) return -1;
237
+ py_status = __Pyx_PyObject_CallMethod0(gc, PYUNICODE("isenabled"));
238
+ if (unlikely(!py_status)) {
239
+ Py_DECREF(gc);
240
+ return -1;
241
+ }
242
+ gc_was_enabled = __Pyx_PyObject_IsTrue(py_status);
243
+ Py_DECREF(py_status);
244
+ if (gc_was_enabled > 0) {
245
+ ret = __Pyx_PyObject_CallMethod0(gc, PYUNICODE("disable"));
246
+ if (unlikely(!ret)) {
247
+ Py_DECREF(gc);
248
+ return -1;
249
+ }
250
+ Py_DECREF(ret);
251
+ } else if (unlikely(gc_was_enabled == -1)) {
252
+ Py_DECREF(gc);
253
+ return -1;
254
+ }
255
+ #endif
256
+
257
+ // As of https://bugs.python.org/issue22079
258
+ // PyType_Ready enforces that all bases of a non-heap type are
259
+ // non-heap. We know that this is the case for the solid base but
260
+ // other bases are heap allocated and are kept alive through the
261
+ // tp_bases reference.
262
+ // Other than this check, the Py_TPFLAGS_HEAPTYPE flag is unused
263
+ // in PyType_Ready().
264
+ t->tp_flags |= Py_TPFLAGS_HEAPTYPE;
265
+ #if PY_VERSION_HEX >= 0x030A0000
266
+ // As of https://github.com/python/cpython/pull/25520
267
+ // PyType_Ready marks types as immutable if they are static types
268
+ // and requires the Py_TPFLAGS_IMMUTABLETYPE flag to mark types as
269
+ // immutable
270
+ // Manually set the Py_TPFLAGS_IMMUTABLETYPE flag, since the type
271
+ // is immutable
272
+ t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
273
+ #endif
274
+ #else
275
+ // avoid C warning about unused helper function
276
+ (void)__Pyx_PyObject_CallMethod0;
277
+ #endif
278
+
279
+ r = PyType_Ready(t);
280
+
281
+ #if !defined(PYSTON_MAJOR_VERSION)
282
+ t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE;
283
+
284
+ #if PY_VERSION_HEX >= 0x030A00b1
285
+ if (gc_was_enabled)
286
+ PyGC_Enable();
287
+ #else
288
+ if (gc_was_enabled) {
289
+ PyObject *tp, *v, *tb;
290
+ PyErr_Fetch(&tp, &v, &tb);
291
+ ret = __Pyx_PyObject_CallMethod0(gc, PYUNICODE("enable"));
292
+ if (likely(ret || r == -1)) {
293
+ Py_XDECREF(ret);
294
+ // do not overwrite exceptions raised by PyType_Ready() above
295
+ PyErr_Restore(tp, v, tb);
296
+ } else {
297
+ // PyType_Ready() succeeded, but gc.enable() failed.
298
+ Py_XDECREF(tp);
299
+ Py_XDECREF(v);
300
+ Py_XDECREF(tb);
301
+ r = -1;
302
+ }
303
+ }
304
+ Py_DECREF(gc);
305
+ #endif
306
+ }
307
+ #endif
308
+
309
+ return r;
310
+ #endif
311
+ }
312
+
313
+
314
+ /////////////// PyTrashcan.proto ///////////////
315
+
316
+ // These macros are taken from https://github.com/python/cpython/pull/11841
317
+ // Unlike the Py_TRASHCAN_SAFE_BEGIN/Py_TRASHCAN_SAFE_END macros, they
318
+ // allow dealing correctly with subclasses.
319
+
320
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03080000
321
+ // https://github.com/python/cpython/pull/11841 merged so Cython reimplementation
322
+ // is no longer necessary
323
+ #define __Pyx_TRASHCAN_BEGIN Py_TRASHCAN_BEGIN
324
+ #define __Pyx_TRASHCAN_END Py_TRASHCAN_END
325
+
326
+ #elif CYTHON_COMPILING_IN_CPYTHON
327
+
328
+ #define __Pyx_TRASHCAN_BEGIN_CONDITION(op, cond) \
329
+ do { \
330
+ PyThreadState *_tstate = NULL; \
331
+ // If "cond" is false, then _tstate remains NULL and the deallocator
332
+ // is run normally without involving the trashcan
333
+ if (cond) { \
334
+ _tstate = PyThreadState_GET(); \
335
+ if (_tstate->trash_delete_nesting >= PyTrash_UNWIND_LEVEL) { \
336
+ // Store the object (to be deallocated later) and jump past
337
+ // Py_TRASHCAN_END, skipping the body of the deallocator
338
+ _PyTrash_thread_deposit_object((PyObject*)(op)); \
339
+ break; \
340
+ } \
341
+ ++_tstate->trash_delete_nesting; \
342
+ }
343
+ // The body of the deallocator is here.
344
+ #define __Pyx_TRASHCAN_END \
345
+ if (_tstate) { \
346
+ --_tstate->trash_delete_nesting; \
347
+ if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \
348
+ _PyTrash_thread_destroy_chain(); \
349
+ } \
350
+ } while (0);
351
+
352
+ #define __Pyx_TRASHCAN_BEGIN(op, dealloc) __Pyx_TRASHCAN_BEGIN_CONDITION(op, \
353
+ __Pyx_PyObject_GetSlot(op, tp_dealloc, destructor) == (destructor)(dealloc))
354
+
355
+ #else
356
+ // The trashcan is a no-op on other Python implementations
357
+ // or old CPython versions
358
+ #define __Pyx_TRASHCAN_BEGIN(op, dealloc)
359
+ #define __Pyx_TRASHCAN_END
360
+ #endif
361
+
362
+ /////////////// CallNextTpDealloc.proto ///////////////
363
+
364
+ static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc);
365
+
366
+ /////////////// CallNextTpDealloc ///////////////
367
+
368
+ static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc) {
369
+ PyTypeObject* type = Py_TYPE(obj);
370
+ destructor tp_dealloc = NULL;
371
+ /* try to find the first parent type that has a different tp_dealloc() function */
372
+ while (type && __Pyx_PyType_GetSlot(type, tp_dealloc, destructor) != current_tp_dealloc)
373
+ type = __Pyx_PyType_GetSlot(type, tp_base, PyTypeObject*);
374
+ while (type && (tp_dealloc = __Pyx_PyType_GetSlot(type, tp_dealloc, destructor)) == current_tp_dealloc)
375
+ type = __Pyx_PyType_GetSlot(type, tp_base, PyTypeObject*);
376
+ if (type)
377
+ tp_dealloc(obj);
378
+ }
379
+
380
+ /////////////// CallNextTpTraverse.proto ///////////////
381
+
382
+ static int __Pyx_call_next_tp_traverse(PyObject* obj, visitproc v, void *a, traverseproc current_tp_traverse);
383
+
384
+ /////////////// CallNextTpTraverse ///////////////
385
+
386
+ static int __Pyx_call_next_tp_traverse(PyObject* obj, visitproc v, void *a, traverseproc current_tp_traverse) {
387
+ PyTypeObject* type = Py_TYPE(obj);
388
+ traverseproc tp_traverse = NULL;
389
+ /* try to find the first parent type that has a different tp_traverse() function */
390
+ while (type && __Pyx_PyType_GetSlot(type, tp_traverse, traverseproc) != current_tp_traverse)
391
+ type = __Pyx_PyType_GetSlot(type, tp_base, PyTypeObject*);
392
+ while (type && (tp_traverse = __Pyx_PyType_GetSlot(type, tp_traverse, traverseproc)) == current_tp_traverse)
393
+ type = __Pyx_PyType_GetSlot(type, tp_base, PyTypeObject*);
394
+ if (type && tp_traverse)
395
+ return tp_traverse(obj, v, a);
396
+ // FIXME: really ignore?
397
+ return 0;
398
+ }
399
+
400
+ /////////////// CallNextTpClear.proto ///////////////
401
+
402
+ static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_clear);
403
+
404
+ /////////////// CallNextTpClear ///////////////
405
+
406
+ static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_clear) {
407
+ PyTypeObject* type = Py_TYPE(obj);
408
+ inquiry tp_clear = NULL;
409
+ /* try to find the first parent type that has a different tp_clear() function */
410
+ while (type && __Pyx_PyType_GetSlot(type, tp_clear, inquiry) != current_tp_clear)
411
+ type = __Pyx_PyType_GetSlot(type, tp_base, PyTypeObject*);
412
+ while (type && (tp_clear = __Pyx_PyType_GetSlot(type, tp_clear, inquiry)) == current_tp_clear)
413
+ type = __Pyx_PyType_GetSlot(type, tp_base, PyTypeObject*);
414
+ if (type && tp_clear)
415
+ tp_clear(obj);
416
+ }
417
+
418
+
419
+ /////////////// SetupReduce.proto ///////////////
420
+
421
+ static int __Pyx_setup_reduce(PyObject* type_obj);
422
+
423
+ /////////////// SetupReduce ///////////////
424
+ //@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
425
+ //@requires: ObjectHandling.c::PyObjectGetAttrStr
426
+ //@requires: SetItemOnTypeDict
427
+ //@requires: DelItemOnTypeDict
428
+
429
+ static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) {
430
+ int ret;
431
+ PyObject *name_attr;
432
+
433
+ name_attr = __Pyx_PyObject_GetAttrStrNoError(meth, PYIDENT("__name__"));
434
+ if (likely(name_attr)) {
435
+ ret = PyObject_RichCompareBool(name_attr, name, Py_EQ);
436
+ } else {
437
+ ret = -1;
438
+ }
439
+
440
+ if (unlikely(ret < 0)) {
441
+ PyErr_Clear();
442
+ ret = 0;
443
+ }
444
+
445
+ Py_XDECREF(name_attr);
446
+ return ret;
447
+ }
448
+
449
+ static int __Pyx_setup_reduce(PyObject* type_obj) {
450
+ int ret = 0;
451
+ PyObject *object_reduce = NULL;
452
+ PyObject *object_getstate = NULL;
453
+ PyObject *object_reduce_ex = NULL;
454
+ PyObject *reduce = NULL;
455
+ PyObject *reduce_ex = NULL;
456
+ PyObject *reduce_cython = NULL;
457
+ PyObject *setstate = NULL;
458
+ PyObject *setstate_cython = NULL;
459
+ PyObject *getstate = NULL;
460
+
461
+ #if CYTHON_USE_PYTYPE_LOOKUP
462
+ getstate = _PyType_Lookup((PyTypeObject*)type_obj, PYIDENT("__getstate__"));
463
+ #else
464
+ getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, PYIDENT("__getstate__"));
465
+ if (!getstate && PyErr_Occurred()) {
466
+ goto __PYX_BAD;
467
+ }
468
+ #endif
469
+ if (getstate) {
470
+ // Python 3.11 introduces object.__getstate__. Because it's version-specific failure to find it should not be an error
471
+ #if CYTHON_USE_PYTYPE_LOOKUP
472
+ object_getstate = _PyType_Lookup(&PyBaseObject_Type, PYIDENT("__getstate__"));
473
+ #else
474
+ object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, PYIDENT("__getstate__"));
475
+ if (!object_getstate && PyErr_Occurred()) {
476
+ goto __PYX_BAD;
477
+ }
478
+ #endif
479
+ if (object_getstate != getstate) {
480
+ goto __PYX_GOOD;
481
+ }
482
+ }
483
+
484
+ #if CYTHON_USE_PYTYPE_LOOKUP
485
+ object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, PYIDENT("__reduce_ex__")); if (!object_reduce_ex) goto __PYX_BAD;
486
+ #else
487
+ object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, PYIDENT("__reduce_ex__")); if (!object_reduce_ex) goto __PYX_BAD;
488
+ #endif
489
+
490
+ reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce_ex__")); if (unlikely(!reduce_ex)) goto __PYX_BAD;
491
+ if (reduce_ex == object_reduce_ex) {
492
+
493
+ #if CYTHON_USE_PYTYPE_LOOKUP
494
+ object_reduce = _PyType_Lookup(&PyBaseObject_Type, PYIDENT("__reduce__")); if (!object_reduce) goto __PYX_BAD;
495
+ #else
496
+ object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, PYIDENT("__reduce__")); if (!object_reduce) goto __PYX_BAD;
497
+ #endif
498
+ reduce = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce__")); if (unlikely(!reduce)) goto __PYX_BAD;
499
+
500
+ if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, PYIDENT("__reduce_cython__"))) {
501
+ reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, PYIDENT("__reduce_cython__"));
502
+ if (likely(reduce_cython)) {
503
+ ret = __Pyx_SetItemOnTypeDict((PyTypeObject*)type_obj, PYIDENT("__reduce__"), reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
504
+ ret = __Pyx_DelItemOnTypeDict((PyTypeObject*)type_obj, PYIDENT("__reduce_cython__")); if (unlikely(ret < 0)) goto __PYX_BAD;
505
+ } else if (reduce == object_reduce || PyErr_Occurred()) {
506
+ // Ignore if we're done, i.e. if 'reduce' already has the right name and the original is gone.
507
+ // Otherwise: error.
508
+ goto __PYX_BAD;
509
+ }
510
+
511
+ setstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, PYIDENT("__setstate__"));
512
+ if (!setstate) PyErr_Clear();
513
+ if (!setstate || __Pyx_setup_reduce_is_named(setstate, PYIDENT("__setstate_cython__"))) {
514
+ setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, PYIDENT("__setstate_cython__"));
515
+ if (likely(setstate_cython)) {
516
+ ret = __Pyx_SetItemOnTypeDict((PyTypeObject*)type_obj, PYIDENT("__setstate__"), setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
517
+ ret = __Pyx_DelItemOnTypeDict((PyTypeObject*)type_obj, PYIDENT("__setstate_cython__")); if (unlikely(ret < 0)) goto __PYX_BAD;
518
+ } else if (!setstate || PyErr_Occurred()) {
519
+ // Ignore if we're done, i.e. if 'setstate' already has the right name and the original is gone.
520
+ // Otherwise: error.
521
+ goto __PYX_BAD;
522
+ }
523
+ }
524
+ PyType_Modified((PyTypeObject*)type_obj);
525
+ }
526
+ }
527
+ goto __PYX_GOOD;
528
+
529
+ __PYX_BAD:
530
+ if (!PyErr_Occurred()) {
531
+ __Pyx_TypeName type_obj_name =
532
+ __Pyx_PyType_GetName((PyTypeObject*)type_obj);
533
+ PyErr_Format(PyExc_RuntimeError,
534
+ "Unable to initialize pickling for " __Pyx_FMT_TYPENAME, type_obj_name);
535
+ __Pyx_DECREF_TypeName(type_obj_name);
536
+ }
537
+ ret = -1;
538
+ __PYX_GOOD:
539
+ #if !CYTHON_USE_PYTYPE_LOOKUP
540
+ Py_XDECREF(object_reduce);
541
+ Py_XDECREF(object_reduce_ex);
542
+ Py_XDECREF(object_getstate);
543
+ Py_XDECREF(getstate);
544
+ #endif
545
+ Py_XDECREF(reduce);
546
+ Py_XDECREF(reduce_ex);
547
+ Py_XDECREF(reduce_cython);
548
+ Py_XDECREF(setstate);
549
+ Py_XDECREF(setstate_cython);
550
+ return ret;
551
+ }
552
+
553
+
554
+ /////////////// BinopSlot ///////////////
555
+
556
+ static CYTHON_INLINE PyObject *{{func_name}}_maybe_call_slot(PyTypeObject* type, PyObject *left, PyObject *right {{extra_arg_decl}}) {
557
+ {{slot_type}} slot;
558
+ #if CYTHON_USE_TYPE_SLOTS
559
+ slot = type->tp_as_number ? type->tp_as_number->{{slot_name}} : NULL;
560
+ #else
561
+ slot = ({{slot_type}}) PyType_GetSlot(type, Py_{{slot_name}});
562
+ #endif
563
+ return slot ? slot(left, right {{extra_arg}}) : __Pyx_NewRef(Py_NotImplemented);
564
+ }
565
+
566
+ static PyObject *{{func_name}}(PyObject *left, PyObject *right {{extra_arg_decl}}) {
567
+ int maybe_self_is_left, maybe_self_is_right = 0;
568
+ maybe_self_is_left = Py_TYPE(left) == Py_TYPE(right)
569
+ #if CYTHON_USE_TYPE_SLOTS
570
+ || (Py_TYPE(left)->tp_as_number && Py_TYPE(left)->tp_as_number->{{slot_name}} == &{{func_name}})
571
+ #endif
572
+ || __Pyx_TypeCheck(left, {{type_cname}});
573
+
574
+ // Optimize for the common case where the left operation is defined (and successful).
575
+ {{if not overloads_left}}
576
+ maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right)
577
+ #if CYTHON_USE_TYPE_SLOTS
578
+ || (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}})
579
+ #endif
580
+ || __Pyx_TypeCheck(right, {{type_cname}});
581
+ {{endif}}
582
+
583
+ if (maybe_self_is_left) {
584
+ PyObject *res;
585
+
586
+ {{if overloads_right and not overloads_left}}
587
+ if (maybe_self_is_right) {
588
+ res = {{call_right}};
589
+ if (res != Py_NotImplemented) return res;
590
+ Py_DECREF(res);
591
+ // Don't bother calling it again.
592
+ maybe_self_is_right = 0;
593
+ }
594
+ {{endif}}
595
+
596
+ res = {{call_left}};
597
+ if (res != Py_NotImplemented) return res;
598
+ Py_DECREF(res);
599
+ }
600
+
601
+ {{if overloads_left}}
602
+ maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right)
603
+ #if CYTHON_USE_TYPE_SLOTS
604
+ || (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}})
605
+ #endif
606
+ || PyType_IsSubtype(Py_TYPE(right), {{type_cname}});
607
+ {{endif}}
608
+
609
+ if (maybe_self_is_right) {
610
+ return {{call_right}};
611
+ }
612
+ return __Pyx_NewRef(Py_NotImplemented);
613
+ }
614
+
615
+ /////////////// ValidateExternBase.proto ///////////////
616
+
617
+ static int __Pyx_validate_extern_base(PyTypeObject *base); /* proto */
618
+
619
+ /////////////// ValidateExternBase ///////////////
620
+ //@requires: ObjectHandling.c::FormatTypeName
621
+
622
+ static int __Pyx_validate_extern_base(PyTypeObject *base) {
623
+ Py_ssize_t itemsize;
624
+ #if CYTHON_COMPILING_IN_LIMITED_API
625
+ PyObject *py_itemsize;
626
+ #endif
627
+ #if !CYTHON_COMPILING_IN_LIMITED_API
628
+ itemsize = ((PyTypeObject *)base)->tp_itemsize;
629
+ #else
630
+ py_itemsize = PyObject_GetAttrString((PyObject*)base, "__itemsize__");
631
+ if (!py_itemsize)
632
+ return -1;
633
+ itemsize = PyLong_AsSsize_t(py_itemsize);
634
+ Py_DECREF(py_itemsize);
635
+ py_itemsize = 0;
636
+ if (itemsize == (Py_ssize_t)-1 && PyErr_Occurred())
637
+ return -1;
638
+ #endif
639
+ if (itemsize) {
640
+ __Pyx_TypeName b_name = __Pyx_PyType_GetName(base);
641
+ PyErr_Format(PyExc_TypeError,
642
+ "inheritance from PyVarObject types like '" __Pyx_FMT_TYPENAME "' not currently supported", b_name);
643
+ __Pyx_DECREF_TypeName(b_name);
644
+ return -1;
645
+ }
646
+ return 0;
647
+ }
648
+
649
+ /////////////// CallTypeTraverse.proto /////////////////////
650
+
651
+ #if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000)
652
+ // Without type specs, we're never responsible for this.
653
+ // If we *know* the Python version is less that 3.9 we're also not responsible
654
+ #define __Pyx_call_type_traverse(o, always_call, visit, arg) 0
655
+ #else
656
+ static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg); /* proto */
657
+ #endif
658
+
659
+ /////////////// CallTypeTraverse ////////////////////////////
660
+
661
+ #if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000)
662
+ // nothing to do
663
+ #else
664
+ static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg) {
665
+ #if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x03090000
666
+ // We have to work out whether to call traverse based on the runtime version.
667
+ // __Pyx_get_runtime_version is always available so no need to require it.
668
+ if (__Pyx_get_runtime_version() < 0x03090000) return 0;
669
+ #endif
670
+ if (!always_call) {
671
+ // Written with reference to https://docs.python.org/3/howto/isolating-extensions.html
672
+ PyTypeObject *base = __Pyx_PyObject_GetSlot(o, tp_base, PyTypeObject*);
673
+ unsigned long flags = PyType_GetFlags(base);
674
+ if (flags & Py_TPFLAGS_HEAPTYPE) {
675
+ // The base class should have handled it
676
+ return 0;
677
+ }
678
+ }
679
+ Py_VISIT((PyObject*)Py_TYPE(o));
680
+ return 0;
681
+ }
682
+ #endif
683
+
684
+
685
+ ////////////////// LimitedApiGetTypeDict.proto //////////////////////
686
+
687
+ #if CYTHON_COMPILING_IN_LIMITED_API
688
+ // This is a little hacky - the Limited API works quite hard to stop us getting
689
+ // the dict of a type object. But apparently not hard enough...
690
+ //
691
+ // In future we should prefer to work with mutable types, and then make them immutable
692
+ // once we're done (pending C API support for this).
693
+ static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp); /* proto */
694
+ #endif
695
+
696
+ ////////////////// LimitedApiGetTypeDict //////////////////////
697
+
698
+ #if CYTHON_COMPILING_IN_LIMITED_API
699
+ static Py_ssize_t __Pyx_GetTypeDictOffset(void) {
700
+ PyObject *tp_dictoffset_o;
701
+ Py_ssize_t tp_dictoffset;
702
+ tp_dictoffset_o = PyObject_GetAttrString((PyObject*)(&PyType_Type), "__dictoffset__");
703
+ if (unlikely(!tp_dictoffset_o)) return -1;
704
+ tp_dictoffset = PyLong_AsSsize_t(tp_dictoffset_o);
705
+ Py_DECREF(tp_dictoffset_o);
706
+
707
+ if (unlikely(tp_dictoffset == 0)) {
708
+ PyErr_SetString(
709
+ PyExc_TypeError,
710
+ "'type' doesn't have a dictoffset");
711
+ return -1;
712
+ } else if (unlikely(tp_dictoffset < 0)) {
713
+ // This isn't completely future proof. dictoffset can be
714
+ // negative, but isn't in Python <=3.13 (current at time
715
+ // of writing). It's awkward to calculate in the limited
716
+ // API because we need to know the object size. For now
717
+ // just raise an error and fix it if it every changes.
718
+ PyErr_SetString(
719
+ PyExc_TypeError,
720
+ "'type' has an unexpected negative dictoffset. "
721
+ "Please report this as Cython bug");
722
+ return -1;
723
+ }
724
+
725
+ return tp_dictoffset;
726
+ }
727
+
728
+ static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp) {
729
+ // TODO - if we ever support custom metatypes for extension types then
730
+ // we have to modify this caching.
731
+ static Py_ssize_t tp_dictoffset = 0;
732
+ if (unlikely(tp_dictoffset == 0)) {
733
+ tp_dictoffset = __Pyx_GetTypeDictOffset();
734
+ // Note that negative dictoffsets are definitely allowed.
735
+ // A dictoffset of -1 seems unlikely but isn't obviously forbidden.
736
+ if (unlikely(tp_dictoffset == -1 && PyErr_Occurred())) {
737
+ tp_dictoffset = 0; // try again next time?
738
+ return NULL;
739
+ }
740
+ }
741
+ return *(PyObject**)((char*)tp + tp_dictoffset);
742
+ }
743
+ #endif
744
+
745
+
746
+ ////////////////// SetItemOnTypeDict.proto //////////////////////////
747
+ //@requires: LimitedApiGetTypeDict
748
+
749
+ static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v); /* proto */
750
+
751
+ #define __Pyx_SetItemOnTypeDict(tp, k, v) __Pyx__SetItemOnTypeDict((PyTypeObject*)tp, k, v)
752
+
753
+ ////////////////// SetItemOnTypeDict //////////////////////////
754
+
755
+ static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v) {
756
+ int result;
757
+ PyObject *tp_dict;
758
+ #if CYTHON_COMPILING_IN_LIMITED_API
759
+ tp_dict = __Pyx_GetTypeDict(tp);
760
+ if (unlikely(!tp_dict)) return -1;
761
+ #else
762
+ tp_dict = tp->tp_dict;
763
+ #endif
764
+ result = PyDict_SetItem(tp_dict, k, v);
765
+ if (likely(!result)) {
766
+ PyType_Modified(tp);
767
+ if (unlikely(PyObject_HasAttr(v, PYIDENT("__set_name__")))) {
768
+ PyObject *setNameResult = PyObject_CallMethodObjArgs(v, PYIDENT("__set_name__"), (PyObject *) tp, k, NULL);
769
+ if (!setNameResult) return -1;
770
+ Py_DECREF(setNameResult);
771
+ }
772
+ }
773
+ return result;
774
+ }
775
+
776
+ ////////////////// DelItemOnTypeDict.proto //////////////////////////
777
+
778
+ static int __Pyx__DelItemOnTypeDict(PyTypeObject *tp, PyObject *k); /* proto */
779
+
780
+ #define __Pyx_DelItemOnTypeDict(tp, k) __Pyx__DelItemOnTypeDict((PyTypeObject*)tp, k)
781
+
782
+ ////////////////// DelItemOnTypeDict //////////////////////////
783
+ //@requires: LimitedApiGetTypeDict
784
+
785
+ static int __Pyx__DelItemOnTypeDict(PyTypeObject *tp, PyObject *k) {
786
+ int result;
787
+ PyObject *tp_dict;
788
+ #if CYTHON_COMPILING_IN_LIMITED_API
789
+ tp_dict = __Pyx_GetTypeDict(tp);
790
+ if (unlikely(!tp_dict)) return -1;
791
+ #else
792
+ tp_dict = tp->tp_dict;
793
+ #endif
794
+ result = PyDict_DelItem(tp_dict, k);
795
+ if (likely(!result)) PyType_Modified(tp);
796
+ return result;
797
+ }