Cython 3.3.0a1__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 (335) 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 +1276 -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 +84 -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 +815 -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 +680 -0
  23. Cython/Compiler/Builtin.py +997 -0
  24. Cython/Compiler/CmdLine.py +263 -0
  25. Cython/Compiler/Code.cp315-win_amd64.pyd +0 -0
  26. Cython/Compiler/Code.pxd +152 -0
  27. Cython/Compiler/Code.py +3907 -0
  28. Cython/Compiler/CodeGeneration.py +33 -0
  29. Cython/Compiler/CythonScope.py +194 -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 +15983 -0
  34. Cython/Compiler/FlowControl.cp315-win_amd64.pyd +0 -0
  35. Cython/Compiler/FlowControl.pxd +99 -0
  36. Cython/Compiler/FlowControl.py +1571 -0
  37. Cython/Compiler/FusedNode.cp315-win_amd64.pyd +0 -0
  38. Cython/Compiler/FusedNode.py +976 -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 +2197 -0
  46. Cython/Compiler/MemoryView.py +930 -0
  47. Cython/Compiler/ModuleNode.py +4517 -0
  48. Cython/Compiler/Naming.py +367 -0
  49. Cython/Compiler/Nodes.py +10941 -0
  50. Cython/Compiler/Optimize.py +5455 -0
  51. Cython/Compiler/Options.py +838 -0
  52. Cython/Compiler/ParseTreeTransforms.pxd +79 -0
  53. Cython/Compiler/ParseTreeTransforms.py +4744 -0
  54. Cython/Compiler/Parsing.cp315-win_amd64.pyd +0 -0
  55. Cython/Compiler/Parsing.pxd +9 -0
  56. Cython/Compiler/Parsing.py +4792 -0
  57. Cython/Compiler/Pipeline.py +439 -0
  58. Cython/Compiler/PyrexTypes.py +6111 -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.py +297 -0
  64. Cython/Compiler/Symtab.py +3092 -0
  65. Cython/Compiler/Tests/TestBuffer.py +105 -0
  66. Cython/Compiler/Tests/TestBuiltin.py +117 -0
  67. Cython/Compiler/Tests/TestCmdLine.py +587 -0
  68. Cython/Compiler/Tests/TestCode.py +145 -0
  69. Cython/Compiler/Tests/TestFlowControl.py +65 -0
  70. Cython/Compiler/Tests/TestGrammar.py +202 -0
  71. Cython/Compiler/Tests/TestMemView.py +71 -0
  72. Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
  73. Cython/Compiler/Tests/TestScanning.py +132 -0
  74. Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
  75. Cython/Compiler/Tests/TestStringEncoding.py +20 -0
  76. Cython/Compiler/Tests/TestTreeFragment.py +63 -0
  77. Cython/Compiler/Tests/TestTreePath.py +103 -0
  78. Cython/Compiler/Tests/TestTypes.py +118 -0
  79. Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
  80. Cython/Compiler/Tests/TestVisitor.py +61 -0
  81. Cython/Compiler/Tests/Utils.py +36 -0
  82. Cython/Compiler/Tests/__init__.py +1 -0
  83. Cython/Compiler/TreeFragment.py +278 -0
  84. Cython/Compiler/TreePath.py +303 -0
  85. Cython/Compiler/TypeInference.py +611 -0
  86. Cython/Compiler/TypeSlots.py +1329 -0
  87. Cython/Compiler/UFuncs.py +311 -0
  88. Cython/Compiler/UtilNodes.py +413 -0
  89. Cython/Compiler/UtilityCode.py +348 -0
  90. Cython/Compiler/Version.py +8 -0
  91. Cython/Compiler/Visitor.cp315-win_amd64.pyd +0 -0
  92. Cython/Compiler/Visitor.pxd +53 -0
  93. Cython/Compiler/Visitor.py +864 -0
  94. Cython/Compiler/__init__.py +1 -0
  95. Cython/Coverage.py +448 -0
  96. Cython/Debugger/Cygdb.py +177 -0
  97. Cython/Debugger/DebugWriter.py +82 -0
  98. Cython/Debugger/Tests/TestLibCython.py +280 -0
  99. Cython/Debugger/Tests/__init__.py +1 -0
  100. Cython/Debugger/Tests/cfuncs.c +8 -0
  101. Cython/Debugger/Tests/codefile +49 -0
  102. Cython/Debugger/Tests/test_libcython_in_gdb.py +580 -0
  103. Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
  104. Cython/Debugger/__init__.py +1 -0
  105. Cython/Debugger/libcython.py +1548 -0
  106. Cython/Debugger/libpython.py +2821 -0
  107. Cython/Debugging.py +20 -0
  108. Cython/Distutils/__init__.py +2 -0
  109. Cython/Distutils/build_ext.py +139 -0
  110. Cython/Distutils/extension.py +96 -0
  111. Cython/Distutils/old_build_ext.py +351 -0
  112. Cython/Includes/cpython/__init__.pxd +173 -0
  113. Cython/Includes/cpython/array.pxd +152 -0
  114. Cython/Includes/cpython/bool.pxd +37 -0
  115. Cython/Includes/cpython/buffer.pxd +112 -0
  116. Cython/Includes/cpython/bytearray.pxd +33 -0
  117. Cython/Includes/cpython/bytes.pxd +200 -0
  118. Cython/Includes/cpython/cellobject.pxd +35 -0
  119. Cython/Includes/cpython/ceval.pxd +8 -0
  120. Cython/Includes/cpython/codecs.pxd +121 -0
  121. Cython/Includes/cpython/complex.pxd +60 -0
  122. Cython/Includes/cpython/contextvars.pxd +145 -0
  123. Cython/Includes/cpython/conversion.pxd +36 -0
  124. Cython/Includes/cpython/datetime.pxd +395 -0
  125. Cython/Includes/cpython/descr.pxd +26 -0
  126. Cython/Includes/cpython/dict.pxd +268 -0
  127. Cython/Includes/cpython/exc.pxd +263 -0
  128. Cython/Includes/cpython/fileobject.pxd +57 -0
  129. Cython/Includes/cpython/float.pxd +56 -0
  130. Cython/Includes/cpython/frozendict.pxd +37 -0
  131. Cython/Includes/cpython/function.pxd +65 -0
  132. Cython/Includes/cpython/genobject.pxd +25 -0
  133. Cython/Includes/cpython/getargs.pxd +12 -0
  134. Cython/Includes/cpython/instance.pxd +25 -0
  135. Cython/Includes/cpython/iterator.pxd +36 -0
  136. Cython/Includes/cpython/iterobject.pxd +24 -0
  137. Cython/Includes/cpython/list.pxd +144 -0
  138. Cython/Includes/cpython/long.pxd +180 -0
  139. Cython/Includes/cpython/longintrepr.pxd +14 -0
  140. Cython/Includes/cpython/mapping.pxd +63 -0
  141. Cython/Includes/cpython/marshal.pxd +66 -0
  142. Cython/Includes/cpython/mem.pxd +120 -0
  143. Cython/Includes/cpython/memoryview.pxd +50 -0
  144. Cython/Includes/cpython/method.pxd +49 -0
  145. Cython/Includes/cpython/module.pxd +208 -0
  146. Cython/Includes/cpython/number.pxd +258 -0
  147. Cython/Includes/cpython/object.pxd +430 -0
  148. Cython/Includes/cpython/pycapsule.pxd +143 -0
  149. Cython/Includes/cpython/pylifecycle.pxd +68 -0
  150. Cython/Includes/cpython/pyport.pxd +8 -0
  151. Cython/Includes/cpython/pystate.pxd +95 -0
  152. Cython/Includes/cpython/pythread.pxd +53 -0
  153. Cython/Includes/cpython/ref.pxd +141 -0
  154. Cython/Includes/cpython/sentinel.pxd +17 -0
  155. Cython/Includes/cpython/sequence.pxd +134 -0
  156. Cython/Includes/cpython/set.pxd +119 -0
  157. Cython/Includes/cpython/slice.pxd +70 -0
  158. Cython/Includes/cpython/time.pxd +129 -0
  159. Cython/Includes/cpython/tuple.pxd +72 -0
  160. Cython/Includes/cpython/type.pxd +146 -0
  161. Cython/Includes/cpython/unicode.pxd +639 -0
  162. Cython/Includes/cpython/version.pxd +32 -0
  163. Cython/Includes/cpython/weakref.pxd +78 -0
  164. Cython/Includes/libc/__init__.pxd +1 -0
  165. Cython/Includes/libc/complex.pxd +35 -0
  166. Cython/Includes/libc/errno.pxd +127 -0
  167. Cython/Includes/libc/float.pxd +43 -0
  168. Cython/Includes/libc/limits.pxd +28 -0
  169. Cython/Includes/libc/locale.pxd +46 -0
  170. Cython/Includes/libc/math.pxd +209 -0
  171. Cython/Includes/libc/setjmp.pxd +10 -0
  172. Cython/Includes/libc/signal.pxd +64 -0
  173. Cython/Includes/libc/stddef.pxd +9 -0
  174. Cython/Includes/libc/stdint.pxd +105 -0
  175. Cython/Includes/libc/stdio.pxd +80 -0
  176. Cython/Includes/libc/stdlib.pxd +72 -0
  177. Cython/Includes/libc/string.pxd +50 -0
  178. Cython/Includes/libc/threads.pxd +234 -0
  179. Cython/Includes/libc/time.pxd +52 -0
  180. Cython/Includes/libcpp/__init__.pxd +4 -0
  181. Cython/Includes/libcpp/algorithm.pxd +320 -0
  182. Cython/Includes/libcpp/any.pxd +16 -0
  183. Cython/Includes/libcpp/atomic.pxd +59 -0
  184. Cython/Includes/libcpp/barrier.pxd +22 -0
  185. Cython/Includes/libcpp/bit.pxd +29 -0
  186. Cython/Includes/libcpp/cast.pxd +12 -0
  187. Cython/Includes/libcpp/cmath.pxd +518 -0
  188. Cython/Includes/libcpp/complex.pxd +106 -0
  189. Cython/Includes/libcpp/condition_variable.pxd +322 -0
  190. Cython/Includes/libcpp/deque.pxd +165 -0
  191. Cython/Includes/libcpp/exception.pxd +216 -0
  192. Cython/Includes/libcpp/execution.pxd +15 -0
  193. Cython/Includes/libcpp/forward_list.pxd +63 -0
  194. Cython/Includes/libcpp/functional.pxd +26 -0
  195. Cython/Includes/libcpp/future.pxd +103 -0
  196. Cython/Includes/libcpp/iterator.pxd +34 -0
  197. Cython/Includes/libcpp/latch.pxd +17 -0
  198. Cython/Includes/libcpp/limits.pxd +61 -0
  199. Cython/Includes/libcpp/list.pxd +117 -0
  200. Cython/Includes/libcpp/map.pxd +252 -0
  201. Cython/Includes/libcpp/memory.pxd +115 -0
  202. Cython/Includes/libcpp/mutex.pxd +387 -0
  203. Cython/Includes/libcpp/numbers.pxd +15 -0
  204. Cython/Includes/libcpp/numeric.pxd +131 -0
  205. Cython/Includes/libcpp/optional.pxd +34 -0
  206. Cython/Includes/libcpp/pair.pxd +1 -0
  207. Cython/Includes/libcpp/queue.pxd +25 -0
  208. Cython/Includes/libcpp/random.pxd +166 -0
  209. Cython/Includes/libcpp/semaphore.pxd +43 -0
  210. Cython/Includes/libcpp/set.pxd +228 -0
  211. Cython/Includes/libcpp/shared_mutex.pxd +96 -0
  212. Cython/Includes/libcpp/span.pxd +87 -0
  213. Cython/Includes/libcpp/stack.pxd +11 -0
  214. Cython/Includes/libcpp/stop_token.pxd +117 -0
  215. Cython/Includes/libcpp/string.pxd +355 -0
  216. Cython/Includes/libcpp/string_view.pxd +183 -0
  217. Cython/Includes/libcpp/typeindex.pxd +15 -0
  218. Cython/Includes/libcpp/typeinfo.pxd +10 -0
  219. Cython/Includes/libcpp/unordered_map.pxd +193 -0
  220. Cython/Includes/libcpp/unordered_set.pxd +152 -0
  221. Cython/Includes/libcpp/utility.pxd +30 -0
  222. Cython/Includes/libcpp/vector.pxd +186 -0
  223. Cython/Includes/numpy/math.pxd +150 -0
  224. Cython/Includes/openmp.pxd +50 -0
  225. Cython/Includes/posix/__init__.pxd +1 -0
  226. Cython/Includes/posix/dlfcn.pxd +14 -0
  227. Cython/Includes/posix/fcntl.pxd +86 -0
  228. Cython/Includes/posix/ioctl.pxd +4 -0
  229. Cython/Includes/posix/mman.pxd +101 -0
  230. Cython/Includes/posix/resource.pxd +57 -0
  231. Cython/Includes/posix/select.pxd +21 -0
  232. Cython/Includes/posix/signal.pxd +73 -0
  233. Cython/Includes/posix/stat.pxd +98 -0
  234. Cython/Includes/posix/stdio.pxd +37 -0
  235. Cython/Includes/posix/stdlib.pxd +29 -0
  236. Cython/Includes/posix/strings.pxd +9 -0
  237. Cython/Includes/posix/time.pxd +71 -0
  238. Cython/Includes/posix/types.pxd +30 -0
  239. Cython/Includes/posix/uio.pxd +26 -0
  240. Cython/Includes/posix/unistd.pxd +271 -0
  241. Cython/Includes/posix/wait.pxd +38 -0
  242. Cython/LZSS.py +170 -0
  243. Cython/Plex/Actions.cp315-win_amd64.pyd +0 -0
  244. Cython/Plex/Actions.pxd +24 -0
  245. Cython/Plex/Actions.py +119 -0
  246. Cython/Plex/DFA.cp315-win_amd64.pyd +0 -0
  247. Cython/Plex/DFA.pxd +14 -0
  248. Cython/Plex/DFA.py +164 -0
  249. Cython/Plex/Errors.py +48 -0
  250. Cython/Plex/Lexicons.py +178 -0
  251. Cython/Plex/Machines.cp315-win_amd64.pyd +0 -0
  252. Cython/Plex/Machines.pxd +36 -0
  253. Cython/Plex/Machines.py +238 -0
  254. Cython/Plex/Regexps.py +535 -0
  255. Cython/Plex/Scanners.cp315-win_amd64.pyd +0 -0
  256. Cython/Plex/Scanners.pxd +45 -0
  257. Cython/Plex/Scanners.py +328 -0
  258. Cython/Plex/Transitions.cp315-win_amd64.pyd +0 -0
  259. Cython/Plex/Transitions.pxd +14 -0
  260. Cython/Plex/Transitions.py +239 -0
  261. Cython/Plex/__init__.py +34 -0
  262. Cython/Runtime/__init__.py +1 -0
  263. Cython/Runtime/refnanny.cp315-win_amd64.pyd +0 -0
  264. Cython/Runtime/refnanny.pyx +237 -0
  265. Cython/Shadow.py +1167 -0
  266. Cython/StringIOTree.cp315-win_amd64.pyd +0 -0
  267. Cython/StringIOTree.py +169 -0
  268. Cython/Tempita/__init__.py +4 -0
  269. Cython/Tempita/_looper.py +154 -0
  270. Cython/Tempita/_tempita.cp315-win_amd64.pyd +0 -0
  271. Cython/Tempita/_tempita.py +1087 -0
  272. Cython/TestUtils.py +464 -0
  273. Cython/Tests/TestCodeWriter.py +128 -0
  274. Cython/Tests/TestCythonUtils.py +202 -0
  275. Cython/Tests/TestJediTyper.py +223 -0
  276. Cython/Tests/TestShadow.py +110 -0
  277. Cython/Tests/TestStringIOTree.py +68 -0
  278. Cython/Tests/TestTestUtils.py +89 -0
  279. Cython/Tests/__init__.py +1 -0
  280. Cython/Tests/xmlrunner.py +390 -0
  281. Cython/Utility/AsyncGen.c +1073 -0
  282. Cython/Utility/Buffer.c +866 -0
  283. Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
  284. Cython/Utility/Builtins.c +933 -0
  285. Cython/Utility/CConvert.pyx +149 -0
  286. Cython/Utility/CMath.c +104 -0
  287. Cython/Utility/CommonStructures.c +244 -0
  288. Cython/Utility/Complex.c +378 -0
  289. Cython/Utility/Coroutine.c +2337 -0
  290. Cython/Utility/CpdefEnums.pyx +107 -0
  291. Cython/Utility/CppConvert.pyx +282 -0
  292. Cython/Utility/CppSupport.cpp +151 -0
  293. Cython/Utility/CythonFunction.c +2072 -0
  294. Cython/Utility/Dataclasses.c +101 -0
  295. Cython/Utility/Embed.c +129 -0
  296. Cython/Utility/Exceptions.c +1038 -0
  297. Cython/Utility/ExtensionTypes.c +1158 -0
  298. Cython/Utility/FunctionArguments.c +1045 -0
  299. Cython/Utility/FusedFunction.pyx +44 -0
  300. Cython/Utility/ImportExport.c +930 -0
  301. Cython/Utility/MatchCase.c +979 -0
  302. Cython/Utility/MatchCase_Cy.pyx +12 -0
  303. Cython/Utility/MemoryView.pxd +108 -0
  304. Cython/Utility/MemoryView.pyx +1499 -0
  305. Cython/Utility/MemoryView_C.c +1056 -0
  306. Cython/Utility/ModuleSetupCode.c +3352 -0
  307. Cython/Utility/NumpyImportArray.c +46 -0
  308. Cython/Utility/ObjectHandling.c +3372 -0
  309. Cython/Utility/Optimize.c +2563 -0
  310. Cython/Utility/Overflow.c +378 -0
  311. Cython/Utility/Profile.c +736 -0
  312. Cython/Utility/StringTools.c +1414 -0
  313. Cython/Utility/Synchronization.c +438 -0
  314. Cython/Utility/TString.c +369 -0
  315. Cython/Utility/TestCyUtilityLoader.pyx +8 -0
  316. Cython/Utility/TestCythonScope.pyx +75 -0
  317. Cython/Utility/TestUtilityLoader.c +12 -0
  318. Cython/Utility/TypeConversion.c +1556 -0
  319. Cython/Utility/UFuncs.pyx +50 -0
  320. Cython/Utility/UFuncs_C.c +89 -0
  321. Cython/Utility/__init__.py +28 -0
  322. Cython/Utility/arrayarray.h +172 -0
  323. Cython/Utils.cp315-win_amd64.pyd +0 -0
  324. Cython/Utils.py +677 -0
  325. Cython/__init__.py +12 -0
  326. Cython/py.typed +0 -0
  327. cython-3.3.0a1.dist-info/METADATA +394 -0
  328. cython-3.3.0a1.dist-info/RECORD +335 -0
  329. cython-3.3.0a1.dist-info/WHEEL +5 -0
  330. cython-3.3.0a1.dist-info/entry_points.txt +4 -0
  331. cython-3.3.0a1.dist-info/top_level.txt +3 -0
  332. cython.py +29 -0
  333. pyximport/__init__.py +4 -0
  334. pyximport/pyxbuild.py +160 -0
  335. pyximport/pyximport.py +482 -0
@@ -0,0 +1,2563 @@
1
+ /*
2
+ * Optional optimisations of built-in functions and methods.
3
+ *
4
+ * Required replacements of builtins are in Builtins.c.
5
+ *
6
+ * General object operations and protocols are in ObjectHandling.c.
7
+ */
8
+
9
+ /////////////// append.proto ///////////////
10
+
11
+ static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x); /*proto*/
12
+
13
+ /////////////// append ///////////////
14
+ //@requires: ListAppend
15
+ //@requires: ObjectHandling.c::PyObjectCallMethod1
16
+
17
+ static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
18
+ if (likely(PyList_CheckExact(L))) {
19
+ if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1;
20
+ } else {
21
+ PyObject* retval = __Pyx_PyObject_CallMethod1(L, PYIDENT("append"), x);
22
+ if (unlikely(!retval))
23
+ return -1;
24
+ Py_DECREF(retval);
25
+ }
26
+ return 0;
27
+ }
28
+
29
+
30
+ /////////////// ListAppendAndDecrefInternal ///////////////
31
+
32
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
33
+ static CYTHON_INLINE void __Pyx__ListComp_AppendAndDecref(PyObject* list, Py_ssize_t len, PyObject* x) {
34
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000
35
+ // In Py3.13a1, PyList_SET_ITEM() checks that the end index is lower than the current size.
36
+ // However, extending the size *before* setting the value would not be correct,
37
+ // so we cannot call PyList_SET_ITEM().
38
+ PyListObject* L = (PyListObject*) list;
39
+ L->ob_item[len] = x;
40
+ #else
41
+ PyList_SET_ITEM(list, len, x);
42
+ #endif
43
+ Py_SET_SIZE(list, len + 1);
44
+ }
45
+ #endif
46
+
47
+
48
+ /////////////// ListAppend.proto ///////////////
49
+
50
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
51
+ static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x); /*proto*/
52
+ #else
53
+ #define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
54
+ #endif
55
+
56
+ /////////////// ListAppend ///////////////
57
+ //@requires: ListAppendAndDecrefInternal
58
+
59
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
60
+ static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
61
+ PyListObject* L = (PyListObject*) list;
62
+ Py_ssize_t len = Py_SIZE(list);
63
+
64
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
65
+ Py_INCREF(x);
66
+ __Pyx__ListComp_AppendAndDecref(list, len, x);
67
+ return 0;
68
+ }
69
+ return PyList_Append(list, x);
70
+ }
71
+ #endif
72
+
73
+
74
+ /////////////// ListCompAppend.proto ///////////////
75
+
76
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
77
+ static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x); /*proto*/
78
+ #else
79
+ #define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
80
+ #endif
81
+
82
+ /////////////// ListCompAppend ///////////////
83
+ //@requires: ListAppendAndDecrefInternal
84
+
85
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
86
+ static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
87
+ PyListObject* L = (PyListObject*) list;
88
+ Py_ssize_t len = Py_SIZE(list);
89
+
90
+ if (likely(L->allocated > len)) {
91
+ Py_INCREF(x);
92
+ __Pyx__ListComp_AppendAndDecref(list, len, x);
93
+ return 0;
94
+ }
95
+ return PyList_Append(list, x);
96
+ }
97
+ #endif
98
+
99
+
100
+ /////////////// ListCompAppendAndDecref.proto ///////////////
101
+
102
+ static CYTHON_INLINE int __Pyx_ListComp_AppendAndDecref(PyObject* list, PyObject* x); /*proto*/
103
+
104
+ /////////////// ListCompAppendAndDecref ///////////////
105
+ //@requires: ListAppendAndDecrefInternal
106
+
107
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
108
+ static CYTHON_INLINE int __Pyx_ListComp_AppendAndDecref(PyObject* list, PyObject* x) {
109
+ PyListObject* L = (PyListObject*) list;
110
+ Py_ssize_t len = Py_SIZE(list);
111
+
112
+ if (likely(L->allocated > len)) {
113
+ __Pyx__ListComp_AppendAndDecref(list, len, x);
114
+ return 0;
115
+ }
116
+
117
+ int result = PyList_Append(list, x);
118
+ Py_DECREF(x);
119
+ return result;
120
+ }
121
+
122
+ #else
123
+ static CYTHON_INLINE int __Pyx_ListComp_AppendAndDecref(PyObject* list, PyObject* x) {
124
+ int result = PyList_Append(list, x);
125
+ Py_DECREF(x);
126
+ return result;
127
+ }
128
+ #endif
129
+
130
+
131
+ //////////////////// ListExtend.proto ////////////////////
132
+
133
+ static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
134
+ #if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00a2
135
+ return PyList_Extend(L, v);
136
+ #elif CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000
137
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
138
+ if (unlikely(!none))
139
+ return -1;
140
+ Py_DECREF(none);
141
+ return 0;
142
+ #else
143
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
144
+ #endif
145
+ }
146
+
147
+ /////////////// pop.proto ///////////////
148
+
149
+ static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L); /*proto*/
150
+
151
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
152
+ static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L); /*proto*/
153
+ #define __Pyx_PyObject_Pop(L) (likely(PyList_CheckExact(L)) ? \
154
+ __Pyx_PyList_Pop(L) : __Pyx__PyObject_Pop(L))
155
+
156
+ #else
157
+ #define __Pyx_PyList_Pop(L) __Pyx__PyObject_Pop(L)
158
+ #define __Pyx_PyObject_Pop(L) __Pyx__PyObject_Pop(L)
159
+ #endif
160
+
161
+ /////////////// pop ///////////////
162
+ //@requires: ObjectHandling.c::PyObjectCallMethod0
163
+
164
+ static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) {
165
+ if (Py_IS_TYPE(L, &PySet_Type)) {
166
+ return PySet_Pop(L);
167
+ }
168
+ return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop"));
169
+ }
170
+
171
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
172
+ static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L) {
173
+ /* Check that both the size is positive and no reallocation shrinking needs to be done. */
174
+ if (likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) {
175
+ Py_SET_SIZE(L, Py_SIZE(L) - 1);
176
+ return PyList_GET_ITEM(L, PyList_GET_SIZE(L));
177
+ }
178
+ return CALL_UNBOUND_METHOD(PyList_Type, "pop", L);
179
+ }
180
+ #endif
181
+
182
+
183
+ /////////////// pop_index.proto ///////////////
184
+
185
+ static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix); /*proto*/
186
+ static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix); /*proto*/
187
+
188
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
189
+ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix); /*proto*/
190
+
191
+ #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
192
+ (likely(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed))) ? \
193
+ __Pyx__PyList_PopIndex(L, py_ix, ix) : ( \
194
+ (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
195
+ __Pyx__PyObject_PopIndex(L, py_ix)))
196
+
197
+ #define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
198
+ __Pyx_fits_Py_ssize_t(ix, type, is_signed) ? \
199
+ __Pyx__PyList_PopIndex(L, py_ix, ix) : ( \
200
+ (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
201
+ __Pyx__PyObject_PopIndex(L, py_ix)))
202
+
203
+ #else
204
+
205
+ #define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) \
206
+ __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func)
207
+
208
+ #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \
209
+ (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \
210
+ __Pyx__PyObject_PopIndex(L, py_ix))
211
+ #endif
212
+
213
+ /////////////// pop_index ///////////////
214
+ //@requires: ObjectHandling.c::PyObjectCallMethod1
215
+
216
+ static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix) {
217
+ PyObject *r;
218
+ if (unlikely(!py_ix)) return NULL;
219
+ r = __Pyx__PyObject_PopIndex(L, py_ix);
220
+ Py_DECREF(py_ix);
221
+ return r;
222
+ }
223
+
224
+ static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix) {
225
+ return __Pyx_PyObject_CallMethod1(L, PYIDENT("pop"), py_ix);
226
+ }
227
+
228
+ #if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
229
+ static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix) {
230
+ Py_ssize_t size = PyList_GET_SIZE(L);
231
+ if (likely(size > (((PyListObject*)L)->allocated >> 1))) {
232
+ Py_ssize_t cix = ix;
233
+ if (cix < 0) {
234
+ cix += size;
235
+ }
236
+ if (likely(__Pyx_is_valid_index(cix, size))) {
237
+ PyObject* v = PyList_GET_ITEM(L, cix);
238
+ Py_SET_SIZE(L, Py_SIZE(L) - 1);
239
+ size -= 1;
240
+ memmove(&PyList_GET_ITEM(L, cix), &PyList_GET_ITEM(L, cix+1), (size_t)(size-cix)*sizeof(PyObject*));
241
+ return v;
242
+ }
243
+ }
244
+ if (py_ix == Py_None) {
245
+ return __Pyx__PyObject_PopNewIndex(L, PyLong_FromSsize_t(ix));
246
+ } else {
247
+ return __Pyx__PyObject_PopIndex(L, py_ix);
248
+ }
249
+ }
250
+ #endif
251
+
252
+
253
+ /////////////// dict_getitem_default.proto ///////////////
254
+
255
+ static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value); /*proto*/
256
+
257
+ /////////////// dict_getitem_default ///////////////
258
+
259
+ static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value) {
260
+ PyObject* value;
261
+ #if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000
262
+ value = PyDict_GetItemWithError(d, key);
263
+ if (unlikely(!value)) {
264
+ if (unlikely(PyErr_Occurred()))
265
+ return NULL;
266
+ value = default_value;
267
+ }
268
+ Py_INCREF(value);
269
+ // avoid C compiler warning about unused utility functions
270
+ if ((1));
271
+ #else
272
+ if (PyBytes_CheckExact(key) || PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) {
273
+ /* these presumably have safe hash functions */
274
+ value = PyDict_GetItem(d, key);
275
+ if (unlikely(!value)) {
276
+ value = default_value;
277
+ }
278
+ Py_INCREF(value);
279
+ }
280
+ #endif
281
+ else {
282
+ if (default_value == Py_None)
283
+ value = CALL_UNBOUND_METHOD(PyDict_Type, "get", d, key);
284
+ else
285
+ value = CALL_UNBOUND_METHOD(PyDict_Type, "get", d, key, default_value);
286
+ }
287
+ return value;
288
+ }
289
+
290
+
291
+ /////////////// py_dict_clear.proto ///////////////
292
+
293
+ #define __Pyx_PyDict_Clear(d) (PyDict_Clear(d), 0)
294
+
295
+
296
+ /////////////// py_dict_pop.proto ///////////////
297
+
298
+ static CYTHON_INLINE PyObject *__Pyx_PyDict_Pop(PyObject *d, PyObject *key, PyObject *default_value); /*proto*/
299
+
300
+ /////////////// py_dict_pop ///////////////
301
+
302
+ static CYTHON_INLINE PyObject *__Pyx_PyDict_Pop(PyObject *d, PyObject *key, PyObject *default_value) {
303
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d00A2 || defined(PyDict_Pop)
304
+ PyObject *value;
305
+ if (PyDict_Pop(d, key, &value) == 0) {
306
+ if (default_value) {
307
+ Py_INCREF(default_value);
308
+ } else {
309
+ PyErr_SetObject(PyExc_KeyError, key);
310
+ }
311
+ value = default_value;
312
+ }
313
+ // On error, PyDict_Pop() returns -1 and sets value to NULL (our own exception return value).
314
+ return value;
315
+ #elif CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000
316
+ return _PyDict_Pop(d, key, default_value);
317
+ #else
318
+ if (default_value) {
319
+ return CALL_UNBOUND_METHOD(PyDict_Type, "pop", d, key, default_value);
320
+ } else {
321
+ return CALL_UNBOUND_METHOD(PyDict_Type, "pop", d, key);
322
+ }
323
+ #endif
324
+ }
325
+
326
+
327
+ /////////////// py_dict_pop_ignore.proto ///////////////
328
+
329
+ static CYTHON_INLINE int __Pyx_PyDict_Pop_ignore(PyObject *d, PyObject *key, PyObject *default_value); /*proto*/
330
+
331
+ /////////////// py_dict_pop_ignore ///////////////
332
+
333
+ static CYTHON_INLINE int __Pyx_PyDict_Pop_ignore(PyObject *d, PyObject *key, PyObject *default_value) {
334
+ // We take the "default_value" as argument to avoid "unused" warnings, but we ignore it here.
335
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d00A2 || defined(PyDict_Pop)
336
+ int result = PyDict_Pop(d, key, NULL);
337
+ CYTHON_UNUSED_VAR(default_value);
338
+ return (unlikely(result == -1)) ? -1 : 0;
339
+ #else
340
+ PyObject *value;
341
+ CYTHON_UNUSED_VAR(default_value);
342
+
343
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000
344
+ value = _PyDict_Pop(d, key, Py_None);
345
+ #else
346
+ value = CALL_UNBOUND_METHOD(PyDict_Type, "pop", d, key, Py_None);
347
+ #endif
348
+
349
+ if (unlikely(value == NULL))
350
+ return -1;
351
+ Py_DECREF(value);
352
+ return 0;
353
+ #endif
354
+ }
355
+
356
+
357
+ /////////////// dict_iter_common.proto ///////////////
358
+ static PyObject *__Pyx_dict_call_to_get_iterable(PyObject* iterable, PyObject* method_name); /* proto */
359
+ static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos,
360
+ PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict);
361
+
362
+ /////////////// dict_iter_common ///////////////
363
+ //@requires: ObjectHandling.c::UnpackTuple2
364
+ //@requires: ObjectHandling.c::IterFinish
365
+ //@requires: ObjectHandling.c::PyObjectCallMethod0
366
+
367
+ static PyObject *__Pyx_dict_call_to_get_iterable(PyObject* iterable, PyObject* method_name) {
368
+
369
+ PyObject* iter;
370
+ iterable = __Pyx_PyObject_CallMethod0(iterable, method_name);
371
+ if (!iterable)
372
+ return NULL;
373
+ #if !CYTHON_AVOID_BORROWED_REFS
374
+ if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable))
375
+ return iterable;
376
+ #endif
377
+ iter = PyObject_GetIter(iterable);
378
+ Py_DECREF(iterable);
379
+ return iter;
380
+ }
381
+
382
+ #if !CYTHON_AVOID_BORROWED_REFS
383
+ static CYTHON_INLINE int __Pyx_dict_iter_next_source_is_dict(
384
+ PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos,
385
+ PyObject** pkey, PyObject** pvalue, PyObject** pitem) {
386
+ PyObject *key, *value;
387
+ if (unlikely(orig_length != PyDict_Size(iter_obj))) {
388
+ PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration");
389
+ return -1;
390
+ }
391
+ if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) {
392
+ return 0;
393
+ }
394
+ if (pitem) {
395
+ PyObject* tuple = PyTuple_New(2);
396
+ if (unlikely(!tuple)) {
397
+ return -1;
398
+ }
399
+ Py_INCREF(key);
400
+ Py_INCREF(value);
401
+ #if CYTHON_ASSUME_SAFE_MACROS
402
+ PyTuple_SET_ITEM(tuple, 0, key);
403
+ PyTuple_SET_ITEM(tuple, 1, value);
404
+ #else
405
+ if (unlikely(PyTuple_SetItem(tuple, 0, key) < 0)) {
406
+ // decref value; PyTuple_SetItem decrefs key on failure
407
+ Py_DECREF(value);
408
+ Py_DECREF(tuple);
409
+ return -1;
410
+ }
411
+ if (unlikely(PyTuple_SetItem(tuple, 1, value) < 0)) {
412
+ // PyTuple_SetItem decrefs value on failure
413
+ Py_DECREF(tuple);
414
+ return -1;
415
+ }
416
+ #endif
417
+ *pitem = tuple;
418
+ } else {
419
+ if (pkey) {
420
+ Py_INCREF(key);
421
+ *pkey = key;
422
+ }
423
+ if (pvalue) {
424
+ Py_INCREF(value);
425
+ *pvalue = value;
426
+ }
427
+ }
428
+ return 1;
429
+ }
430
+ #endif
431
+
432
+ static CYTHON_INLINE int __Pyx_dict_iter_next(
433
+ PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos,
434
+ PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) {
435
+ PyObject* next_item;
436
+ #if !CYTHON_AVOID_BORROWED_REFS
437
+ if (source_is_dict) {
438
+ int result;
439
+ #if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API
440
+ Py_BEGIN_CRITICAL_SECTION(iter_obj);
441
+ #endif
442
+ result = __Pyx_dict_iter_next_source_is_dict(iter_obj, orig_length, ppos, pkey, pvalue, pitem);
443
+ #if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API
444
+ Py_END_CRITICAL_SECTION();
445
+ #endif
446
+ return result;
447
+ } else if (PyTuple_CheckExact(iter_obj)) {
448
+ Py_ssize_t pos = *ppos;
449
+ Py_ssize_t tuple_size = __Pyx_PyTuple_GET_SIZE(iter_obj);
450
+ #if !CYTHON_ASSUME_SAFE_SIZE
451
+ if (unlikely(tuple_size < 0)) return -1;
452
+ #endif
453
+ if (unlikely(pos >= tuple_size)) return 0;
454
+ *ppos = pos + 1;
455
+ #if CYTHON_ASSUME_SAFE_MACROS
456
+ next_item = PyTuple_GET_ITEM(iter_obj, pos);
457
+ #else
458
+ next_item = PyTuple_GetItem(iter_obj, pos);
459
+ if (unlikely(!next_item)) return -1;
460
+ #endif
461
+ Py_INCREF(next_item);
462
+ } else if (PyList_CheckExact(iter_obj)) {
463
+ Py_ssize_t pos = *ppos;
464
+ Py_ssize_t list_size = __Pyx_PyList_GET_SIZE(iter_obj);
465
+ #if !CYTHON_ASSUME_SAFE_SIZE
466
+ if (unlikely(list_size < 0)) return -1;
467
+ #endif
468
+ if (unlikely(pos >= list_size)) return 0;
469
+ *ppos = pos + 1;
470
+ next_item = __Pyx_PyList_GetItemRef(iter_obj, pos);
471
+ if (unlikely(!next_item)) return -1;
472
+ } else
473
+ #endif
474
+ {
475
+ next_item = PyIter_Next(iter_obj);
476
+ if (unlikely(!next_item)) {
477
+ return __Pyx_IterFinish();
478
+ }
479
+ }
480
+ if (pitem) {
481
+ *pitem = next_item;
482
+ } else if (pkey && pvalue) {
483
+ if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1))
484
+ return -1;
485
+ } else if (pkey) {
486
+ *pkey = next_item;
487
+ } else {
488
+ *pvalue = next_item;
489
+ }
490
+ return 1;
491
+ }
492
+
493
+ /////////////// dict_iter_legacy.proto //////////////
494
+
495
+ // "legacy" handles old-style iter* methods
496
+ static CYTHON_INLINE PyObject* __Pyx_dict_iterator_legacy(PyObject* dict, int is_dict, PyObject* method_name,
497
+ Py_ssize_t* p_orig_length, int* p_is_dict);
498
+
499
+ /////////////// dict_iter_legacy //////////////////
500
+ //@requires: dict_iter_common
501
+
502
+ #if CYTHON_AVOID_BORROWED_REFS
503
+ #include <string.h>
504
+ #endif
505
+
506
+ static CYTHON_INLINE PyObject* __Pyx_dict_iterator_legacy(PyObject* iterable, int is_dict, PyObject* method_name,
507
+ Py_ssize_t* p_orig_length, int* p_source_is_dict) {
508
+ int owned_method_name = 0;
509
+ // Don't include frozendict.
510
+ is_dict = is_dict || likely(PyDict_CheckExact(iterable));
511
+ *p_source_is_dict = is_dict;
512
+ if (is_dict) {
513
+ #if !CYTHON_AVOID_BORROWED_REFS
514
+ *p_orig_length = PyDict_Size(iterable);
515
+ Py_INCREF(iterable);
516
+ return iterable;
517
+ #else
518
+ // On PyPy3/GraalPy, we need to translate manually the method name.
519
+ // This logic is not needed on CPython thanks to the fast case above.
520
+ if (method_name) {
521
+ method_name = PyUnicode_Substring(method_name, 4, 10); // longest is "itervalues" (len=10)
522
+ if (unlikely(!method_name))
523
+ return NULL;
524
+ owned_method_name = 1;
525
+ }
526
+ #endif
527
+ }
528
+ *p_orig_length = 0;
529
+ if (method_name) {
530
+ iterable = __Pyx_dict_call_to_get_iterable(iterable, method_name);
531
+ if (owned_method_name) {
532
+ Py_DECREF(method_name);
533
+ }
534
+ return iterable;
535
+ } else {
536
+ return PyObject_GetIter(iterable);
537
+ }
538
+ }
539
+
540
+ /////////////// dict_iter.proto ///////////////
541
+
542
+ static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name,
543
+ Py_ssize_t* p_orig_length, int* p_is_dict);
544
+
545
+ /////////////// dict_iter ///////////////
546
+ //@requires: Builtins.c::PyFrozenDict
547
+ //@requires: dict_iter_common
548
+
549
+ static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name,
550
+ Py_ssize_t* p_orig_length, int* p_source_is_dict) {
551
+ is_dict = is_dict || likely(__Pyx_PyAnyDict_CheckExact(iterable));
552
+ *p_source_is_dict = is_dict;
553
+ #if !CYTHON_AVOID_BORROWED_REFS
554
+ if (is_dict) {
555
+ *p_orig_length = PyDict_Size(iterable);
556
+ Py_INCREF(iterable);
557
+ return iterable;
558
+ }
559
+ #endif
560
+ *p_orig_length = 0;
561
+ if (method_name) {
562
+ return __Pyx_dict_call_to_get_iterable(iterable, method_name);
563
+ } else {
564
+ return PyObject_GetIter(iterable);
565
+ }
566
+ }
567
+
568
+
569
+ /////////////// set_iter.proto ///////////////
570
+
571
+ static CYTHON_INLINE PyObject* __Pyx_set_iterator(PyObject* iterable, int is_set,
572
+ Py_ssize_t* p_orig_length, int* p_source_is_set); /*proto*/
573
+ static CYTHON_INLINE int __Pyx_set_iter_next(
574
+ PyObject* iter_obj, Py_ssize_t orig_length,
575
+ Py_ssize_t* ppos, PyObject **value,
576
+ int source_is_set); /*proto*/
577
+
578
+ /////////////// set_iter ///////////////
579
+ //@requires: ObjectHandling.c::IterFinish
580
+
581
+ static CYTHON_INLINE PyObject* __Pyx_set_iterator(PyObject* iterable, int is_set,
582
+ Py_ssize_t* p_orig_length, int* p_source_is_set) {
583
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000
584
+ is_set = is_set || likely(PySet_CheckExact(iterable) || PyFrozenSet_CheckExact(iterable));
585
+ *p_source_is_set = is_set;
586
+ if (likely(is_set)) {
587
+ *p_orig_length = PySet_Size(iterable);
588
+ Py_INCREF(iterable);
589
+ return iterable;
590
+ }
591
+ #else
592
+ CYTHON_UNUSED_VAR(is_set);
593
+ *p_source_is_set = 0;
594
+ #endif
595
+ *p_orig_length = 0;
596
+ return PyObject_GetIter(iterable);
597
+ }
598
+
599
+ static CYTHON_INLINE int __Pyx_set_iter_next(
600
+ PyObject* iter_obj, Py_ssize_t orig_length,
601
+ Py_ssize_t* ppos, PyObject **value,
602
+ int source_is_set) {
603
+ if (!CYTHON_COMPILING_IN_CPYTHON || PY_VERSION_HEX >= 0x030d0000 || unlikely(!source_is_set)) {
604
+ *value = PyIter_Next(iter_obj);
605
+ if (unlikely(!*value)) {
606
+ return __Pyx_IterFinish();
607
+ }
608
+ CYTHON_UNUSED_VAR(orig_length);
609
+ CYTHON_UNUSED_VAR(ppos);
610
+ return 1;
611
+ }
612
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000
613
+ if (unlikely(PySet_GET_SIZE(iter_obj) != orig_length)) {
614
+ PyErr_SetString(
615
+ PyExc_RuntimeError,
616
+ "set changed size during iteration");
617
+ return -1;
618
+ }
619
+ {
620
+ Py_hash_t hash;
621
+ int ret = _PySet_NextEntry(iter_obj, ppos, value, &hash);
622
+ // CPython does not raise errors here, only if !isinstance(iter_obj, set/frozenset)
623
+ assert (ret != -1);
624
+ if (likely(ret)) {
625
+ Py_INCREF(*value);
626
+ return 1;
627
+ }
628
+ }
629
+ #endif
630
+ return 0;
631
+ }
632
+
633
+ /////////////// py_set_discard_unhashable ///////////////
634
+ //@requires: Builtins.c::pyfrozenset_new
635
+
636
+ static int __Pyx_PySet_DiscardUnhashable(PyObject *set, PyObject *key) {
637
+ PyObject *tmpkey;
638
+ int rv;
639
+
640
+ if (likely(!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)))
641
+ return -1;
642
+ PyErr_Clear();
643
+ tmpkey = __Pyx_PyFrozenSet_New(key);
644
+ if (tmpkey == NULL)
645
+ return -1;
646
+ rv = PySet_Discard(set, tmpkey);
647
+ Py_DECREF(tmpkey);
648
+ return rv;
649
+ }
650
+
651
+
652
+ /////////////// py_set_discard.proto ///////////////
653
+
654
+ static CYTHON_INLINE int __Pyx_PySet_Discard(PyObject *set, PyObject *key); /*proto*/
655
+
656
+ /////////////// py_set_discard ///////////////
657
+ //@requires: py_set_discard_unhashable
658
+
659
+ static CYTHON_INLINE int __Pyx_PySet_Discard(PyObject *set, PyObject *key) {
660
+ int found = PySet_Discard(set, key);
661
+ // Convert *key* to frozenset if necessary
662
+ if (unlikely(found < 0)) {
663
+ found = __Pyx_PySet_DiscardUnhashable(set, key);
664
+ }
665
+ // note: returns -1 on error, 0 (not found) or 1 (found) otherwise => error check for -1 or < 0 works
666
+ return found;
667
+ }
668
+
669
+
670
+ /////////////// py_set_remove.proto ///////////////
671
+
672
+ static CYTHON_INLINE int __Pyx_PySet_Remove(PyObject *set, PyObject *key); /*proto*/
673
+
674
+ /////////////// py_set_remove ///////////////
675
+ //@requires: py_set_discard_unhashable
676
+
677
+ static int __Pyx_PySet_RemoveNotFound(PyObject *set, PyObject *key, int found) {
678
+ // Convert *key* to frozenset if necessary
679
+ if (unlikely(found < 0)) {
680
+ found = __Pyx_PySet_DiscardUnhashable(set, key);
681
+ }
682
+ if (likely(found == 0)) {
683
+ // Not found
684
+ PyObject *tup;
685
+ tup = PyTuple_Pack(1, key);
686
+ if (!tup)
687
+ return -1;
688
+ PyErr_SetObject(PyExc_KeyError, tup);
689
+ Py_DECREF(tup);
690
+ return -1;
691
+ }
692
+ // note: returns -1 on error, 0 (not found) or 1 (found) otherwise => error check for -1 or < 0 works
693
+ return found;
694
+ }
695
+
696
+ static CYTHON_INLINE int __Pyx_PySet_Remove(PyObject *set, PyObject *key) {
697
+ int found = PySet_Discard(set, key);
698
+ if (unlikely(found != 1)) {
699
+ // note: returns -1 on error, 0 (not found) or 1 (found) otherwise => error check for -1 or < 0 works
700
+ return __Pyx_PySet_RemoveNotFound(set, key, found);
701
+ }
702
+ return 0;
703
+ }
704
+
705
+
706
+ /////////////// unicode_iter.proto ///////////////
707
+
708
+ static CYTHON_INLINE int __Pyx_init_unicode_iteration(
709
+ PyObject* ustring, Py_ssize_t *length, void** data, int *kind); /* proto */
710
+
711
+ /////////////// unicode_iter ///////////////
712
+
713
+ static CYTHON_INLINE int __Pyx_init_unicode_iteration(
714
+ PyObject* ustring, Py_ssize_t *length, void** data, int *kind) {
715
+ #if CYTHON_COMPILING_IN_LIMITED_API
716
+ // In the limited API we just point data to the unicode object
717
+ *kind = 0;
718
+ *length = PyUnicode_GetLength(ustring);
719
+ *data = (void*)ustring;
720
+ #else
721
+ if (unlikely(__Pyx_PyUnicode_READY(ustring) < 0)) return -1;
722
+ *kind = PyUnicode_KIND(ustring);
723
+ *length = PyUnicode_GET_LENGTH(ustring);
724
+ *data = PyUnicode_DATA(ustring);
725
+ #endif
726
+ return 0;
727
+ }
728
+
729
+ /////////////// pyobject_as_double.proto ///////////////
730
+
731
+ static double __Pyx__PyObject_AsDouble(PyObject* obj); /* proto */
732
+
733
+ #if CYTHON_COMPILING_IN_PYPY
734
+ #define __Pyx_PyObject_AsDouble(obj) \
735
+ (likely(PyFloat_CheckExact(obj)) ? PyFloat_AS_DOUBLE(obj) : \
736
+ likely(PyLong_CheckExact(obj)) ? \
737
+ PyFloat_AsDouble(obj) : __Pyx__PyObject_AsDouble(obj))
738
+ #else
739
+ #define __Pyx_PyObject_AsDouble(obj) \
740
+ ((likely(PyFloat_CheckExact(obj))) ? __Pyx_PyFloat_AS_DOUBLE(obj) : \
741
+ likely(PyLong_CheckExact(obj)) ? \
742
+ PyLong_AsDouble(obj) : __Pyx__PyObject_AsDouble(obj))
743
+ #endif
744
+
745
+ /////////////// pyobject_as_double ///////////////
746
+ //@requires: pybytes_as_double
747
+ //@requires: pyunicode_as_double
748
+ //@requires: ObjectHandling.c::PyObjectCallOneArg
749
+ //@requires: ObjectHandling.c::RaiseErrorWithObjectType
750
+
751
+ static double __Pyx__PyObject_AsDouble(PyObject* obj) {
752
+ if (PyUnicode_CheckExact(obj)) {
753
+ return __Pyx_PyUnicode_AsDouble(obj);
754
+ } else if (PyBytes_CheckExact(obj)) {
755
+ return __Pyx_PyBytes_AsDouble(obj);
756
+ } else if (PyByteArray_CheckExact(obj)) {
757
+ return __Pyx_PyByteArray_AsDouble(obj);
758
+ } else {
759
+ PyObject* float_value;
760
+ #if !CYTHON_USE_TYPE_SLOTS
761
+ float_value = PyNumber_Float(obj); if ((0)) goto bad;
762
+ // avoid "unused" warnings
763
+ (void)__Pyx_PyObject_CallOneArg;
764
+ #else
765
+ PyNumberMethods *nb = Py_TYPE(obj)->tp_as_number;
766
+ if (likely(nb) && likely(nb->nb_float)) {
767
+ float_value = nb->nb_float(obj);
768
+ if (likely(float_value) && unlikely(!PyFloat_Check(float_value))) {
769
+ __Pyx_RaiseTypeErrorWithObjectType(
770
+ "__float__ returned non-float (type " __Pyx_FMT_TYPENAME ")",
771
+ float_value);
772
+ Py_DECREF(float_value);
773
+ goto bad;
774
+ }
775
+ } else {
776
+ float_value = __Pyx_PyObject_CallOneArg((PyObject*)&PyFloat_Type, obj);
777
+ }
778
+ #endif
779
+ if (likely(float_value)) {
780
+ double value = __Pyx_PyFloat_AS_DOUBLE(float_value);
781
+ Py_DECREF(float_value);
782
+ return value;
783
+ }
784
+ }
785
+ bad:
786
+ return (double)-1;
787
+ }
788
+
789
+
790
+ /////////////// pyunicode_as_double.proto ///////////////
791
+
792
+ static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj);/*proto*/
793
+
794
+ /////////////// pyunicode_as_double.proto ///////////////
795
+ //@requires: pybytes_as_double
796
+
797
+ #if !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS
798
+ static const char* __Pyx__PyUnicode_AsDouble_Copy(const void* data, const int kind, char* buffer, Py_ssize_t start, Py_ssize_t end) {
799
+ int last_was_punctuation;
800
+ Py_ssize_t i;
801
+ // number must not start with punctuation
802
+ last_was_punctuation = 1;
803
+ for (i=start; i <= end; i++) {
804
+ Py_UCS4 chr = PyUnicode_READ(kind, data, i);
805
+ int is_punctuation = (chr == '_') | (chr == '.');
806
+ *buffer = (char)chr;
807
+ // reject sequences of '_' and '.'
808
+ buffer += (chr != '_');
809
+ if (unlikely(chr > 127)) goto parse_failure;
810
+ if (unlikely(last_was_punctuation & is_punctuation)) goto parse_failure;
811
+ last_was_punctuation = is_punctuation;
812
+ }
813
+ if (unlikely(last_was_punctuation)) goto parse_failure;
814
+ *buffer = '\0';
815
+ return buffer;
816
+
817
+ parse_failure:
818
+ return NULL;
819
+ }
820
+
821
+ static double __Pyx__PyUnicode_AsDouble_inf_nan(const void* data, int kind, Py_ssize_t start, Py_ssize_t length) {
822
+ int matches = 1;
823
+ Py_UCS4 chr;
824
+ Py_UCS4 sign = PyUnicode_READ(kind, data, start);
825
+ int is_signed = (sign == '-') | (sign == '+');
826
+ start += is_signed;
827
+ length -= is_signed;
828
+
829
+ switch (PyUnicode_READ(kind, data, start)) {
830
+ #ifdef Py_NAN
831
+ case 'n':
832
+ case 'N':
833
+ if (unlikely(length != 3)) goto parse_failure;
834
+ chr = PyUnicode_READ(kind, data, start+1);
835
+ matches &= (chr == 'a') | (chr == 'A');
836
+ chr = PyUnicode_READ(kind, data, start+2);
837
+ matches &= (chr == 'n') | (chr == 'N');
838
+ if (unlikely(!matches)) goto parse_failure;
839
+ return (sign == '-') ? -Py_NAN : Py_NAN;
840
+ #endif
841
+ case 'i':
842
+ case 'I':
843
+ if (unlikely(length < 3)) goto parse_failure;
844
+ chr = PyUnicode_READ(kind, data, start+1);
845
+ matches &= (chr == 'n') | (chr == 'N');
846
+ chr = PyUnicode_READ(kind, data, start+2);
847
+ matches &= (chr == 'f') | (chr == 'F');
848
+ if (likely(length == 3 && matches))
849
+ return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL;
850
+ if (unlikely(length != 8)) goto parse_failure;
851
+ chr = PyUnicode_READ(kind, data, start+3);
852
+ matches &= (chr == 'i') | (chr == 'I');
853
+ chr = PyUnicode_READ(kind, data, start+4);
854
+ matches &= (chr == 'n') | (chr == 'N');
855
+ chr = PyUnicode_READ(kind, data, start+5);
856
+ matches &= (chr == 'i') | (chr == 'I');
857
+ chr = PyUnicode_READ(kind, data, start+6);
858
+ matches &= (chr == 't') | (chr == 'T');
859
+ chr = PyUnicode_READ(kind, data, start+7);
860
+ matches &= (chr == 'y') | (chr == 'Y');
861
+ if (unlikely(!matches)) goto parse_failure;
862
+ return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL;
863
+ case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
864
+ break;
865
+ default:
866
+ goto parse_failure;
867
+ }
868
+ return 0.0;
869
+ parse_failure:
870
+ return -1.0;
871
+ }
872
+
873
+ static double __Pyx_PyUnicode_AsDouble_WithSpaces(PyObject *obj) {
874
+ double value;
875
+ const char *last;
876
+ char *end;
877
+ int valid_parse;
878
+ Py_ssize_t start, length = PyUnicode_GET_LENGTH(obj);
879
+ const int kind = PyUnicode_KIND(obj);
880
+ const void* data = PyUnicode_DATA(obj);
881
+
882
+ // strip spaces at start and end
883
+ start = 0;
884
+ while (Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, start)))
885
+ start++;
886
+ while (start < length - 1 && Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, length - 1)))
887
+ length--;
888
+ length -= start;
889
+ if (unlikely(length <= 0)) goto fallback;
890
+
891
+ // parse NaN / inf
892
+ value = __Pyx__PyUnicode_AsDouble_inf_nan(data, kind, start, length);
893
+ if (value != 0.0) {
894
+ if (unlikely(value == -1.0)) goto fallback;
895
+ return value;
896
+ }
897
+
898
+ if (length < 40) {
899
+ char number[40];
900
+ last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length);
901
+ if (unlikely(!last)) goto fallback;
902
+ value = PyOS_string_to_double(number, &end, NULL);
903
+ valid_parse = (end == last);
904
+ } else {
905
+ char *number = (char*) PyMem_Malloc(((size_t) length + 1) * sizeof(char));
906
+ if (unlikely(!number)) goto fallback;
907
+ last = __Pyx__PyUnicode_AsDouble_Copy(data, kind, number, start, start + length);
908
+ if (unlikely(!last)) {
909
+ PyMem_Free(number);
910
+ goto fallback;
911
+ }
912
+ value = PyOS_string_to_double(number, &end, NULL);
913
+ valid_parse = (end == last);
914
+ PyMem_Free(number);
915
+ }
916
+ if (likely(valid_parse) || (value == (double)-1 && PyErr_Occurred())) {
917
+ return value;
918
+ }
919
+ fallback:
920
+ return __Pyx_SlowPyString_AsDouble(obj);
921
+ }
922
+ #endif
923
+
924
+ static CYTHON_INLINE double __Pyx_PyUnicode_AsDouble(PyObject *obj) {
925
+ // Currently not optimised for Py2.7.
926
+ #if !CYTHON_COMPILING_IN_PYPY && CYTHON_ASSUME_SAFE_MACROS
927
+ if (unlikely(__Pyx_PyUnicode_READY(obj) == -1))
928
+ return (double)-1;
929
+ if (likely(PyUnicode_IS_ASCII(obj))) {
930
+ const char *s;
931
+ Py_ssize_t length;
932
+ s = PyUnicode_AsUTF8AndSize(obj, &length);
933
+ return __Pyx__PyBytes_AsDouble(obj, s, length);
934
+ }
935
+ return __Pyx_PyUnicode_AsDouble_WithSpaces(obj);
936
+ #else
937
+ return __Pyx_SlowPyString_AsDouble(obj);
938
+ #endif
939
+ }
940
+
941
+
942
+ /////////////// pybytes_as_double.proto ///////////////
943
+
944
+ static double __Pyx_SlowPyString_AsDouble(PyObject *obj);/*proto*/
945
+ static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length);/*proto*/
946
+
947
+ static CYTHON_INLINE double __Pyx_PyBytes_AsDouble(PyObject *obj) {
948
+ char* as_c_string;
949
+ Py_ssize_t size;
950
+ #if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
951
+ as_c_string = PyBytes_AS_STRING(obj);
952
+ size = PyBytes_GET_SIZE(obj);
953
+ #else
954
+ if (PyBytes_AsStringAndSize(obj, &as_c_string, &size) < 0) {
955
+ return (double)-1;
956
+ }
957
+ #endif
958
+ return __Pyx__PyBytes_AsDouble(obj, as_c_string, size);
959
+ }
960
+ static CYTHON_INLINE double __Pyx_PyByteArray_AsDouble(PyObject *obj) {
961
+ char* as_c_string;
962
+ Py_ssize_t size;
963
+ #if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE
964
+ as_c_string = PyByteArray_AS_STRING(obj);
965
+ size = PyByteArray_GET_SIZE(obj);
966
+ #else
967
+ as_c_string = PyByteArray_AsString(obj);
968
+ if (as_c_string == NULL) {
969
+ return (double)-1;
970
+ }
971
+ size = PyByteArray_Size(obj);
972
+ #endif
973
+ return __Pyx__PyBytes_AsDouble(obj, as_c_string, size);
974
+ }
975
+
976
+
977
+ /////////////// pybytes_as_double ///////////////
978
+
979
+ static double __Pyx_SlowPyString_AsDouble(PyObject *obj) {
980
+ PyObject *float_value = PyFloat_FromString(obj);
981
+ if (likely(float_value)) {
982
+ double value = __Pyx_PyFloat_AS_DOUBLE(float_value);
983
+ Py_DECREF(float_value);
984
+ return value;
985
+ }
986
+ return (double)-1;
987
+ }
988
+
989
+ static const char* __Pyx__PyBytes_AsDouble_Copy(const char* start, char* buffer, Py_ssize_t length) {
990
+ // number must not start with punctuation
991
+ int last_was_punctuation = 1;
992
+ int parse_error_found = 0;
993
+ Py_ssize_t i;
994
+ for (i=0; i < length; i++) {
995
+ char chr = start[i];
996
+ int is_punctuation = (chr == '_') | (chr == '.') | (chr == 'e') | (chr == 'E');
997
+ *buffer = chr;
998
+ buffer += (chr != '_');
999
+ // reject sequences of punctuation, e.g. '_.'
1000
+ parse_error_found |= last_was_punctuation & is_punctuation;
1001
+ last_was_punctuation = is_punctuation;
1002
+ }
1003
+ // number must not end with punctuation
1004
+ parse_error_found |= last_was_punctuation;
1005
+ *buffer = '\0';
1006
+ return unlikely(parse_error_found) ? NULL : buffer;
1007
+ }
1008
+
1009
+ static double __Pyx__PyBytes_AsDouble_inf_nan(const char* start, Py_ssize_t length) {
1010
+ int matches = 1;
1011
+ char sign = start[0];
1012
+ int is_signed = (sign == '+') | (sign == '-');
1013
+ start += is_signed;
1014
+ length -= is_signed;
1015
+
1016
+ switch (start[0]) {
1017
+ #ifdef Py_NAN
1018
+ case 'n':
1019
+ case 'N':
1020
+ if (unlikely(length != 3)) goto parse_failure;
1021
+ matches &= (start[1] == 'a' || start[1] == 'A');
1022
+ matches &= (start[2] == 'n' || start[2] == 'N');
1023
+ if (unlikely(!matches)) goto parse_failure;
1024
+ return (sign == '-') ? -Py_NAN : Py_NAN;
1025
+ #endif
1026
+ case 'i':
1027
+ case 'I':
1028
+ if (unlikely(length < 3)) goto parse_failure;
1029
+ matches &= (start[1] == 'n' || start[1] == 'N');
1030
+ matches &= (start[2] == 'f' || start[2] == 'F');
1031
+ if (likely(length == 3 && matches))
1032
+ return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL;
1033
+ if (unlikely(length != 8)) goto parse_failure;
1034
+ matches &= (start[3] == 'i' || start[3] == 'I');
1035
+ matches &= (start[4] == 'n' || start[4] == 'N');
1036
+ matches &= (start[5] == 'i' || start[5] == 'I');
1037
+ matches &= (start[6] == 't' || start[6] == 'T');
1038
+ matches &= (start[7] == 'y' || start[7] == 'Y');
1039
+ if (unlikely(!matches)) goto parse_failure;
1040
+ return (sign == '-') ? -Py_HUGE_VAL : Py_HUGE_VAL;
1041
+ case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
1042
+ break;
1043
+ default:
1044
+ goto parse_failure;
1045
+ }
1046
+ return 0.0;
1047
+ parse_failure:
1048
+ return -1.0;
1049
+ }
1050
+
1051
+ static CYTHON_INLINE int __Pyx__PyBytes_AsDouble_IsSpace(char ch) {
1052
+ // see Py_ISSPACE() in CPython
1053
+ // https://github.com/python/cpython/blob/master/Python/pyctype.c
1054
+ return (ch == 0x20) | !((ch < 0x9) | (ch > 0xd));
1055
+ }
1056
+
1057
+ CYTHON_UNUSED static double __Pyx__PyBytes_AsDouble(PyObject *obj, const char* start, Py_ssize_t length) {
1058
+ double value;
1059
+ Py_ssize_t i, digits;
1060
+ const char *last = start + length;
1061
+ char *end;
1062
+ int valid_parse;
1063
+
1064
+ // strip spaces at start and end
1065
+ while (__Pyx__PyBytes_AsDouble_IsSpace(*start))
1066
+ start++;
1067
+ while (start < last - 1 && __Pyx__PyBytes_AsDouble_IsSpace(last[-1]))
1068
+ last--;
1069
+ length = last - start;
1070
+ if (unlikely(length <= 0)) goto fallback;
1071
+
1072
+ // parse NaN / inf
1073
+ value = __Pyx__PyBytes_AsDouble_inf_nan(start, length);
1074
+ if (value != 0.0) {
1075
+ if (unlikely(value == -1.0)) goto fallback;
1076
+ return value;
1077
+ }
1078
+
1079
+ // look for underscores
1080
+ digits = 0;
1081
+ for (i=0; i < length; digits += start[i++] != '_');
1082
+
1083
+ if (likely(digits == length)) {
1084
+ value = PyOS_string_to_double(start, &end, NULL);
1085
+ valid_parse = (end == last);
1086
+ } else if (digits < 40) {
1087
+ char number[40];
1088
+ last = __Pyx__PyBytes_AsDouble_Copy(start, number, length);
1089
+ if (unlikely(!last)) goto fallback;
1090
+ value = PyOS_string_to_double(number, &end, NULL);
1091
+ valid_parse = (end == last);
1092
+ } else {
1093
+ char *number = (char*) PyMem_Malloc(((size_t) digits + 1) * sizeof(char));
1094
+ if (unlikely(!number)) goto fallback;
1095
+ last = __Pyx__PyBytes_AsDouble_Copy(start, number, length);
1096
+ if (unlikely(!last)) {
1097
+ PyMem_Free(number);
1098
+ goto fallback;
1099
+ }
1100
+ value = PyOS_string_to_double(number, &end, NULL);
1101
+ valid_parse = (end == last);
1102
+ PyMem_Free(number);
1103
+ }
1104
+ if (likely(valid_parse) || (value == (double)-1 && PyErr_Occurred())) {
1105
+ return value;
1106
+ }
1107
+ fallback:
1108
+ return __Pyx_SlowPyString_AsDouble(obj);
1109
+ }
1110
+
1111
+
1112
+ /////////////// PyNumberPow2.proto ///////////////
1113
+
1114
+ #define __Pyx_PyNumber_InPlacePowerOf2(a, b, c) __Pyx__PyNumber_PowerOf2(a, b, c, 1)
1115
+ #define __Pyx_PyNumber_PowerOf2(a, b, c) __Pyx__PyNumber_PowerOf2(a, b, c, 0)
1116
+
1117
+ static PyObject* __Pyx__PyNumber_PowerOf2(PyObject *two, PyObject *exp, PyObject *none, int inplace); /*proto*/
1118
+
1119
+ /////////////// PyNumberPow2 ///////////////
1120
+ //@requires: Exceptions.c::IgnoreException
1121
+
1122
+ static PyObject* __Pyx__PyNumber_PowerOf2(PyObject *two, PyObject *exp, PyObject *none, int inplace) {
1123
+ // in CPython, 1<<N is substantially faster than 2**N
1124
+ // see https://bugs.python.org/issue21420
1125
+ #if !CYTHON_COMPILING_IN_PYPY
1126
+ Py_ssize_t shiftby;
1127
+ if (likely(PyLong_CheckExact(exp))) {
1128
+ #if CYTHON_USE_PYLONG_INTERNALS
1129
+ if (__Pyx_PyLong_IsZero(exp)) {
1130
+ return PyLong_FromLong(1L);
1131
+ } else if (__Pyx_PyLong_IsNeg(exp)) {
1132
+ goto fallback;
1133
+ } else if (__Pyx_PyLong_IsCompact(exp)) {
1134
+ shiftby = __Pyx_PyLong_CompactValueUnsigned(exp);
1135
+ } else {
1136
+ shiftby = PyLong_AsSsize_t(exp);
1137
+ }
1138
+ #else
1139
+ shiftby = PyLong_AsSsize_t(exp);
1140
+ #endif
1141
+ } else {
1142
+ goto fallback;
1143
+ }
1144
+ if (likely(shiftby >= 0)) {
1145
+ if ((size_t)shiftby <= sizeof(long) * 8 - 2) {
1146
+ long value = 1L << shiftby;
1147
+ return PyLong_FromLong(value);
1148
+ } else if ((size_t)shiftby <= sizeof(unsigned PY_LONG_LONG) * 8 - 1) {
1149
+ unsigned PY_LONG_LONG value = ((unsigned PY_LONG_LONG)1) << shiftby;
1150
+ return PyLong_FromUnsignedLongLong(value);
1151
+ } else {
1152
+ PyObject *result, *one = PyLong_FromLong(1L);
1153
+ if (unlikely(!one)) return NULL;
1154
+ result = PyNumber_Lshift(one, exp);
1155
+ Py_DECREF(one);
1156
+ return result;
1157
+ }
1158
+ } else if (shiftby == -1) {
1159
+ PyObject *err = PyErr_Occurred();
1160
+ if (err && !__Pyx_IgnoreGivenException(err, PyExc_Exception)) {
1161
+ return NULL; // BaseException
1162
+ }
1163
+ }
1164
+ fallback:
1165
+ #endif
1166
+ return (inplace ? PyNumber_InPlacePower : PyNumber_Power)(two, exp, none);
1167
+ }
1168
+
1169
+ /////////////// PyNumberBinop.proto ///////////////
1170
+
1171
+ #if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_GRAAL || CYTHON_COMPILING_IN_LIMITED_API
1172
+
1173
+ #define __Pyx_{{op_name}}_{{type1}}_{{type2}}(op1, op2) {{op_name}}(op1, op2)
1174
+ #define __Pyx_{{inplace_op_name}}_{{type1}}_{{type2}}(op1, op2) {{inplace_op_name}}(op1, op2)
1175
+
1176
+ #else
1177
+
1178
+ #define __Pyx_{{op_name}}_{{type1}}_{{type2}}(op1, op2) __Pyx__{{op_name}}_{{type1}}_{{type2}}(op1, op2, 0)
1179
+ #define __Pyx_{{inplace_op_name}}_{{type1}}_{{type2}}(op1, op2) __Pyx__{{op_name}}_{{type1}}_{{type2}}(op1, op2, 1)
1180
+
1181
+ static CYTHON_INLINE PyObject* __Pyx__{{op_name}}_{{type1}}_{{type2}}(PyObject *op1, PyObject *op2, int inplace); /*proto*/
1182
+ #endif
1183
+
1184
+ /////////////// PyNumberBinop ///////////////
1185
+ //@requires: ObjectHandling.c::RaiseErrorWithObjectTypes
1186
+
1187
+ #if !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_GRAAL || CYTHON_COMPILING_IN_LIMITED_API)
1188
+
1189
+ {{py: assert type1 in ('object', 'int', 'float'), type1 }}
1190
+ {{py: assert type2 in ('object', 'int', 'float'), type2 }}
1191
+ {{py: slot_name = {'+': 'add', '-': 'subtract', '*': 'multiply', '^': 'xor', '&': 'and', '|': 'or'}[c_op] }}
1192
+ {{py:
1193
+ def is_type(operand, expected, type1=type1, type2=type2):
1194
+ assert operand in ('op1', 'op2'), operand
1195
+ assert expected in ('int', 'float'), type
1196
+ type = type1 if operand == 'op1' else type2
1197
+ if type == expected:
1198
+ check = f"likely({operand} != Py_None)"
1199
+ else:
1200
+ function = "PyFloat_CheckExact" if expected == 'float' else 'PyLong_CheckExact'
1201
+ check = f"{function}({operand})"
1202
+ other_type = type2 if operand == 'op1' else type1
1203
+ if other_type == expected:
1204
+ check = f"likely({check})"
1205
+ return check
1206
+ }}
1207
+
1208
+ {{if c_op in '+-*' or type1 != 'float'}}
1209
+
1210
+ #if CYTHON_USE_TYPE_SLOTS || __PYX_LIMITED_VERSION_HEX >= 0x030A0000
1211
+ #ifndef __Pyx_DEFINED_BinopTypeError
1212
+ #define __Pyx_DEFINED_BinopTypeError
1213
+
1214
+ static void __Pyx_BinopTypeError(PyObject *op1, PyObject *op2, const char* op, int inplace) {
1215
+ // op1 is either 'int' or 'float', op2 is unknown.
1216
+ // op has either 1 or 2 characters, ending with NUL.
1217
+ char opname[4] = {op[0], op[1], 0, 0};
1218
+ if (inplace) {
1219
+ opname[op[1] ? 2 : 1] = '=';
1220
+ }
1221
+ __Pyx_RaiseErrorWithObjectTypes1(
1222
+ PyExc_TypeError,
1223
+ "unsupported operand type(s) for %.3s: '" __Pyx_FMT_TYPENAME "' and '" __Pyx_FMT_TYPENAME "'",
1224
+ opname, op1, op2);
1225
+ }
1226
+ #endif
1227
+ #endif
1228
+
1229
+ {{endif}}
1230
+
1231
+ {{if c_op in '+-*'}}
1232
+
1233
+ {{if type1 in ('object', 'float')}}
1234
+ #ifndef __Pyx_DEFINED_{{op_name}}_xfloat_{{type2}}
1235
+ #define __Pyx_DEFINED_{{op_name}}_xfloat_{{type2}}
1236
+
1237
+ static PyObject* __Pyx_{{op_name}}_xfloat_{{type2}}(PyObject *op1, PyObject *op2, int inplace) {
1238
+ {{if type2 in ('object', 'int')}}
1239
+ if ({{is_type('op2', 'int')}}) {
1240
+ double int_op2;
1241
+ #if CYTHON_USE_PYLONG_INTERNALS
1242
+ if (__Pyx_PyLong_IsCompact(op2)) {
1243
+ Py_ssize_t compact_op2 = __Pyx_PyLong_CompactValue(op2);
1244
+ {{if c_op in '+-'}}
1245
+ if (compact_op2 == 0) return __Pyx_NewRef(op1);
1246
+ {{endif}}
1247
+ int_op2 = (double) compact_op2;
1248
+ } else
1249
+ #endif
1250
+ {
1251
+ int_op2 = PyLong_AsDouble(op2);
1252
+ if (unlikely((int_op2 == -1.) && PyErr_Occurred())) return NULL;
1253
+
1254
+ {{if c_op in '+-'}}
1255
+ #if !CYTHON_USE_PYLONG_INTERNALS
1256
+ if (int_op2 == 0.) return __Pyx_NewRef(op1);
1257
+ #endif
1258
+ {{endif}}
1259
+ }
1260
+
1261
+ double float_op1 = __Pyx_PyFloat_AS_DOUBLE(op1);
1262
+ #if !CYTHON_ASSUME_SAFE_MACROS
1263
+ if (unlikely((float_op1 == -1.) && PyErr_Occurred())) return NULL;
1264
+ #endif
1265
+
1266
+ {{if c_op == '*'}}
1267
+ // "0 * op2" could be handled before extracting op2, but that has the potential
1268
+ // to fail for very large numbers in op2 and we'd like to keep that error.
1269
+ if (float_op1 == 0.) return __Pyx_NewRef(op1);
1270
+ {{endif}}
1271
+
1272
+ return PyFloat_FromDouble(float_op1 {{c_op}} int_op2);
1273
+ }
1274
+ {{endif}}
1275
+
1276
+ {{if type2 == 'object'}}
1277
+ if (PyLong_Check(op2)) {
1278
+ // Pass PyLong subclasses to PyFloat-op1.
1279
+ binaryfunc slot_func = __Pyx_PyType_GetSubSlot(&PyFloat_Type, tp_as_number, nb_{{slot_name}}, binaryfunc);
1280
+ if (likely(slot_func)) {
1281
+ return slot_func(op1, op2);
1282
+ }
1283
+ }
1284
+ {{endif}}
1285
+
1286
+ // PyFloat-op1 only handles exact PyFloat/PyLong as op2, everything else is left to op2.
1287
+ // PyLong-op2 is handled above, so we can always pass on to op2 here.
1288
+
1289
+ // Avoid running into non-heap-type problems in Py<3.10 Limited API.
1290
+ #if CYTHON_USE_TYPE_SLOTS || __PYX_LIMITED_VERSION_HEX >= 0x030A0000
1291
+ {
1292
+ PyTypeObject *type_op2 = Py_TYPE(op2);
1293
+ // Reverse operation => ignore 'InPlace' operator since it applies to op1, not op2.
1294
+ binaryfunc slot_func = __Pyx_PyType_GetSubSlot(type_op2, tp_as_number, nb_{{slot_name}}, binaryfunc);
1295
+ if (likely(slot_func)) {
1296
+ PyObject *result = slot_func(op1, op2);
1297
+ if (likely(result != Py_NotImplemented)) {
1298
+ return result;
1299
+ }
1300
+ Py_DECREF(result);
1301
+ }
1302
+ // No "sq_concat" since Python doesn't try it on op2 and 'float' definitely doesn't have it.
1303
+
1304
+ __Pyx_BinopTypeError(op1, op2, "{{c_op}}", inplace);
1305
+ return NULL;
1306
+
1307
+ }
1308
+ #else
1309
+ return (inplace) ? {{inplace_op_name}}(op1, op2) : {{op_name}}(op1, op2);
1310
+ #endif
1311
+ }
1312
+ #endif
1313
+ {{endif}}
1314
+
1315
+ // c_op in '+-*'
1316
+ {{endif}}
1317
+
1318
+ {{if type1 in ('object', 'int')}}
1319
+ #ifndef __Pyx_DEFINED_{{op_name}}_xint_{{type2}}
1320
+ #define __Pyx_DEFINED_{{op_name}}_xint_{{type2}}
1321
+
1322
+ static PyObject* __Pyx_{{op_name}}_xint_{{type2}}(PyObject *op1, PyObject *op2, int inplace) {
1323
+ {{if type2 in ('object', 'float') and c_op in '+-*'}}
1324
+ if ({{is_type('op2', 'float')}}) {
1325
+ double int_op1;
1326
+ #if CYTHON_USE_PYLONG_INTERNALS
1327
+ if (__Pyx_PyLong_IsCompact(op1)) {
1328
+ Py_ssize_t compact_op1 = __Pyx_PyLong_CompactValue(op1);
1329
+ {{if c_op == '+'}}
1330
+ if (compact_op1 == 0) return __Pyx_NewRef(op2);
1331
+ {{endif}}
1332
+ int_op1 = (double) compact_op1;
1333
+ } else
1334
+ #endif
1335
+ {
1336
+ int_op1 = PyLong_AsDouble(op1);
1337
+ if (unlikely((int_op1 == -1.) && PyErr_Occurred())) return NULL;
1338
+
1339
+ {{if c_op == '+'}}
1340
+ #if !CYTHON_USE_PYLONG_INTERNALS
1341
+ if (int_op1 == 0.) return __Pyx_NewRef(op2);
1342
+ #endif
1343
+ {{endif}}
1344
+ }
1345
+
1346
+ double float_op2 = __Pyx_PyFloat_AS_DOUBLE(op2);
1347
+ #if !CYTHON_ASSUME_SAFE_MACROS
1348
+ if (unlikely((float_op2 == -1.) && PyErr_Occurred())) return NULL;
1349
+ #endif
1350
+
1351
+ return PyFloat_FromDouble(int_op1 {{c_op}} float_op2);
1352
+ }
1353
+ {{endif}}
1354
+
1355
+ // PyLong-op1 only handles exact PyLong as op2, everything else is left to op2.
1356
+ // Thus, we can always pass on to op2 here.
1357
+
1358
+ // Avoid running into non-heap-type problems in Py<3.10 Limited API.
1359
+ #if CYTHON_USE_TYPE_SLOTS || __PYX_LIMITED_VERSION_HEX >= 0x030A0000
1360
+ {
1361
+ PyTypeObject *type_op2 = Py_TYPE(op2);
1362
+ // Reverse operation => ignore 'InPlace' operator since it applies to op1, not op2.
1363
+ binaryfunc slot_func = __Pyx_PyType_GetSubSlot(type_op2, tp_as_number, nb_{{slot_name}}, binaryfunc);
1364
+ if (likely(slot_func)) {
1365
+ PyObject *result = slot_func(op1, op2);
1366
+ if (likely(result != Py_NotImplemented)) {
1367
+ return result;
1368
+ }
1369
+ Py_DECREF(result);
1370
+ }
1371
+ // No "sq_concat" since Python doesn't try it on op2 and 'int' definitely doesn't have it.
1372
+ {{if c_op == '*'}}
1373
+ ssizeargfunc repeat_func = __Pyx_PyType_GetSubSlot(type_op2, tp_as_sequence, sq_repeat, ssizeargfunc);
1374
+ if (likely(repeat_func)) {
1375
+ Py_ssize_t count;
1376
+ #if CYTHON_USE_PYLONG_INTERNALS
1377
+ if (__Pyx_PyLong_IsCompact(op1)) {
1378
+ count = __Pyx_PyLong_CompactValue(op1);
1379
+ } else
1380
+ #endif
1381
+ {
1382
+ count = PyLong_AsSsize_t(op1);
1383
+ if (unlikely((count == -1) && PyErr_Occurred())) return NULL;
1384
+ }
1385
+ return repeat_func(op2, count);
1386
+ }
1387
+ {{endif}}
1388
+
1389
+ __Pyx_BinopTypeError(op1, op2, "{{c_op}}", inplace);
1390
+ return NULL;
1391
+
1392
+ }
1393
+ #else
1394
+ return (inplace) ? {{inplace_op_name}}(op1, op2) : {{op_name}}(op1, op2);
1395
+ #endif
1396
+ }
1397
+ #endif
1398
+ {{endif}}
1399
+
1400
+ static CYTHON_INLINE PyObject* __Pyx__{{op_name}}_{{type1}}_{{type2}}(PyObject *op1, PyObject *op2, int inplace) {
1401
+ {{if type1 in ('object', 'float') and c_op in '+-*'}}
1402
+ if ({{is_type('op1', 'float')}}) {
1403
+ {{if type2 in ('object', 'float')}}
1404
+ if ({{is_type('op2', 'float')}}) {
1405
+ double float_op2 = __Pyx_PyFloat_AS_DOUBLE(op2);
1406
+ #if !CYTHON_ASSUME_SAFE_MACROS
1407
+ if (unlikely((float_op2 == -1.) && PyErr_Occurred())) return NULL;
1408
+ #endif
1409
+ double float_op1 = __Pyx_PyFloat_AS_DOUBLE(op1);
1410
+ #if !CYTHON_ASSUME_SAFE_MACROS
1411
+ if (unlikely((float_op1 == -1.) && PyErr_Occurred())) return NULL;
1412
+ #endif
1413
+
1414
+ return PyFloat_FromDouble(float_op1 {{c_op}} float_op2);
1415
+ }
1416
+ {{endif}}
1417
+ return __Pyx_{{op_name}}_xfloat_{{type2}}(op1, op2, inplace);
1418
+ }
1419
+ {{endif}}
1420
+
1421
+ {{if type1 in ('object', 'int')}}
1422
+ if ({{is_type('op1', 'int')}}) {
1423
+ {{if type2 in ('object', 'int')}}
1424
+ if ({{is_type('op2', 'int')}}) {
1425
+ #if CYTHON_USE_PYLONG_INTERNALS
1426
+ {{if c_op == '*'}}
1427
+
1428
+ if (__Pyx_PyLong_IsCompact(op1)) {
1429
+ long long int_op1 = (long long) __Pyx_PyLong_CompactValue(op1);
1430
+ if (int_op1 == 0) return __Pyx_NewRef(op1);
1431
+
1432
+ if (__Pyx_PyLong_IsCompact(op2)) {
1433
+ long long int_op2 = (long long) __Pyx_PyLong_CompactValue(op2);
1434
+ if (int_op2 == 0) return __Pyx_NewRef(op2);
1435
+
1436
+ return PyLong_FromLongLong(int_op1 {{c_op}} int_op2);
1437
+ }
1438
+ }
1439
+
1440
+ {{else}}
1441
+
1442
+ if (__Pyx_PyLong_IsCompact(op1)) {
1443
+ Py_ssize_t int_op1 = __Pyx_PyLong_CompactValue(op1);
1444
+ {{if c_op in '+|^'}}
1445
+ if (int_op1 == 0) return __Pyx_NewRef(op2);
1446
+ {{elif c_op == '&'}}
1447
+ if (int_op1 == 0) return __Pyx_NewRef(op1);
1448
+ {{endif}}
1449
+
1450
+ if (__Pyx_PyLong_IsCompact(op2)) {
1451
+ Py_ssize_t int_op2 = __Pyx_PyLong_CompactValue(op2);
1452
+ {{if c_op in '+-|^'}}
1453
+ if (int_op2 == 0) return __Pyx_NewRef(op1);
1454
+ {{elif c_op == '&'}}
1455
+ if (int_op2 == 0) return __Pyx_NewRef(op2);
1456
+ {{endif}}
1457
+
1458
+ return PyLong_FromSsize_t(int_op1 {{c_op}} int_op2);
1459
+ }
1460
+ }
1461
+ {{endif}}
1462
+
1463
+ // op1 is not compact, but op2 might still hit the special case for '0':
1464
+ // identity for '+-|^' -> reuse op1
1465
+ // zero for '*&' -> reuse op2
1466
+ else if (__Pyx_PyLong_IsZero(op2)) return __Pyx_NewRef({{if c_op in '+-|^'}}op1{{else}}op2{{endif}});
1467
+
1468
+ #endif
1469
+
1470
+ binaryfunc slot_func = __Pyx_PyType_GetSubSlot(&PyLong_Type, tp_as_number, nb_{{slot_name}}, binaryfunc);
1471
+ if (likely(slot_func)) {
1472
+ return slot_func(op1, op2);
1473
+ }
1474
+ }
1475
+ {{endif}}
1476
+
1477
+ return __Pyx_{{op_name}}_xint_{{type2}}(op1, op2, inplace);
1478
+ }
1479
+ {{endif}}
1480
+
1481
+ return (inplace) ? {{inplace_op_name}}(op1, op2) : {{op_name}}(op1, op2);
1482
+ }
1483
+ // !(PyPy/Graal/LimitedAPI)
1484
+ #endif
1485
+
1486
+
1487
+ /////////////// UnicodeEquals.proto ///////////////
1488
+ //@requires: PyObjectCompare{"return_obj": 0, "op": "Eq", "c_op": "==", "type1": "str", "type2": "str"}
1489
+
1490
+ #define __Pyx_PyUnicode_Equals(s1, s2) __Pyx_PyObject_CompareBoolEq_str_str(s1, s2, Py_EQ)
1491
+
1492
+
1493
+ /////////////// PyObjectCompare.proto ///////////////
1494
+
1495
+ {{py: c_ret_type = 'PyObject*' if return_obj else 'int'}}
1496
+ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyObject_Compare{{'' if return_obj else 'Bool'}}{{op}}_{{type1}}_{{type2}}(PyObject *op1, PyObject *op2, int pyop); /*proto*/
1497
+
1498
+ /////////////// PyObjectCompare ///////////////
1499
+ //@requires: StringTools.c::IncludeStringH
1500
+
1501
+ {{py: c_ret_type = 'PyObject*' if return_obj else 'int'}}
1502
+ {{py: func_suffix = f"{'' if return_obj else 'Bool'}{op}"}}
1503
+ {{py: return_true = 'goto __pyx_return_true'}}
1504
+ {{py: return_false = 'goto __pyx_return_false'}}
1505
+ {{py: return_error = "return NULL" if return_obj else "return -1"}}
1506
+ {{py: c_op_reversed = {'==': '==', '!=': '!=', '<': '>=', '<=': '>', '>=': '<', '>': '<='}[c_op] }}
1507
+ {{py:
1508
+ check_functions = {
1509
+ 'float': "PyFloat_CheckExact",
1510
+ 'int': 'PyLong_CheckExact',
1511
+ 'str': 'PyUnicode_CheckExact',
1512
+ 'bytes': 'PyBytes_CheckExact',
1513
+ 'bytearray': 'PyByteArray_CheckExact',
1514
+ }
1515
+ }}
1516
+ {{py:
1517
+ def is_type(operand, expected, type1=type1, type2=type2, check_functions=check_functions):
1518
+ assert operand in ('op1', 'op2'), operand
1519
+ assert expected in check_functions, expected
1520
+ type = type1 if operand == 'op1' else type2
1521
+ if type == expected:
1522
+ check = f"likely({operand} != Py_None)"
1523
+ else:
1524
+ function = check_functions[expected]
1525
+ check = f"{function}({operand})"
1526
+ other_type = type2 if operand == 'op1' else type1
1527
+ if other_type == expected:
1528
+ check = f"likely({check})"
1529
+ return check
1530
+ }}
1531
+
1532
+ // str comparisons
1533
+
1534
+ {{if type1 in ('object', 'str') and type2 in ('object', 'str')}}
1535
+ #ifndef __Pyx_DEFINED_PyObject_CompareStrStr{{func_suffix}}
1536
+ #define __Pyx_DEFINED_PyObject_CompareStrStr{{func_suffix}}
1537
+ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyObject_CompareStrStr{{func_suffix}}(PyObject* s1, PyObject* s2) {
1538
+ {{if op in 'EqNe'}}
1539
+ #if __PYX_LIMITED_VERSION_HEX >= 0x030e0000
1540
+ int result = PyUnicode_Equal(s1, s2);
1541
+ #if !CYTHON_COMPILING_IN_CPYTHON
1542
+ // Cannot fail in CPython, but might in others.
1543
+ if (unlikely(result == -1)) {{return_error}};
1544
+ #endif
1545
+ if (result {{c_op}} 0) {{return_false}}; else {{return_true}};
1546
+ #else
1547
+ {{endif}}
1548
+ int result = PyUnicode_Compare(s1, s2);
1549
+ if (unlikely((result == -1) && PyErr_Occurred())) {{return_error}};
1550
+ if (result {{c_op}} 0) {{return_true}}; else {{return_false}};
1551
+ {{if op in 'EqNe'}}
1552
+ #endif
1553
+ {{endif}}
1554
+
1555
+ __pyx_return_true:
1556
+ {{'Py_RETURN_TRUE' if return_obj else 'return 1'}};
1557
+ __pyx_return_false:
1558
+ {{'Py_RETURN_FALSE' if return_obj else 'return 0'}};
1559
+ }
1560
+ #endif
1561
+ // end of str comparisons
1562
+ {{endif}}
1563
+
1564
+ // bytes/bytearray comparisons
1565
+
1566
+ {{for s1_type in ('bytes', 'bytearray')}}
1567
+ {{for s2_type in ('bytes', 'bytearray')}}
1568
+
1569
+ {{if type1 in ('object', s1_type) and type2 in ('object', s2_type)}}
1570
+
1571
+ {{py: s1_prefix = "PyBytes" if s1_type == 'bytes' else "PyByteArray"}}
1572
+ {{py: s2_prefix = "PyBytes" if s2_type == 'bytes' else "PyByteArray"}}
1573
+
1574
+ #if !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_GRAAL)
1575
+
1576
+ #ifndef __Pyx_DEFINED_PyObject_Compare{{s1_prefix}}{{s2_prefix}}{{func_suffix}}
1577
+ #define __Pyx_DEFINED_PyObject_Compare{{s1_prefix}}{{s2_prefix}}{{func_suffix}}
1578
+
1579
+ {{if op in 'EqNe'}}
1580
+ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyObject_Compare{{s1_prefix}}{{s2_prefix}}{{func_suffix}}(PyObject* s1, PyObject* s2) {
1581
+ #if CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS
1582
+ const char *ps1, *ps2;
1583
+ Py_ssize_t length = {{s1_prefix}}_GET_SIZE(s1);
1584
+ if (length != {{s2_prefix}}_GET_SIZE(s2)) {{return_false if op == 'Eq' else return_true}};
1585
+
1586
+ ps1 = {{s1_prefix}}_AS_STRING(s1);
1587
+ ps2 = {{s2_prefix}}_AS_STRING(s2);
1588
+
1589
+ #else
1590
+
1591
+ char *ps1, *ps2;
1592
+ Py_ssize_t length, length2;
1593
+
1594
+ {{if s1_type == 'bytes'}}
1595
+ if (unlikely(PyBytes_AsStringAndSize(s1, &ps1, &length) == -1)) {{return_error}};
1596
+ {{else}}
1597
+ ps1 = __Pyx_PyByteArray_AsString(s1); if (unlikely(!ps1)) {{return_error}};
1598
+ length = __Pyx_PyByteArray_GET_SIZE(s1); if (unlikely(length == -1)) {{return_error}};
1599
+ {{endif}}
1600
+
1601
+ {{if s2_type == 'bytes'}}
1602
+ if (unlikely(PyBytes_AsStringAndSize(s2, &ps2, &length2) == -1)) {{return_error}};
1603
+ {{else}}
1604
+ ps2 = __Pyx_PyByteArray_AsString(s2); if (unlikely(!ps2)) {{return_error}};
1605
+ length2 = __Pyx_PyByteArray_GET_SIZE(s2); if (unlikely(length2 == -1)) {{return_error}};
1606
+ {{endif}}
1607
+
1608
+ if (length != length2) {{return_false if op == 'Eq' else return_true}};
1609
+
1610
+ #endif
1611
+
1612
+ // len(s1) == len(s2)
1613
+ {{if s1_type == 'bytearray'}}
1614
+ if (length == 0) {{return_true if op == 'Eq' else return_false}};
1615
+ {{else}}
1616
+ // bytes: length >= 1 (empty bytes is singleton, and "s1 is not s2")
1617
+ {{endif}}
1618
+
1619
+ if (ps1[0] != ps2[0]) {{return_false if op == 'Eq' else return_true}};
1620
+ if (length == 1) {{return_true if op == 'Eq' else return_false}};
1621
+
1622
+ {
1623
+ int cmp;
1624
+ {{if s1_type == 'bytes' and s2_type == 'bytes'}}
1625
+ #if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000)
1626
+ Py_hash_t hash1 = ((PyBytesObject*)s1)->ob_shash;
1627
+ Py_hash_t hash2 = ((PyBytesObject*)s2)->ob_shash;
1628
+ if (hash1 != hash2 && hash1 != -1 && hash2 != -1) {{return_false if op == 'Eq' else return_true}};
1629
+ #endif
1630
+ {{endif}}
1631
+ cmp = memcmp(ps1, ps2, (size_t)length);
1632
+ if (cmp {{c_op}} 0) {{return_true}}; else {{return_false}};
1633
+ }
1634
+
1635
+ __pyx_return_true:
1636
+ {{'Py_RETURN_TRUE' if return_obj else 'return 1'}};
1637
+ __pyx_return_false:
1638
+ {{'Py_RETURN_FALSE' if return_obj else 'return 0'}};
1639
+ }
1640
+
1641
+ {{else}}
1642
+ // !EqNe
1643
+
1644
+ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyObject_Compare{{s1_prefix}}{{s2_prefix}}{{func_suffix}}(PyObject* s1, PyObject* s2) {
1645
+ Py_ssize_t cmp;
1646
+ Py_ssize_t length1, length2, short_length;
1647
+
1648
+ #if CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS
1649
+ const char *ps1, *ps2;
1650
+ length1 = __Pyx_{{s1_prefix}}_GET_SIZE(s1);
1651
+ length2 = __Pyx_{{s2_prefix}}_GET_SIZE(s2);
1652
+
1653
+ short_length = (length1 < length2) ? length1 : length2;
1654
+ if (short_length == 0) {
1655
+ if (length1 == 0) {{return_true if op in 'LtLe' else return_false}}; else {{return_false if op in 'LtLe' else return_true}};
1656
+ }
1657
+
1658
+ ps1 = {{s1_prefix}}_AS_STRING(s1);
1659
+ ps2 = {{s2_prefix}}_AS_STRING(s2);
1660
+
1661
+ #else
1662
+ char *ps1, *ps2;
1663
+
1664
+ {{if s1_type == 'bytes'}}
1665
+ if (unlikely(PyBytes_AsStringAndSize(s1, &ps1, &length1) == -1)) {{return_error}};
1666
+ {{else}}
1667
+ ps1 = __Pyx_PyByteArray_AsString(s1); if (unlikely(!ps1)) {{return_error}};
1668
+ length1 = __Pyx_PyByteArray_GET_SIZE(s1); if (unlikely(length1 == -1)) {{return_error}};
1669
+ {{endif}}
1670
+
1671
+ {{if s2_type == 'bytes'}}
1672
+ if (unlikely(PyBytes_AsStringAndSize(s2, &ps2, &length2) == -1)) {{return_error}};
1673
+ {{else}}
1674
+ ps2 = __Pyx_PyByteArray_AsString(s2); if (unlikely(!ps2)) {{return_error}};
1675
+ length2 = __Pyx_PyByteArray_GET_SIZE(s2); if (unlikely(length2 == -1)) {{return_error}};
1676
+ {{endif}}
1677
+
1678
+ short_length = (length1 < length2) ? length1 : length2;
1679
+ if (short_length == 0) {
1680
+ if (length1 == 0) {{return_true if op in 'LtLe' else return_false}}; else {{return_false if op in 'LtLe' else return_true}};
1681
+ }
1682
+ #endif
1683
+
1684
+ cmp = (Py_ssize_t) ((const unsigned char*) ps1)[0] - (Py_ssize_t) ((const unsigned char*) ps2)[0];
1685
+ if (cmp == 0 && short_length > 1) {
1686
+ cmp = memcmp(ps1, ps2, (size_t)short_length);
1687
+ }
1688
+ if (cmp == 0) cmp = (length1 - length2);
1689
+ if (cmp {{c_op}} 0) {{return_true}}; else {{return_false}};
1690
+
1691
+ __pyx_return_true:
1692
+ {{'Py_RETURN_TRUE' if return_obj else 'return 1'}};
1693
+ __pyx_return_false:
1694
+ {{'Py_RETURN_FALSE' if return_obj else 'return 0'}};
1695
+ }
1696
+ {{endif}}
1697
+
1698
+ // End of bytes/bytearray comparisons.
1699
+ #endif
1700
+ #endif
1701
+ {{endif}}
1702
+
1703
+ {{endfor}}
1704
+ {{endfor}}
1705
+
1706
+ // float/int comparisons
1707
+
1708
+ {{if type1 in ('object', 'float') and type2 in ('object', 'int')}}
1709
+ // Less likely, non-inlined comparison of float and int.
1710
+ #ifndef __Pyx_DEFINED_PyObject_CompareFloatInt{{func_suffix}}
1711
+ #define __Pyx_DEFINED_PyObject_CompareFloatInt{{func_suffix}}
1712
+ static {{c_ret_type}} __Pyx_PyObject_CompareFloatInt{{func_suffix}}(PyObject *op1, PyObject *op2) {
1713
+ double float_op1 = __Pyx_PyFloat_AS_DOUBLE(op1);
1714
+ #if !CYTHON_ASSUME_SAFE_MACROS
1715
+ if (unlikely(float_op1 == -1. && PyErr_Occurred())) {{return_error}};
1716
+ #endif
1717
+
1718
+ #if CYTHON_USE_PYLONG_INTERNALS
1719
+ if (__Pyx_PyLong_IsCompact(op2)) {
1720
+ Py_ssize_t iop2 = __Pyx_PyLong_CompactValue(op2);
1721
+ if (float_op1 {{c_op}} ((double)iop2)) {{return_true}}; else {{return_false}};
1722
+ }
1723
+ if (unlikely(!isfinite(float_op1))) {
1724
+ // CPython just compares inf/nan to 0.0
1725
+ if (float_op1 {{c_op}} 0.0) {{return_true}}; else {{return_false}};
1726
+ } else {
1727
+ // op2 != 0 (which would be compact)
1728
+ int sign2 = __Pyx_PyLong_Sign(op2);
1729
+ if (float_op1 >= 0.) {
1730
+ if (sign2 < 0) {{return_true if op in 'NeGeGt' else return_false}};
1731
+ // same sign - is float value compact while PyLong is not?
1732
+ if (float_op1 < (double) (1L << PyLong_SHIFT)) {{return_true if op in 'NeLeLt' else return_false}};
1733
+ } else {
1734
+ if (sign2 > 0) {{return_true if op in 'NeLeLt' else return_false}};
1735
+ // same sign - is float value compact while PyLong is not?
1736
+ if (float_op1 > -(double) (1L << PyLong_SHIFT)) {{return_false if op in 'EqLeLt' else return_true}};
1737
+ }
1738
+ }
1739
+ #else
1740
+ if (unlikely(!isfinite(float_op1))) {
1741
+ // CPython just compares inf/nan to 0.0
1742
+ if (float_op1 {{c_op}} 0.0) {{return_true}}; else {{return_false}};
1743
+ } else {
1744
+ int overflow2;
1745
+ // We know that we have an exact PyLong value, so we assume no exceptions.
1746
+ long iop2 = PyLong_AsLongAndOverflow(op2, &overflow2);
1747
+ if (likely(!overflow2)) {
1748
+ if ((long long) iop2 >= (1LL << 53)) {
1749
+ overflow2 = 1;
1750
+ } else if ((long long) iop2 <= - (1LL << 53)) {
1751
+ overflow2 = -1;
1752
+ } else {
1753
+ if (float_op1 {{c_op}} ((double) iop2)) {{return_true}}; else {{return_false}};
1754
+ }
1755
+ }
1756
+ if (overflow2 > 0) {
1757
+ if (float_op1 < ((double) (1LL << 53))) {{return_true if op in 'NeLeLt' else return_false}};
1758
+ } else {
1759
+ if (float_op1 > - ((double) (1LL << 53))) {{return_true if op in 'NeGeGt' else return_false}};
1760
+ }
1761
+ }
1762
+ #endif
1763
+
1764
+ return {{'PyObject_RichCompare' if return_obj else '__Pyx_PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}});
1765
+
1766
+ __pyx_return_true:
1767
+ {{'Py_RETURN_TRUE' if return_obj else 'return 1'}};
1768
+ __pyx_return_false:
1769
+ {{'Py_RETURN_FALSE' if return_obj else 'return 0'}};
1770
+ }
1771
+ #endif
1772
+ {{endif}}
1773
+
1774
+ {{if type1 in ('object', 'int') and type2 in ('object', 'float')}}
1775
+ // Less likely, non-inlined comparison of int and float.
1776
+ #ifndef __Pyx_DEFINED_PyObject_CompareIntFloat{{func_suffix}}
1777
+ #define __Pyx_DEFINED_PyObject_CompareIntFloat{{func_suffix}}
1778
+ static {{c_ret_type}} __Pyx_PyObject_CompareIntFloat{{func_suffix}}(PyObject *op1, PyObject *op2) {
1779
+ double float_op2 = __Pyx_PyFloat_AS_DOUBLE(op2);
1780
+ #if !CYTHON_ASSUME_SAFE_MACROS
1781
+ if (unlikely(float_op2 == -1. && PyErr_Occurred())) {{return_error}};
1782
+ #endif
1783
+
1784
+ #if CYTHON_USE_PYLONG_INTERNALS
1785
+ if (__Pyx_PyLong_IsCompact(op1)) {
1786
+ Py_ssize_t iop1 = __Pyx_PyLong_CompactValue(op1);
1787
+ if (((double)iop1) {{c_op}} float_op2) {{return_true}}; else {{return_false}};
1788
+ }
1789
+ if (unlikely(!isfinite(float_op2))) {
1790
+ // CPython just compares inf/nan to 0.0
1791
+ if (0.0 {{c_op}} float_op2) {{return_true}}; else {{return_false}};
1792
+ } else {
1793
+ // op1 != 0 (which would be compact)
1794
+ int sign1 = __Pyx_PyLong_Sign(op1);
1795
+ if (float_op2 >= 0.) {
1796
+ if (sign1 < 0) {{return_true if op in 'NeLeLt' else return_false}};
1797
+ // same sign - is float value compact while PyLong is not?
1798
+ if (float_op2 < (double) (1L << PyLong_SHIFT)) {{return_true if op in 'NeGeGt' else return_false}};
1799
+ } else {
1800
+ if (sign1 > 0) {{return_true if op in 'NeGeGt' else return_false}};
1801
+ // same sign - is float value compact while PyLong is not?
1802
+ if (float_op2 > -(double) (1L << PyLong_SHIFT)) {{return_false if op in 'EqGeGt' else return_true}};
1803
+ }
1804
+ }
1805
+ #else
1806
+ if (unlikely(!isfinite(float_op2))) {
1807
+ // CPython just compares inf/nan to 0.0
1808
+ if (0.0 {{c_op}} float_op2) {{return_true}}; else {{return_false}};
1809
+ } else {
1810
+ int overflow1;
1811
+ // We know that we have an exact PyLong value, so we assume no exceptions.
1812
+ long iop1 = PyLong_AsLongAndOverflow(op1, &overflow1);
1813
+ if (likely(!overflow1)) {
1814
+ if ((long long) iop1 >= (1LL << 53)) {
1815
+ overflow1 = 1;
1816
+ } else if ((long long) iop1 <= - (1LL << 53)) {
1817
+ overflow1 = -1;
1818
+ } else {
1819
+ if (((double) iop1) {{c_op}} float_op2) {{return_true}}; else {{return_false}};
1820
+ }
1821
+ }
1822
+ if (overflow1 < 0) {
1823
+ if (float_op2 > ((double) (1LL << 53))) {{return_true if op in 'NeLeLt' else return_false}};
1824
+ } else {
1825
+ if (float_op2 < - ((double) (1LL << 53))) {{return_true if op in 'NeGeGt' else return_false}};
1826
+ }
1827
+ }
1828
+ #endif
1829
+
1830
+ return {{'PyObject_RichCompare' if return_obj else '__Pyx_PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}});
1831
+
1832
+ __pyx_return_true:
1833
+ {{'Py_RETURN_TRUE' if return_obj else 'return 1'}};
1834
+ __pyx_return_false:
1835
+ {{'Py_RETURN_FALSE' if return_obj else 'return 0'}};
1836
+ }
1837
+ #endif
1838
+ {{endif}}
1839
+
1840
+ {{if type1 in ('object', 'int') and type2 in ('object', 'int')}}
1841
+ {{py: from Cython.Utility import pylong_join }}
1842
+
1843
+ #ifndef __Pyx_DEFINED_PyObject_CompareIntInt{{func_suffix}}
1844
+ #define __Pyx_DEFINED_PyObject_CompareIntInt{{func_suffix}}
1845
+ static {{c_ret_type}} __Pyx_PyObject_CompareIntInt{{func_suffix}}(PyObject *op1, PyObject *op2) {
1846
+ #if CYTHON_USE_PYLONG_INTERNALS
1847
+ Py_ssize_t cmp = __Pyx_PyLong_CompareSignAndSize(op1, op2);
1848
+ if (cmp == 0) {
1849
+ Py_ssize_t size = __Pyx_PyLong_DigitCount(op1);
1850
+ if (size > 0) {
1851
+ const digit* digits1 = __Pyx_PyLong_Digits(op1);
1852
+ const digit* digits2 = __Pyx_PyLong_Digits(op2);
1853
+ if (size == 1) {
1854
+ cmp = (Py_ssize_t) digits1[0] - (Py_ssize_t) digits2[0];
1855
+ } else if ((size == 2) && (8 * sizeof(Py_ssize_t) >= 2 * PyLong_SHIFT)) {
1856
+ cmp = (Py_ssize_t) {{pylong_join(2, 'digits1', 'size_t')}} - (Py_ssize_t) {{pylong_join(2, 'digits2', 'size_t')}};
1857
+ } else {
1858
+ for (Py_ssize_t i=size-1; i >= 0 && !cmp; --i) {
1859
+ cmp = (Py_ssize_t) digits1[i] - (Py_ssize_t) digits2[i];
1860
+ }
1861
+ }
1862
+ }
1863
+ if (cmp == 0) {{return_true if op in 'EqLeGe' else return_false}};
1864
+ if (__Pyx_PyLong_IsNeg(op1)) cmp = -cmp;
1865
+ }
1866
+
1867
+ {{if op == 'Eq'}}
1868
+ {{return_false}};
1869
+ {{elif op == 'Ne'}}
1870
+ {{return_true}};
1871
+ {{else}}
1872
+ if (cmp < 0) {{return_true if op in 'LeLt' else return_false}}; else {{return_false if op in 'LeLt' else return_true}};
1873
+ {{endif}}
1874
+
1875
+ #else
1876
+ int overflow1, overflow2;
1877
+ // We know that we have two exact PyLong values, so we assume no exceptions.
1878
+ long long iop1 = PyLong_AsLongLongAndOverflow(op1, &overflow1);
1879
+ long long iop2 = PyLong_AsLongLongAndOverflow(op2, &overflow2);
1880
+ if (likely(!(overflow1 | overflow2))) {
1881
+ if (iop1 {{c_op}} iop2) {{return_true}}; else {{return_false}};
1882
+ } else if (overflow1 != overflow2) {
1883
+ if (overflow1 {{c_op}} overflow2) {{return_true}}; else {{return_false}};
1884
+ } else {
1885
+ return {{'PyObject_RichCompare' if return_obj else '__Pyx_PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}});
1886
+ }
1887
+ #endif
1888
+
1889
+ __pyx_return_true:
1890
+ {{'Py_RETURN_TRUE' if return_obj else 'return 1'}};
1891
+ __pyx_return_false:
1892
+ {{'Py_RETURN_FALSE' if return_obj else 'return 0'}};
1893
+ }
1894
+ #endif
1895
+
1896
+ // end of float/int comparisons
1897
+ {{endif}}
1898
+
1899
+ // main comparison function
1900
+
1901
+ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyObject_Compare{{func_suffix}}_{{type1}}_{{type2}}(PyObject *op1, PyObject *op2, int pyop) {
1902
+ CYTHON_UNUSED_VAR(pyop);
1903
+
1904
+ {{if type1 != 'object'}}
1905
+ // For concrete types, the whole rest simplifies a lot if we handle None up front.
1906
+ if (unlikely(op1 == Py_None)) {
1907
+ {{if op == 'Eq'}}
1908
+ if (op2 == Py_None) {{return_true}}; else {{if type2 != 'object'}}{{return_false}}{{else}}goto __pyx_richcmp{{endif}};
1909
+ {{elif op == 'Ne'}}
1910
+ if (op2 == Py_None) {{return_false}}; else {{if type2 != 'object'}}{{return_true}}{{else}}goto __pyx_richcmp{{endif}};
1911
+ {{else}}
1912
+ goto __pyx_richcmp;
1913
+ {{endif}}
1914
+ }
1915
+ {{endif}}
1916
+ {{if type2 != 'object'}}
1917
+ if (unlikely(op2 == Py_None)) {
1918
+ {{if op == 'Eq'}}
1919
+ if (op1 == Py_None) {{return_true}}; else {{if type1 != 'object'}}{{return_false}}{{else}}goto __pyx_richcmp{{endif}};
1920
+ {{elif op == 'Ne'}}
1921
+ if (op1 == Py_None) {{return_false}}; else {{if type1 != 'object'}}{{return_true}}{{else}}goto __pyx_richcmp{{endif}};
1922
+ {{else}}
1923
+ goto __pyx_richcmp;
1924
+ {{endif}}
1925
+ }
1926
+ {{endif}}
1927
+
1928
+ {{if (type1 == 'int' or type2 == 'int') and (type1 != 'float' and type2 != 'float')}}
1929
+ if (op1 == op2) {{return_true if op in 'EqLeGe' else return_false}};
1930
+ {{endif}}
1931
+
1932
+ {{if type1 in ('object', 'float')}}
1933
+ if ({{is_type('op1', 'float')}}) {
1934
+ {{if type2 in ('object', 'float')}}
1935
+ if ({{is_type('op2', 'float')}}) {
1936
+ double float_op1 = __Pyx_PyFloat_AS_DOUBLE(op1);
1937
+ #if !CYTHON_ASSUME_SAFE_MACROS
1938
+ if (unlikely(float_op1 == -1. && PyErr_Occurred())) {{return_error}};
1939
+ #endif
1940
+ double float_op2 = __Pyx_PyFloat_AS_DOUBLE(op2);
1941
+ #if !CYTHON_ASSUME_SAFE_MACROS
1942
+ if (unlikely(float_op2 == -1. && PyErr_Occurred())) {{return_error}};
1943
+ #endif
1944
+ if (float_op1 {{c_op}} float_op2) {{return_true}}; else {{return_false}};
1945
+ }
1946
+ {{endif}}
1947
+
1948
+ {{if type2 in ('object', 'int')}}
1949
+ if ({{is_type('op2', 'int')}}) {
1950
+ return __Pyx_PyObject_CompareFloatInt{{func_suffix}}(op1, op2);
1951
+ }
1952
+ {{endif}}
1953
+
1954
+ goto __pyx_richcmp;
1955
+ }
1956
+ {{endif}}
1957
+
1958
+ {{if type1 in ('object', 'int')}}
1959
+ if ({{is_type('op1', 'int')}}) {
1960
+ if (op1 == op2) {{return_true if op in 'EqLeGe' else return_false}};
1961
+
1962
+ {{if type2 in ('object', 'int')}}
1963
+ if ({{is_type('op2', 'int')}}) {
1964
+ return __Pyx_PyObject_CompareIntInt{{func_suffix}}(op1, op2);
1965
+ }
1966
+ {{endif}}
1967
+
1968
+ {{if type2 in ('object', 'float')}}
1969
+ if ({{is_type('op2', 'float')}}) {
1970
+ return __Pyx_PyObject_CompareIntFloat{{func_suffix}}(op1, op2);
1971
+ }
1972
+ {{endif}}
1973
+
1974
+ goto __pyx_richcmp;
1975
+ }
1976
+ {{endif}}
1977
+
1978
+ {{for string_type in ('str', 'bytes', 'bytearray')}}
1979
+ {{if type1 in ('object', string_type) and type2 in ('object', string_type)}}
1980
+
1981
+ {{if string_type != 'str'}}#if !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_GRAAL){{endif}}
1982
+ if ({{is_type('op1', string_type)}}) {
1983
+ // Catch interned and identical strings as well as the empty string.
1984
+ if (op1 == op2) {{return_true if op in 'EqLeGe' else return_false}};
1985
+
1986
+ if ({{is_type('op2', string_type)}}) {
1987
+ {{if string_type == 'bytes'}}
1988
+ return __Pyx_PyObject_ComparePyBytesPyBytes{{func_suffix}}(op1, op2);
1989
+ {{elif string_type == 'bytearray'}}
1990
+ return __Pyx_PyObject_ComparePyByteArrayPyByteArray{{func_suffix}}(op1, op2);
1991
+ {{else}}
1992
+ return __Pyx_PyObject_CompareStrStr{{func_suffix}}(op1, op2);
1993
+ {{endif}}
1994
+ }
1995
+
1996
+ {{if string_type == 'bytes' and type2 in ('object', 'bytearray')}}
1997
+ if ({{is_type('op2', 'bytearray')}}) {
1998
+ return __Pyx_PyObject_ComparePyBytesPyByteArray{{func_suffix}}(op1, op2);
1999
+ }
2000
+ {{elif string_type == 'bytearray' and type2 in ('object', 'bytes')}}
2001
+ if ({{is_type('op2', 'bytes')}}) {
2002
+ return __Pyx_PyObject_ComparePyByteArrayPyBytes{{func_suffix}}(op1, op2);
2003
+ }
2004
+ {{endif}}
2005
+
2006
+ goto __pyx_richcmp;
2007
+ }
2008
+ {{if string_type != 'str'}}#endif{{endif}}
2009
+
2010
+ {{endif}}
2011
+ {{endfor}}
2012
+
2013
+ // avoid unused labels
2014
+ if ((0)) goto __pyx_richcmp;
2015
+ if ((0)) {{return_true}};
2016
+ if ((0)) {{return_false}};
2017
+
2018
+ __pyx_richcmp:
2019
+ return {{'PyObject_RichCompare' if return_obj else '__Pyx_PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}});
2020
+
2021
+ __pyx_return_true:
2022
+ {{'Py_RETURN_TRUE' if return_obj else 'return 1'}};
2023
+ __pyx_return_false:
2024
+ {{'Py_RETURN_FALSE' if return_obj else 'return 0'}};
2025
+ }
2026
+
2027
+
2028
+ /////////////// PyLongCompare.proto ///////////////
2029
+
2030
+ {{py: c_ret_type = 'PyObject*' if ret_type.is_pyobject else 'int'}}
2031
+ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyLong_{{'' if ret_type.is_pyobject else 'Bool'}}{{op}}{{order}}(PyObject *op1, PyObject *op2, long intval, long inplace); /*proto*/
2032
+
2033
+ /////////////// PyLongCompare ///////////////
2034
+
2035
+ {{py: pyval, ival = ('op2', 'b') if order == 'CObj' else ('op1', 'a') }}
2036
+ {{py: c_ret_type = 'PyObject*' if ret_type.is_pyobject else 'int'}}
2037
+ {{py: return_true = 'Py_RETURN_TRUE' if ret_type.is_pyobject else 'return 1'}}
2038
+ {{py: return_false = 'Py_RETURN_FALSE' if ret_type.is_pyobject else 'return 0'}}
2039
+ {{py: slot_name = op.lower() }}
2040
+ {{py: c_op = {'Eq': '==', 'Ne': '!='}[op] }}
2041
+ {{py:
2042
+ return_compare = (
2043
+ (lambda a,b,c_op, return_true=return_true, return_false=return_false: "if ({a} {c_op} {b}) {return_true}; else {return_false};".format(
2044
+ a=a, b=b, c_op=c_op, return_true=return_true, return_false=return_false))
2045
+ if ret_type.is_pyobject else
2046
+ (lambda a,b,c_op: "return ({a} {c_op} {b});".format(a=a, b=b, c_op=c_op))
2047
+ )
2048
+ }}
2049
+
2050
+ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyLong_{{'' if ret_type.is_pyobject else 'Bool'}}{{op}}{{order}}(PyObject *op1, PyObject *op2, long intval, long inplace) {
2051
+ CYTHON_MAYBE_UNUSED_VAR(intval);
2052
+ CYTHON_UNUSED_VAR(inplace);
2053
+ if (op1 == op2) {
2054
+ {{return_true if op == 'Eq' else return_false}};
2055
+ }
2056
+
2057
+ #if CYTHON_USE_PYLONG_INTERNALS
2058
+ if (likely(PyLong_CheckExact({{pyval}}))) {
2059
+ int unequal;
2060
+ unsigned long uintval;
2061
+ Py_ssize_t size = __Pyx_PyLong_DigitCount({{pyval}});
2062
+ const digit* digits = __Pyx_PyLong_Digits({{pyval}});
2063
+ if (intval == 0) {
2064
+ {{return_compare('__Pyx_PyLong_IsZero(%s)' % pyval, '1', c_op)}}
2065
+ } else if (intval < 0) {
2066
+ if (__Pyx_PyLong_IsNonNeg({{pyval}}))
2067
+ {{return_false if op == 'Eq' else return_true}};
2068
+ // both are negative => can use absolute values now.
2069
+ intval = -intval;
2070
+ } else {
2071
+ // > 0 => Py_SIZE(pyval) > 0
2072
+ if (__Pyx_PyLong_IsNeg({{pyval}}))
2073
+ {{return_false if op == 'Eq' else return_true}};
2074
+ }
2075
+ // After checking that the sign is the same (and excluding 0), now compare the absolute values.
2076
+ // When inlining, the C compiler should select exactly one line from this unrolled loop.
2077
+ uintval = (unsigned long) intval;
2078
+ {{for _size in range(4, 0, -1)}}
2079
+ #if PyLong_SHIFT * {{_size}} < SIZEOF_LONG*8
2080
+ if (uintval >> (PyLong_SHIFT * {{_size}})) {
2081
+ // The C integer value is between (PyLong_BASE ** _size) and MIN(PyLong_BASE ** _size, LONG_MAX).
2082
+ unequal = (size != {{_size+1}}) || (digits[0] != (uintval & (unsigned long) PyLong_MASK))
2083
+ {{for _i in range(1, _size+1)}} | (digits[{{_i}}] != ((uintval >> ({{_i}} * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)){{endfor}};
2084
+ } else
2085
+ #endif
2086
+ {{endfor}}
2087
+ unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK));
2088
+
2089
+ {{return_compare('unequal', '0', c_op)}}
2090
+ }
2091
+ #endif
2092
+
2093
+ if (PyFloat_CheckExact({{pyval}})) {
2094
+ const long {{'a' if order == 'CObj' else 'b'}} = intval;
2095
+ double {{ival}} = __Pyx_PyFloat_AS_DOUBLE({{pyval}});
2096
+ {{return_compare('(double)a', '(double)b', c_op)}}
2097
+ }
2098
+
2099
+ return {{'PyObject_RichCompare' if ret_type.is_pyobject else '__Pyx_PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}});
2100
+ }
2101
+
2102
+
2103
+ /////////////// PyLongBinop.proto ///////////////
2104
+
2105
+ {{py: c_ret_type = 'PyObject*' if ret_type.is_pyobject else 'int'}}
2106
+ #if !CYTHON_COMPILING_IN_PYPY
2107
+ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyLong_{{'' if ret_type.is_pyobject else 'Bool'}}{{op}}{{order}}(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check); /*proto*/
2108
+ #else
2109
+ #define __Pyx_PyLong_{{'' if ret_type.is_pyobject else 'Bool'}}{{op}}{{order}}(op1, op2, intval, inplace, zerodivision_check) \
2110
+ {{if op in ('Eq', 'Ne')}}{{'PyObject_RichCompare' if ret_type.is_pyobject else 'PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}})
2111
+ {{else}}(inplace ? PyNumber_InPlace{{op}}(op1, op2) : PyNumber_{{op}}(op1, op2))
2112
+ {{endif}}
2113
+ #endif
2114
+
2115
+ /////////////// PyLongBinop ///////////////
2116
+
2117
+ #if !CYTHON_COMPILING_IN_PYPY
2118
+ {{py: from Cython.Utility import pylong_join }}
2119
+ {{py: pyval, ival = ('op2', 'b') if order == 'CObj' else ('op1', 'a') }}
2120
+ {{py: c_ret_type = 'PyObject*' if ret_type.is_pyobject else 'int'}}
2121
+ {{py: return_true = 'Py_RETURN_TRUE' if ret_type.is_pyobject else 'return 1'}}
2122
+ {{py: return_false = 'Py_RETURN_FALSE' if ret_type.is_pyobject else 'return 0'}}
2123
+ {{py: slot_name = {'TrueDivide': 'true_divide', 'FloorDivide': 'floor_divide'}.get(op, op.lower()) }}
2124
+ {{py: cfunc_name = f"__Pyx_PyLong_{'' if ret_type.is_pyobject else 'Bool'}{op}{order}" }}
2125
+ {{py:
2126
+ c_op = {
2127
+ 'Add': '+', 'Subtract': '-', 'Multiply': '*', 'Remainder': '%', 'TrueDivide': '/', 'FloorDivide': '/',
2128
+ 'Or': '|', 'Xor': '^', 'And': '&', 'Rshift': '>>', 'Lshift': '<<',
2129
+ 'Eq': '==', 'Ne': '!=',
2130
+ }[op]
2131
+ }}
2132
+ {{py:
2133
+ def zerodiv_check(operand, optype='integer', _is_mod=op == 'Remainder', _needs_check=(order == 'CObj' and c_op in '%/')):
2134
+ return (((
2135
+ 'if (unlikely(zerodivision_check && ((%s) == 0))) {'
2136
+ ' PyErr_SetString(PyExc_ZeroDivisionError, "%s division%s by zero");'
2137
+ ' return NULL;'
2138
+ '}') % (operand, optype, ' or modulo' if _is_mod else '')
2139
+ ) if _needs_check else '')
2140
+ }}
2141
+
2142
+ static {{c_ret_type}} __Pyx_Fallback_{{cfunc_name}}(PyObject *op1, PyObject *op2, int inplace) {
2143
+ {{if op in ('Eq', 'Ne')}}
2144
+ CYTHON_UNUSED_VAR(inplace);
2145
+ return {{'PyObject_RichCompare' if ret_type.is_pyobject else '__Pyx_PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}});
2146
+ {{else}}
2147
+ return (inplace ? PyNumber_InPlace{{op}} : PyNumber_{{op}})(op1, op2);
2148
+ {{endif}}
2149
+ }
2150
+
2151
+ #if CYTHON_USE_PYLONG_INTERNALS
2152
+ {{if op == 'Lshift'}}
2153
+ #if __clang__ || __GNUC__
2154
+ // left-shift by more than the width of the number is undefined behaviour.
2155
+ // We do check it (and test that it gives the right answer though).
2156
+ __attribute__((no_sanitize("shift")))
2157
+ #endif
2158
+ {{endif}}
2159
+ static {{c_ret_type}} __Pyx_Unpacked_{{cfunc_name}}(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) {
2160
+ CYTHON_MAYBE_UNUSED_VAR(inplace);
2161
+ CYTHON_UNUSED_VAR(zerodivision_check);
2162
+
2163
+ const long {{'a' if order == 'CObj' else 'b'}} = intval;
2164
+ long {{ival}};
2165
+ {{if op not in ('Eq', 'Ne', 'TrueDivide')}}
2166
+ const PY_LONG_LONG ll{{'a' if order == 'CObj' else 'b'}} = intval;
2167
+ PY_LONG_LONG ll{{ival}};
2168
+ {{endif}}
2169
+ {{if op == 'Rshift' or op == 'Lshift'}}
2170
+ // shifting negative numbers is technically implementation defined on C, and
2171
+ // C++ before C++20. Most implementation do the right thing though so
2172
+ // special case ones we know are good.
2173
+ #if (defined(__cplusplus) && __cplusplus >= 202002L) \
2174
+ || (defined(__GNUC__) || (defined(__clang__))) && \
2175
+ (defined(__arm__) || defined(__x86_64__) || defined(__i386__)) \
2176
+ || (defined(_MSC_VER) && \
2177
+ (defined(_M_ARM) || defined(_M_AMD64) || defined(_M_IX86)))
2178
+ const int negative_shift_works = 1;
2179
+ #else
2180
+ const int negative_shift_works = 0;
2181
+ #endif
2182
+ {{endif}}
2183
+
2184
+ // special cases for 0: + - * % / // | ^ & >> <<
2185
+ if (unlikely(__Pyx_PyLong_IsZero({{pyval}}))) {
2186
+ {{if order == 'CObj' and c_op in '%/'}}
2187
+ // division by zero!
2188
+ {{zerodiv_check('0')}}
2189
+ {{elif order == 'CObj' and c_op in '+-|^>><<'}}
2190
+ // x == x+0 == x-0 == x|0 == x^0 == x>>0 == x<<0
2191
+ return __Pyx_NewRef(op1);
2192
+ {{elif order == 'CObj' and c_op in '*&'}}
2193
+ // 0 == x*0 == x&0
2194
+ return __Pyx_NewRef(op2);
2195
+ {{elif order == 'ObjC' and c_op in '+|^'}}
2196
+ // x == 0+x == 0|x == 0^x
2197
+ return __Pyx_NewRef(op2);
2198
+ {{elif order == 'ObjC' and c_op == '-'}}
2199
+ // -x == 0-x
2200
+ return PyLong_FromLong(-intval);
2201
+ {{elif order == 'ObjC' and (c_op in '*%&>><<' or op == 'FloorDivide')}}
2202
+ // 0 == 0*x == 0%x == 0&x == 0>>x == 0<<x == 0//x
2203
+ return __Pyx_NewRef(op1);
2204
+ {{endif}}
2205
+ }
2206
+
2207
+ // IsZero/IsPos/IsNeg are practically the same and can probably be decided almost for free.
2208
+ const int is_positive = __Pyx_PyLong_IsPos({{pyval}});
2209
+
2210
+ {{if c_op == '&'}}
2211
+ // special case for &-ing arbitrarily large numbers with known single digit operands
2212
+ if ((intval & PyLong_MASK) == intval) {
2213
+ // Calling PyLong_CompactValue() requires the PyLong value to be compact, we only need the last digit.
2214
+ long last_digit = (long) __Pyx_PyLong_Digits({{pyval}})[0];
2215
+ long result = intval & (likely(is_positive) ? last_digit : (PyLong_MASK - last_digit + 1));
2216
+ return PyLong_FromLong(result);
2217
+ }
2218
+ {{endif}}
2219
+
2220
+ // Handle most common case (fits into 'long') first to avoid indirect branch and optimise branch prediction.
2221
+ const digit* digits = __Pyx_PyLong_Digits({{pyval}});
2222
+ const Py_ssize_t size = __Pyx_PyLong_DigitCount({{pyval}});
2223
+ if (likely(size == 1)) {
2224
+ {{ival}} = (long) digits[0];
2225
+ if (!is_positive) {{ival}} *= -1;
2226
+ } else {
2227
+ {{for _size in range(2, 5)}}
2228
+ if (size == {{_size}} && 8 * sizeof(long) - 1 > {{_size}} * PyLong_SHIFT{{if c_op == '*'}}+30{{endif}}{{if op == 'TrueDivide'}} && {{_size-1}} * PyLong_SHIFT < 53{{endif}}) {
2229
+ {{ival}} = (long) {{pylong_join(_size, 'digits')}};
2230
+ if (!is_positive) {{ival}} *= -1;
2231
+ goto calculate_long;
2232
+ {{if op != 'TrueDivide'}}
2233
+ } else if (size == {{_size}} && 8 * sizeof(PY_LONG_LONG) - 1 > {{_size}} * PyLong_SHIFT{{if c_op == '*'}}+30{{endif}}) {
2234
+ ll{{ival}} = (PY_LONG_LONG) {{pylong_join(_size, 'digits', 'unsigned PY_LONG_LONG')}};
2235
+ if (!is_positive) ll{{ival}} *= -1;
2236
+ goto calculate_long_long;
2237
+ {{endif}}
2238
+ } else
2239
+ // size doesn't fit into a long or PY_LONG_LONG any more
2240
+ {{endfor}}
2241
+ {}
2242
+
2243
+ {{if op in ('Eq', 'Ne')}}
2244
+ #if PyLong_SHIFT < 30 && PyLong_SHIFT != 15
2245
+ // unusual setup - your fault
2246
+ return {{'' if ret_type.is_pyobject else '__Pyx_PyObject_IsTrueAndDecref'}}(
2247
+ PyLong_Type.tp_richcompare({{'op1, op2' if order == 'ObjC' else 'op2, op1'}}, Py_{{op.upper()}}));
2248
+ #else
2249
+ // too large for the long values we allow => definitely not equal
2250
+ {{return_false if op == 'Eq' else return_true}};
2251
+ #endif
2252
+ {{else}}
2253
+ return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
2254
+ {{endif}}
2255
+ }
2256
+
2257
+ calculate_long:
2258
+
2259
+ {{if op in ('Eq', 'Ne')}}
2260
+ if (a {{c_op}} b) {
2261
+ {{return_true}};
2262
+ } else {
2263
+ {{return_false}};
2264
+ }
2265
+ {{elif c_op == '*'}}
2266
+ // Multiplying a 'long' value with a <= 30 bits constant can give a 'long long' value.
2267
+ // Note that we constrain the bit count of the PyLong in the unpacking code above.
2268
+ CYTHON_UNUSED_VAR(a);
2269
+ CYTHON_UNUSED_VAR(b);
2270
+ ll{{ival}} = {{ival}};
2271
+ goto calculate_long_long;
2272
+ {{elif c_op == '%'}}
2273
+ {
2274
+ // see CMath.c :: ModInt utility code
2275
+ long x = a % b;
2276
+ x += ((x != 0) & ((x ^ b) < 0)) * b;
2277
+ return PyLong_FromLong(x);
2278
+ }
2279
+ {{elif op == 'TrueDivide'}}
2280
+ if ((8 * sizeof(long) <= 53 || likely(labs({{ival}}) <= ((PY_LONG_LONG)1 << 53)))
2281
+ || __Pyx_PyLong_DigitCount({{pyval}}) <= 52 / PyLong_SHIFT) {
2282
+ return PyFloat_FromDouble((double)a / (double)b);
2283
+ }
2284
+ return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2);
2285
+ {{elif op == 'FloorDivide'}}
2286
+ {
2287
+ long q, r;
2288
+ // see CMath.c :: DivInt utility code
2289
+ q = a / b;
2290
+ r = a - q*b;
2291
+ q -= ((r != 0) & ((r ^ b) < 0));
2292
+ return PyLong_FromLong(q);
2293
+ }
2294
+ {{else}}
2295
+ {{if op == 'Rshift' or op == 'Lshift'}}
2296
+ if ((!negative_shift_works) && unlikely(a < 0)) goto fallback;
2297
+ {{endif}}
2298
+
2299
+ {
2300
+ long x;
2301
+ {{if op == 'Rshift'}}
2302
+ if (unlikely(b >= (long) (sizeof(long)*8))) {
2303
+ x = (a < 0) ? -1 : 0;
2304
+ } else
2305
+ {{endif}}
2306
+ x = a {{c_op}} b;
2307
+
2308
+ {{if op == 'Lshift'}}
2309
+ if (unlikely(!(b < (long) (sizeof(long)*8) && a == x >> b)) && a) {
2310
+ ll{{ival}} = {{ival}};
2311
+ goto calculate_long_long;
2312
+ }
2313
+ {{endif}}
2314
+
2315
+ return PyLong_FromLong(x);
2316
+ }
2317
+ {{endif}}
2318
+
2319
+ {{if op != 'TrueDivide'}}
2320
+ calculate_long_long:
2321
+ {{if op == 'Eq'}}
2322
+ // One operand fits into a 30 bit 'long', the other doesn't => not equal.
2323
+ {{return_false}};
2324
+ {{elif op == 'Ne'}}
2325
+ // One operand fits into a 30 bit 'long', the other doesn't => not equal.
2326
+ {{return_true}};
2327
+ {{elif c_op == '%'}}
2328
+ {
2329
+ // see CMath.c :: ModInt utility code
2330
+ PY_LONG_LONG llx = lla % llb;
2331
+ llx += ((llx != 0) & ((llx ^ llb) < 0)) * llb;
2332
+ return PyLong_FromLongLong(llx);
2333
+ }
2334
+ {{elif op == 'FloorDivide'}}
2335
+ {
2336
+ PY_LONG_LONG q, r;
2337
+ // see CMath.c :: DivInt utility code
2338
+ q = lla / llb;
2339
+ r = lla - q*llb;
2340
+ q -= ((r != 0) & ((r ^ llb) < 0));
2341
+ return PyLong_FromLongLong(q);
2342
+ }
2343
+ {{else}}
2344
+ {{if op == 'LShift' or op == 'Rshift'}}
2345
+ if ((!negative_shift_works) && unlikely(lla < 0)) goto fallback;
2346
+ {{endif}}
2347
+
2348
+ {
2349
+ PY_LONG_LONG llx;
2350
+ {{if op == 'Rshift'}}
2351
+ if (unlikely(llb >= (long long) (sizeof(long long)*8))) {
2352
+ llx = (lla < 0) ? -1 : 0;
2353
+ } else
2354
+ {{endif}}
2355
+ llx = lla {{c_op}} llb;
2356
+
2357
+ {{if op == 'Lshift'}}
2358
+ if (unlikely(lla != llx >> llb)) goto fallback;
2359
+ {{endif}}
2360
+ return PyLong_FromLongLong(llx);
2361
+ }
2362
+ {{endif}}
2363
+
2364
+ {{if op == 'Lshift' or op == 'Rshift'}}
2365
+ fallback:
2366
+ return __Pyx_Fallback_{{cfunc_name}}(op1, op2, inplace);
2367
+ {{endif}}
2368
+
2369
+ {{endif}}{{# if op != 'TrueDivide' #}}
2370
+ }
2371
+ #endif
2372
+
2373
+ {{if c_op in '+-*' or op in ('TrueDivide', 'Eq', 'Ne')}}
2374
+ static {{c_ret_type}} __Pyx_Float_{{cfunc_name}}(PyObject *float_val, long intval, int zerodivision_check) {
2375
+ CYTHON_UNUSED_VAR(zerodivision_check);
2376
+
2377
+ const long {{'a' if order == 'CObj' else 'b'}} = intval;
2378
+ double {{ival}} = __Pyx_PyFloat_AS_DOUBLE(float_val);
2379
+ {{if op in ('Eq', 'Ne')}}
2380
+ if ((double)a {{c_op}} (double)b) {
2381
+ {{return_true}};
2382
+ } else {
2383
+ {{return_false}};
2384
+ }
2385
+ {{else}}
2386
+ double result;
2387
+ {{zerodiv_check('b', 'float')}}
2388
+ result = ((double)a) {{c_op}} (double)b;
2389
+ return PyFloat_FromDouble(result);
2390
+ {{endif}}
2391
+ }
2392
+ {{endif}}
2393
+
2394
+ static CYTHON_INLINE {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) {
2395
+ CYTHON_MAYBE_UNUSED_VAR(intval);
2396
+ CYTHON_UNUSED_VAR(zerodivision_check);
2397
+
2398
+ {{if op in ('Eq', 'Ne')}}
2399
+ if (op1 == op2) {
2400
+ {{return_true if op == 'Eq' else return_false}};
2401
+ }
2402
+ {{endif}}
2403
+
2404
+ #if CYTHON_USE_PYLONG_INTERNALS
2405
+ if (likely(PyLong_CheckExact({{pyval}}))) {
2406
+ return __Pyx_Unpacked_{{cfunc_name}}(op1, op2, intval, inplace, zerodivision_check);
2407
+ }
2408
+ #endif
2409
+
2410
+ {{if c_op in '+-*' or op in ('TrueDivide', 'Eq', 'Ne')}}
2411
+ if (PyFloat_CheckExact({{pyval}})) {
2412
+ return __Pyx_Float_{{cfunc_name}}({{pyval}}, intval, zerodivision_check);
2413
+ }
2414
+ {{endif}}
2415
+
2416
+ return __Pyx_Fallback_{{cfunc_name}}(op1, op2, inplace);
2417
+ }
2418
+ #endif /* !CYTHON_COMPILING_IN_PYPY */
2419
+
2420
+
2421
+ /////////////// PyFloatBinop.proto ///////////////
2422
+
2423
+ {{py: c_ret_type = 'PyObject*' if ret_type.is_pyobject else 'int'}}
2424
+ #if !CYTHON_COMPILING_IN_PYPY
2425
+ static {{c_ret_type}} __Pyx_PyFloat_{{'' if ret_type.is_pyobject else 'Bool'}}{{op}}{{order}}(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check); /*proto*/
2426
+ #else
2427
+ #define __Pyx_PyFloat_{{'' if ret_type.is_pyobject else 'Bool'}}{{op}}{{order}}(op1, op2, floatval, inplace, zerodivision_check) \
2428
+ {{if op in ('Eq', 'Ne')}}{{'PyObject_RichCompare' if ret_type.is_pyobject else 'PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}})
2429
+ {{elif op == 'Divide'}}((inplace ? __Pyx_PyNumber_InPlaceDivide(op1, op2) : __Pyx_PyNumber_Divide(op1, op2)))
2430
+ {{else}}(inplace ? PyNumber_InPlace{{op}}(op1, op2) : PyNumber_{{op}}(op1, op2))
2431
+ {{endif}}
2432
+ #endif
2433
+
2434
+ /////////////// PyFloatBinop ///////////////
2435
+
2436
+ #if !CYTHON_COMPILING_IN_PYPY
2437
+ {{py: from Cython.Utility import pylong_join }}
2438
+ {{py: c_ret_type = 'PyObject*' if ret_type.is_pyobject else 'int'}}
2439
+ {{py: return_true = 'Py_RETURN_TRUE' if ret_type.is_pyobject else 'return 1'}}
2440
+ {{py: return_false = 'Py_RETURN_FALSE' if ret_type.is_pyobject else 'return 0'}}
2441
+ {{py: pyval, fval = ('op2', 'b') if order == 'CObj' else ('op1', 'a') }}
2442
+ {{py: cfunc_name = '__Pyx_PyFloat_%s%s%s' % ('' if ret_type.is_pyobject else 'Bool', op, order) }}
2443
+ {{py:
2444
+ c_op = {
2445
+ 'Add': '+', 'Subtract': '-', 'TrueDivide': '/', 'Divide': '/', 'Remainder': '%',
2446
+ 'Eq': '==', 'Ne': '!=',
2447
+ }[op]
2448
+ }}
2449
+ {{py:
2450
+ def zerodiv_check(operand, _is_mod=op == 'Remainder', _needs_check=(order == 'CObj' and c_op in '%/')):
2451
+ return (((
2452
+ 'if (unlikely(zerodivision_check && ((%s) == 0.0))) {'
2453
+ ' PyErr_SetString(PyExc_ZeroDivisionError, "float division%s by zero");'
2454
+ ' return NULL;'
2455
+ '}') % (operand, ' or modulo' if _is_mod else '')
2456
+ ) if _needs_check else '')
2457
+ }}
2458
+
2459
+ static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, double floatval, int inplace, int zerodivision_check) {
2460
+ const double {{'a' if order == 'CObj' else 'b'}} = floatval;
2461
+ double {{fval}};
2462
+ CYTHON_UNUSED_VAR(inplace);
2463
+ CYTHON_UNUSED_VAR(zerodivision_check);
2464
+
2465
+ {{if op in ('Eq', 'Ne')}}
2466
+ if (op1 == op2) {
2467
+ {{return_true if op == 'Eq' else return_false}};
2468
+ }
2469
+ {{endif}}
2470
+
2471
+ if (likely(PyFloat_CheckExact({{pyval}}))) {
2472
+ {{fval}} = __Pyx_PyFloat_AS_DOUBLE({{pyval}});
2473
+ {{zerodiv_check(fval)}}
2474
+ } else
2475
+
2476
+ if (likely(PyLong_CheckExact({{pyval}}))) {
2477
+ #if CYTHON_USE_PYLONG_INTERNALS
2478
+ if (__Pyx_PyLong_IsZero({{pyval}})) {
2479
+ {{fval}} = 0.0;
2480
+ {{zerodiv_check(fval)}}
2481
+ goto digits_done;
2482
+ } else if (__Pyx_PyLong_IsCompact({{pyval}})) {
2483
+ {{fval}} = (double) __Pyx_PyLong_CompactValue({{pyval}});
2484
+ goto digits_done;
2485
+ } else {
2486
+ const digit* digits = __Pyx_PyLong_Digits({{pyval}});
2487
+ const Py_ssize_t size = __Pyx_PyLong_DigitCount({{pyval}});
2488
+ {{for _size in (2, 3, 4)}}
2489
+ if (size <= {{_size}} && (8 * sizeof(unsigned long) > {{_size}} * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || ({{_size-1}} * PyLong_SHIFT < 53)))) {
2490
+ {{fval}} = (double) {{pylong_join(_size, 'digits')}};
2491
+ // let CPython do its own float rounding from 2**53 on (max. consecutive integer in double float)
2492
+ if ((8 * sizeof(unsigned long) < 53) || ({{_size}} * PyLong_SHIFT < 53) || ({{fval}} < (double) ((PY_LONG_LONG)1 << 53))) {
2493
+ if (__Pyx_PyLong_IsNeg({{pyval}})) {{fval}} = -{{fval}};
2494
+ goto digits_done;
2495
+ }
2496
+ }
2497
+ // Fall through if size doesn't fit safely into a double anymore.
2498
+ // It may not be obvious that this is a safe fall-through given the "fval < 2**53"
2499
+ // check above. However, the number of digits that CPython uses for a given PyLong
2500
+ // value is minimal, and together with the "(size-1) * SHIFT < 53" check above,
2501
+ // this should make it safe.
2502
+ {{endfor}}
2503
+ }
2504
+ #endif
2505
+
2506
+ {{if op in ('Eq', 'Ne')}}
2507
+ {
2508
+ PyObject *res =
2509
+ #if CYTHON_USE_TYPE_SLOTS || __PYX_LIMITED_VERSION_HEX >= 0x030A0000
2510
+ // PyType_GetSlot only works on non-heap types from Python 3.10
2511
+ __Pyx_PyType_GetSlot((&PyFloat_Type), tp_richcompare, richcmpfunc)
2512
+ #else
2513
+ PyObject_RichCompare
2514
+ #endif
2515
+ ({{'op1, op2' if order == 'CObj' else 'op2, op1'}},
2516
+ Py_{{op.upper()}});
2517
+
2518
+ return {{if ret_type.is_pyobject}}res{{else}}__Pyx_PyObject_IsTrueAndDecref(res){{endif}};
2519
+ }
2520
+ {{else}}
2521
+ {{fval}} = PyLong_AsDouble({{pyval}});
2522
+ if (unlikely({{fval}} == -1.0 && PyErr_Occurred())) return NULL;
2523
+ {{if zerodiv_check(fval)}}
2524
+ #if !CYTHON_USE_PYLONG_INTERNALS
2525
+ {{zerodiv_check(fval)}}
2526
+ #endif
2527
+ {{endif}}
2528
+ {{endif}}
2529
+ } else {
2530
+ {{if op in ('Eq', 'Ne')}}
2531
+ return {{'PyObject_RichCompare' if ret_type.is_pyobject else '__Pyx_PyObject_RichCompareBool'}}(op1, op2, Py_{{op.upper()}});
2532
+ {{elif op == 'Divide'}}
2533
+ return (inplace ? __Pyx_PyNumber_InPlaceDivide(op1, op2) : __Pyx_PyNumber_Divide(op1, op2));
2534
+ {{else}}
2535
+ return (inplace ? PyNumber_InPlace{{op}} : PyNumber_{{op}})(op1, op2);
2536
+ {{endif}}
2537
+ }
2538
+
2539
+ #if CYTHON_USE_PYLONG_INTERNALS
2540
+ digits_done:;
2541
+ #endif
2542
+
2543
+ {{if op in ('Eq', 'Ne')}}
2544
+ if (a {{c_op}} b) {
2545
+ {{return_true}};
2546
+ } else {
2547
+ {{return_false}};
2548
+ }
2549
+ {{else}}
2550
+ double result;
2551
+ {{if c_op == '%'}}
2552
+ result = fmod(a, b);
2553
+ if (result)
2554
+ result += ((result < 0) ^ (b < 0)) * b;
2555
+ else
2556
+ result = copysign(0.0, b);
2557
+ {{else}}
2558
+ result = a {{c_op}} b;
2559
+ {{endif}}
2560
+ return PyFloat_FromDouble(result);
2561
+ {{endif}}
2562
+ }
2563
+ #endif