oxython 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. Cython/Build/BuildExecutable.py +156 -0
  2. Cython/Build/Cache.py +198 -0
  3. Cython/Build/Cythonize.py +349 -0
  4. Cython/Build/Dependencies.py +1320 -0
  5. Cython/Build/Distutils.py +1 -0
  6. Cython/Build/Inline.py +467 -0
  7. Cython/Build/IpythonMagic.py +559 -0
  8. Cython/Build/SharedModule.py +165 -0
  9. Cython/Build/Tests/TestCyCache.py +222 -0
  10. Cython/Build/Tests/TestCythonizeArgsParser.py +480 -0
  11. Cython/Build/Tests/TestDependencies.py +133 -0
  12. Cython/Build/Tests/TestInline.py +177 -0
  13. Cython/Build/Tests/TestIpythonMagic.py +303 -0
  14. Cython/Build/Tests/TestRecythonize.py +212 -0
  15. Cython/Build/Tests/TestStripLiterals.py +155 -0
  16. Cython/Build/Tests/__init__.py +1 -0
  17. Cython/Build/__init__.py +11 -0
  18. Cython/CodeWriter.py +825 -0
  19. Cython/Compiler/AnalysedTreeTransforms.py +97 -0
  20. Cython/Compiler/Annotate.py +328 -0
  21. Cython/Compiler/AutoDocTransforms.py +320 -0
  22. Cython/Compiler/Buffer.py +679 -0
  23. Cython/Compiler/Builtin.py +1102 -0
  24. Cython/Compiler/CmdLine.py +373 -0
  25. Cython/Compiler/Code.pxd +154 -0
  26. Cython/Compiler/Code.py +3760 -0
  27. Cython/Compiler/CodeGeneration.py +33 -0
  28. Cython/Compiler/CythonScope.py +208 -0
  29. Cython/Compiler/Dataclass.py +890 -0
  30. Cython/Compiler/DebugFlags.py +24 -0
  31. Cython/Compiler/Errors.py +310 -0
  32. Cython/Compiler/ExprNodes.py +16319 -0
  33. Cython/Compiler/FlowControl.pxd +112 -0
  34. Cython/Compiler/FlowControl.py +1575 -0
  35. Cython/Compiler/FusedNode.py +978 -0
  36. Cython/Compiler/Future.py +16 -0
  37. Cython/Compiler/Interpreter.py +57 -0
  38. Cython/Compiler/Lexicon.py +442 -0
  39. Cython/Compiler/LineTable.py +114 -0
  40. Cython/Compiler/Main.py +879 -0
  41. Cython/Compiler/MatchCaseNodes.py +2200 -0
  42. Cython/Compiler/MemoryView.py +930 -0
  43. Cython/Compiler/ModuleNode.py +4558 -0
  44. Cython/Compiler/Naming.py +370 -0
  45. Cython/Compiler/Nodes.py +11334 -0
  46. Cython/Compiler/Optimize.py +5563 -0
  47. Cython/Compiler/Options.py +841 -0
  48. Cython/Compiler/ParseTreeTransforms.pxd +80 -0
  49. Cython/Compiler/ParseTreeTransforms.py +4808 -0
  50. Cython/Compiler/Parsing.pxd +9 -0
  51. Cython/Compiler/Parsing.py +5442 -0
  52. Cython/Compiler/Pipeline.py +439 -0
  53. Cython/Compiler/PyrexTypes.py +6588 -0
  54. Cython/Compiler/Pythran.py +232 -0
  55. Cython/Compiler/Scanning.pxd +74 -0
  56. Cython/Compiler/Scanning.py +771 -0
  57. Cython/Compiler/StringEncoding.py +354 -0
  58. Cython/Compiler/Symtab.py +3122 -0
  59. Cython/Compiler/Tests/TestBuffer.py +105 -0
  60. Cython/Compiler/Tests/TestBuiltin.py +196 -0
  61. Cython/Compiler/Tests/TestCmdLine.py +652 -0
  62. Cython/Compiler/Tests/TestCode.py +145 -0
  63. Cython/Compiler/Tests/TestFlowControl.py +65 -0
  64. Cython/Compiler/Tests/TestGrammar.py +202 -0
  65. Cython/Compiler/Tests/TestMemView.py +71 -0
  66. Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
  67. Cython/Compiler/Tests/TestScanning.py +132 -0
  68. Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
  69. Cython/Compiler/Tests/TestStringEncoding.py +20 -0
  70. Cython/Compiler/Tests/TestTreeFragment.py +63 -0
  71. Cython/Compiler/Tests/TestTreePath.py +103 -0
  72. Cython/Compiler/Tests/TestTypes.py +119 -0
  73. Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
  74. Cython/Compiler/Tests/TestVisitor.py +119 -0
  75. Cython/Compiler/Tests/Utils.py +36 -0
  76. Cython/Compiler/Tests/__init__.py +1 -0
  77. Cython/Compiler/TreeFragment.py +279 -0
  78. Cython/Compiler/TreePath.py +303 -0
  79. Cython/Compiler/TypeInference.py +626 -0
  80. Cython/Compiler/TypeSlots.py +1330 -0
  81. Cython/Compiler/UFuncs.py +317 -0
  82. Cython/Compiler/UtilNodes.py +389 -0
  83. Cython/Compiler/UtilityCode.py +354 -0
  84. Cython/Compiler/Version.py +8 -0
  85. Cython/Compiler/Visitor.pxd +52 -0
  86. Cython/Compiler/Visitor.py +914 -0
  87. Cython/Compiler/__init__.py +1 -0
  88. Cython/Coverage.py +448 -0
  89. Cython/Debugger/Cygdb.py +214 -0
  90. Cython/Debugger/DebugWriter.py +82 -0
  91. Cython/Debugger/Tests/TestLibCython.py +280 -0
  92. Cython/Debugger/Tests/__init__.py +1 -0
  93. Cython/Debugger/Tests/cfuncs.c +8 -0
  94. Cython/Debugger/Tests/codefile +49 -0
  95. Cython/Debugger/Tests/test_libcython_in_gdb.py +580 -0
  96. Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
  97. Cython/Debugger/__init__.py +1 -0
  98. Cython/Debugger/libcython.py +1548 -0
  99. Cython/Debugger/libpython.py +2821 -0
  100. Cython/Debugging.py +20 -0
  101. Cython/Distutils/__init__.py +2 -0
  102. Cython/Distutils/build_ext.py +143 -0
  103. Cython/Distutils/extension.py +96 -0
  104. Cython/Distutils/old_build_ext.py +351 -0
  105. Cython/Includes/cpython/__init__.pxd +173 -0
  106. Cython/Includes/cpython/array.pxd +159 -0
  107. Cython/Includes/cpython/bool.pxd +37 -0
  108. Cython/Includes/cpython/buffer.pxd +112 -0
  109. Cython/Includes/cpython/bytearray.pxd +33 -0
  110. Cython/Includes/cpython/bytes.pxd +200 -0
  111. Cython/Includes/cpython/cellobject.pxd +35 -0
  112. Cython/Includes/cpython/ceval.pxd +8 -0
  113. Cython/Includes/cpython/codecs.pxd +121 -0
  114. Cython/Includes/cpython/complex.pxd +60 -0
  115. Cython/Includes/cpython/contextvars.pxd +145 -0
  116. Cython/Includes/cpython/conversion.pxd +36 -0
  117. Cython/Includes/cpython/datetime.pxd +395 -0
  118. Cython/Includes/cpython/descr.pxd +26 -0
  119. Cython/Includes/cpython/dict.pxd +268 -0
  120. Cython/Includes/cpython/exc.pxd +263 -0
  121. Cython/Includes/cpython/fileobject.pxd +57 -0
  122. Cython/Includes/cpython/float.pxd +56 -0
  123. Cython/Includes/cpython/frozendict.pxd +37 -0
  124. Cython/Includes/cpython/function.pxd +65 -0
  125. Cython/Includes/cpython/genobject.pxd +25 -0
  126. Cython/Includes/cpython/getargs.pxd +12 -0
  127. Cython/Includes/cpython/instance.pxd +25 -0
  128. Cython/Includes/cpython/iterator.pxd +36 -0
  129. Cython/Includes/cpython/iterobject.pxd +24 -0
  130. Cython/Includes/cpython/list.pxd +144 -0
  131. Cython/Includes/cpython/long.pxd +180 -0
  132. Cython/Includes/cpython/longintrepr.pxd +14 -0
  133. Cython/Includes/cpython/mapping.pxd +63 -0
  134. Cython/Includes/cpython/marshal.pxd +66 -0
  135. Cython/Includes/cpython/mem.pxd +120 -0
  136. Cython/Includes/cpython/memoryview.pxd +50 -0
  137. Cython/Includes/cpython/method.pxd +49 -0
  138. Cython/Includes/cpython/module.pxd +208 -0
  139. Cython/Includes/cpython/number.pxd +258 -0
  140. Cython/Includes/cpython/object.pxd +430 -0
  141. Cython/Includes/cpython/pycapsule.pxd +143 -0
  142. Cython/Includes/cpython/pylifecycle.pxd +68 -0
  143. Cython/Includes/cpython/pyport.pxd +8 -0
  144. Cython/Includes/cpython/pystate.pxd +95 -0
  145. Cython/Includes/cpython/pythread.pxd +53 -0
  146. Cython/Includes/cpython/ref.pxd +141 -0
  147. Cython/Includes/cpython/sentinel.pxd +17 -0
  148. Cython/Includes/cpython/sequence.pxd +134 -0
  149. Cython/Includes/cpython/set.pxd +119 -0
  150. Cython/Includes/cpython/slice.pxd +70 -0
  151. Cython/Includes/cpython/time.pxd +129 -0
  152. Cython/Includes/cpython/tuple.pxd +72 -0
  153. Cython/Includes/cpython/type.pxd +146 -0
  154. Cython/Includes/cpython/unicode.pxd +639 -0
  155. Cython/Includes/cpython/version.pxd +32 -0
  156. Cython/Includes/cpython/weakref.pxd +78 -0
  157. Cython/Includes/libc/__init__.pxd +1 -0
  158. Cython/Includes/libc/complex.pxd +35 -0
  159. Cython/Includes/libc/errno.pxd +127 -0
  160. Cython/Includes/libc/float.pxd +43 -0
  161. Cython/Includes/libc/limits.pxd +28 -0
  162. Cython/Includes/libc/locale.pxd +46 -0
  163. Cython/Includes/libc/math.pxd +209 -0
  164. Cython/Includes/libc/setjmp.pxd +10 -0
  165. Cython/Includes/libc/signal.pxd +64 -0
  166. Cython/Includes/libc/stdbool.pxd +5 -0
  167. Cython/Includes/libc/stddef.pxd +9 -0
  168. Cython/Includes/libc/stdint.pxd +105 -0
  169. Cython/Includes/libc/stdio.pxd +80 -0
  170. Cython/Includes/libc/stdlib.pxd +72 -0
  171. Cython/Includes/libc/string.pxd +50 -0
  172. Cython/Includes/libc/threads.pxd +234 -0
  173. Cython/Includes/libc/time.pxd +52 -0
  174. Cython/Includes/libcpp/__init__.pxd +4 -0
  175. Cython/Includes/libcpp/algorithm.pxd +320 -0
  176. Cython/Includes/libcpp/any.pxd +16 -0
  177. Cython/Includes/libcpp/atomic.pxd +59 -0
  178. Cython/Includes/libcpp/barrier.pxd +22 -0
  179. Cython/Includes/libcpp/bit.pxd +29 -0
  180. Cython/Includes/libcpp/cast.pxd +12 -0
  181. Cython/Includes/libcpp/cmath.pxd +518 -0
  182. Cython/Includes/libcpp/complex.pxd +106 -0
  183. Cython/Includes/libcpp/condition_variable.pxd +322 -0
  184. Cython/Includes/libcpp/deque.pxd +165 -0
  185. Cython/Includes/libcpp/exception.pxd +216 -0
  186. Cython/Includes/libcpp/execution.pxd +15 -0
  187. Cython/Includes/libcpp/forward_list.pxd +63 -0
  188. Cython/Includes/libcpp/functional.pxd +26 -0
  189. Cython/Includes/libcpp/future.pxd +103 -0
  190. Cython/Includes/libcpp/iterator.pxd +34 -0
  191. Cython/Includes/libcpp/latch.pxd +17 -0
  192. Cython/Includes/libcpp/limits.pxd +61 -0
  193. Cython/Includes/libcpp/list.pxd +117 -0
  194. Cython/Includes/libcpp/map.pxd +252 -0
  195. Cython/Includes/libcpp/memory.pxd +115 -0
  196. Cython/Includes/libcpp/mutex.pxd +387 -0
  197. Cython/Includes/libcpp/numbers.pxd +15 -0
  198. Cython/Includes/libcpp/numeric.pxd +131 -0
  199. Cython/Includes/libcpp/optional.pxd +34 -0
  200. Cython/Includes/libcpp/pair.pxd +1 -0
  201. Cython/Includes/libcpp/queue.pxd +25 -0
  202. Cython/Includes/libcpp/random.pxd +166 -0
  203. Cython/Includes/libcpp/semaphore.pxd +43 -0
  204. Cython/Includes/libcpp/set.pxd +228 -0
  205. Cython/Includes/libcpp/shared_mutex.pxd +96 -0
  206. Cython/Includes/libcpp/span.pxd +87 -0
  207. Cython/Includes/libcpp/stack.pxd +11 -0
  208. Cython/Includes/libcpp/stop_token.pxd +117 -0
  209. Cython/Includes/libcpp/string.pxd +355 -0
  210. Cython/Includes/libcpp/string_view.pxd +183 -0
  211. Cython/Includes/libcpp/typeindex.pxd +15 -0
  212. Cython/Includes/libcpp/typeinfo.pxd +10 -0
  213. Cython/Includes/libcpp/unordered_map.pxd +193 -0
  214. Cython/Includes/libcpp/unordered_set.pxd +152 -0
  215. Cython/Includes/libcpp/utility.pxd +30 -0
  216. Cython/Includes/libcpp/vector.pxd +186 -0
  217. Cython/Includes/numpy/math.pxd +150 -0
  218. Cython/Includes/openmp.pxd +50 -0
  219. Cython/Includes/posix/__init__.pxd +1 -0
  220. Cython/Includes/posix/dlfcn.pxd +14 -0
  221. Cython/Includes/posix/fcntl.pxd +86 -0
  222. Cython/Includes/posix/ioctl.pxd +4 -0
  223. Cython/Includes/posix/mman.pxd +101 -0
  224. Cython/Includes/posix/resource.pxd +57 -0
  225. Cython/Includes/posix/select.pxd +21 -0
  226. Cython/Includes/posix/signal.pxd +73 -0
  227. Cython/Includes/posix/stat.pxd +98 -0
  228. Cython/Includes/posix/stdio.pxd +37 -0
  229. Cython/Includes/posix/stdlib.pxd +29 -0
  230. Cython/Includes/posix/strings.pxd +9 -0
  231. Cython/Includes/posix/time.pxd +71 -0
  232. Cython/Includes/posix/types.pxd +30 -0
  233. Cython/Includes/posix/uio.pxd +26 -0
  234. Cython/Includes/posix/unistd.pxd +271 -0
  235. Cython/Includes/posix/wait.pxd +38 -0
  236. Cython/LZSS.py +184 -0
  237. Cython/Plex/Actions.pxd +24 -0
  238. Cython/Plex/Actions.py +119 -0
  239. Cython/Plex/DFA.pxd +14 -0
  240. Cython/Plex/DFA.py +164 -0
  241. Cython/Plex/Errors.py +48 -0
  242. Cython/Plex/Lexicons.py +178 -0
  243. Cython/Plex/Machines.pxd +36 -0
  244. Cython/Plex/Machines.py +238 -0
  245. Cython/Plex/Regexps.py +535 -0
  246. Cython/Plex/Scanners.pxd +45 -0
  247. Cython/Plex/Scanners.py +328 -0
  248. Cython/Plex/Transitions.pxd +14 -0
  249. Cython/Plex/Transitions.py +239 -0
  250. Cython/Plex/__init__.py +34 -0
  251. Cython/Runtime/__init__.py +1 -0
  252. Cython/Runtime/refnanny.pyx +237 -0
  253. Cython/Shadow.py +1172 -0
  254. Cython/StringIOTree.py +169 -0
  255. Cython/Tempita/__init__.py +4 -0
  256. Cython/Tempita/_looper.py +154 -0
  257. Cython/Tempita/_tempita.py +1087 -0
  258. Cython/TestUtils.py +472 -0
  259. Cython/Tests/TestCodeWriter.py +128 -0
  260. Cython/Tests/TestCythonUtils.py +237 -0
  261. Cython/Tests/TestJediTyper.py +223 -0
  262. Cython/Tests/TestShadow.py +125 -0
  263. Cython/Tests/TestStringIOTree.py +68 -0
  264. Cython/Tests/TestTestUtils.py +89 -0
  265. Cython/Tests/__init__.py +1 -0
  266. Cython/Tests/xmlrunner.py +390 -0
  267. Cython/Utility/AsyncGen.c +1152 -0
  268. Cython/Utility/Buffer.c +866 -0
  269. Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
  270. Cython/Utility/Builtins.c +1068 -0
  271. Cython/Utility/CConvert.pyx +153 -0
  272. Cython/Utility/CMath.c +104 -0
  273. Cython/Utility/CommonStructures.c +244 -0
  274. Cython/Utility/Complex.c +378 -0
  275. Cython/Utility/Coroutine.c +2344 -0
  276. Cython/Utility/CpdefEnums.pyx +119 -0
  277. Cython/Utility/CppConvert.pyx +284 -0
  278. Cython/Utility/CppSupport.cpp +151 -0
  279. Cython/Utility/CythonFunction.c +2143 -0
  280. Cython/Utility/Dataclasses.c +101 -0
  281. Cython/Utility/Embed.c +129 -0
  282. Cython/Utility/Exceptions.c +1331 -0
  283. Cython/Utility/Exceptions_Cy.pyx +109 -0
  284. Cython/Utility/ExtensionTypes.c +1199 -0
  285. Cython/Utility/FunctionArguments.c +1052 -0
  286. Cython/Utility/FusedFunction.pyx +44 -0
  287. Cython/Utility/ImportExport.c +972 -0
  288. Cython/Utility/MatchCase.c +985 -0
  289. Cython/Utility/MatchCase_Cy.pyx +12 -0
  290. Cython/Utility/MemoryView.pxd +108 -0
  291. Cython/Utility/MemoryView.pyx +1499 -0
  292. Cython/Utility/MemoryView_C.c +1056 -0
  293. Cython/Utility/ModuleSetupCode.c +3349 -0
  294. Cython/Utility/NumpyImportArray.c +46 -0
  295. Cython/Utility/ObjectHandling.c +3404 -0
  296. Cython/Utility/Optimize.c +2575 -0
  297. Cython/Utility/Overflow.c +378 -0
  298. Cython/Utility/Profile.c +736 -0
  299. Cython/Utility/StringTools.c +1534 -0
  300. Cython/Utility/Synchronization.c +438 -0
  301. Cython/Utility/TString.c +369 -0
  302. Cython/Utility/TestCyUtilityLoader.pyx +8 -0
  303. Cython/Utility/TestCythonScope.pyx +75 -0
  304. Cython/Utility/TestUtilityLoader.c +12 -0
  305. Cython/Utility/TypeConversion.c +1588 -0
  306. Cython/Utility/UFuncs.pyx +50 -0
  307. Cython/Utility/UFuncs_C.c +89 -0
  308. Cython/Utility/__init__.py +28 -0
  309. Cython/Utility/arrayarray.h +190 -0
  310. Cython/Utils.py +682 -0
  311. Cython/__init__.py +12 -0
  312. Cython/py.typed +0 -0
  313. cython.py +29 -0
  314. oxython-0.1.0.dist-info/METADATA +138 -0
  315. oxython-0.1.0.dist-info/RECORD +321 -0
  316. oxython-0.1.0.dist-info/WHEEL +5 -0
  317. oxython-0.1.0.dist-info/entry_points.txt +4 -0
  318. oxython-0.1.0.dist-info/top_level.txt +3 -0
  319. pyximport/__init__.py +4 -0
  320. pyximport/pyxbuild.py +160 -0
  321. pyximport/pyximport.py +482 -0
@@ -0,0 +1,1330 @@
1
+ #
2
+ # Tables describing slots in the CPython type object
3
+ # and associated know-how.
4
+ #
5
+
6
+
7
+ from . import Naming
8
+ from . import PyrexTypes
9
+ from .Errors import error, warn_once
10
+
11
+ import copy
12
+ import enum
13
+
14
+ invisible = ['__cinit__', '__dealloc__', '__richcmp__',
15
+ '__nonzero__', '__bool__']
16
+
17
+ richcmp_special_methods = ['__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__']
18
+
19
+
20
+ class Signature:
21
+ # Method slot signature descriptor.
22
+ #
23
+ # has_dummy_arg boolean
24
+ # has_generic_args boolean
25
+ # fixed_arg_format string
26
+ # ret_format string
27
+ # error_value string
28
+ # use_fastcall FastcallUsed enum
29
+ #
30
+ # The formats are strings made up of the following
31
+ # characters:
32
+ #
33
+ # 'O' Python object
34
+ # 'T' Python object of the type of 'self'
35
+ # 'v' void
36
+ # 'p' void *
37
+ # 'P' void **
38
+ # 'i' int
39
+ # 'b' bint
40
+ # 'I' int *
41
+ # 'l' long
42
+ # 'f' float
43
+ # 'd' double
44
+ # 'h' Py_hash_t
45
+ # 'z' Py_ssize_t
46
+ # 'Z' Py_ssize_t *
47
+ # 's' char *
48
+ # 'S' char **
49
+ # 'r' int used only to signal exception
50
+ # 'B' Py_buffer *
51
+ # '-' dummy 'self' argument (not used)
52
+ # '*' rest of args passed as generic Python
53
+ # arg tuple and kw dict (must be last
54
+ # char in format string)
55
+ # '?' optional object arg (currently for pow only)
56
+
57
+ format_map = {
58
+ 'O': PyrexTypes.py_object_type,
59
+ 'v': PyrexTypes.c_void_type,
60
+ 'p': PyrexTypes.c_void_ptr_type,
61
+ 'P': PyrexTypes.c_void_ptr_ptr_type,
62
+ 'i': PyrexTypes.c_int_type,
63
+ 'b': PyrexTypes.c_bint_type,
64
+ 'I': PyrexTypes.c_int_ptr_type,
65
+ 'l': PyrexTypes.c_long_type,
66
+ 'f': PyrexTypes.c_float_type,
67
+ 'd': PyrexTypes.c_double_type,
68
+ 'h': PyrexTypes.c_py_hash_t_type,
69
+ 'z': PyrexTypes.c_py_ssize_t_type,
70
+ 'Z': PyrexTypes.c_py_ssize_t_ptr_type,
71
+ 's': PyrexTypes.c_char_ptr_type,
72
+ 'S': PyrexTypes.c_char_ptr_ptr_type,
73
+ 'r': PyrexTypes.c_returncode_type,
74
+ 'B': PyrexTypes.c_py_buffer_ptr_type,
75
+ '?': PyrexTypes.py_object_type
76
+ # 'T', '-' and '*' are handled otherwise
77
+ # and are not looked up in here
78
+ }
79
+
80
+ type_to_format_map = {type_: format_ for format_, type_ in format_map.items()}
81
+
82
+ error_value_map = {
83
+ 'O': "NULL",
84
+ 'T': "NULL",
85
+ 'i': "-1",
86
+ 'b': "-1",
87
+ 'l': "-1",
88
+ 'r': "-1",
89
+ 'h': "-1",
90
+ 'z': "-1",
91
+ }
92
+
93
+ # Describes whether to use fastcall, and what macro
94
+ # to use the guard the use of fastcall.
95
+ class FastcallUsed(enum.IntEnum):
96
+ NO = 0
97
+ YES = 1 # guarded by CYTHON_FASTCALL
98
+ TP_NEW = 2 # guarded by CYTHON_FASTCALL_TPNEW
99
+
100
+ # Use METH_FASTCALL instead of METH_VARARGS
101
+ use_fastcall = FastcallUsed.NO
102
+
103
+ def __init__(self, arg_format, ret_format, nogil=False):
104
+ self.has_dummy_arg = False
105
+ self.has_generic_args = False
106
+ self.optional_object_arg_count = 0
107
+ if arg_format[:1] == '-':
108
+ self.has_dummy_arg = True
109
+ arg_format = arg_format[1:]
110
+ if arg_format[-1:] == '*':
111
+ self.has_generic_args = True
112
+ arg_format = arg_format[:-1]
113
+ if arg_format[-1:] == '?':
114
+ self.optional_object_arg_count += 1
115
+ self.fixed_arg_format = arg_format
116
+ self.ret_format = ret_format
117
+ self.error_value = self.error_value_map.get(ret_format, None)
118
+ self.exception_check = ret_format != 'r' and self.error_value is not None
119
+ self.is_staticmethod = False
120
+ self.nogil = nogil
121
+
122
+ def __repr__(self):
123
+ return '<Signature[%s(%s%s)]>' % (
124
+ self.ret_format,
125
+ ', '.join(self.fixed_arg_format),
126
+ '*' if self.has_generic_args else '')
127
+
128
+ def min_num_fixed_args(self):
129
+ return self.max_num_fixed_args() - self.optional_object_arg_count
130
+
131
+ def max_num_fixed_args(self):
132
+ return len(self.fixed_arg_format)
133
+
134
+ def is_self_arg(self, i):
135
+ # argument is 'self' for methods or 'class' for classmethods
136
+ return self.fixed_arg_format[i] == 'T'
137
+
138
+ def returns_self_type(self):
139
+ # return type is same as 'self' argument type
140
+ return self.ret_format == 'T'
141
+
142
+ def fixed_arg_type(self, i):
143
+ return self.format_map[self.fixed_arg_format[i]]
144
+
145
+ def return_type(self):
146
+ return self.format_map[self.ret_format]
147
+
148
+ def format_from_type(self, arg_type):
149
+ if arg_type.is_pyobject:
150
+ arg_type = PyrexTypes.py_object_type
151
+ return self.type_to_format_map[arg_type]
152
+
153
+ def exception_value(self):
154
+ return self.error_value_map.get(self.ret_format)
155
+
156
+ def function_type(self, self_arg_override=None):
157
+ # Construct a C function type descriptor for this signature
158
+ args = []
159
+ for i in range(self.max_num_fixed_args()):
160
+ if self_arg_override is not None and self.is_self_arg(i):
161
+ assert isinstance(self_arg_override, PyrexTypes.CFuncTypeArg)
162
+ args.append(self_arg_override)
163
+ else:
164
+ arg_type = self.fixed_arg_type(i)
165
+ args.append(PyrexTypes.CFuncTypeArg("", arg_type, None))
166
+ if self_arg_override is not None and self.returns_self_type():
167
+ ret_type = self_arg_override.type
168
+ else:
169
+ ret_type = self.return_type()
170
+ exc_value = self.exception_value()
171
+ return PyrexTypes.CFuncType(
172
+ ret_type, args, exception_value=exc_value,
173
+ exception_check=self.exception_check,
174
+ nogil=self.nogil)
175
+
176
+ def method_flags(self):
177
+ if self.ret_format == "O":
178
+ full_args = self.fixed_arg_format
179
+ if self.has_dummy_arg:
180
+ full_args = "O" + full_args
181
+ if full_args in ["O", "T"]:
182
+ if not self.has_generic_args:
183
+ return [method_noargs]
184
+ elif self.use_fastcall:
185
+ return [method_fastcall, method_keywords]
186
+ else:
187
+ return [method_varargs, method_keywords]
188
+ elif full_args in ["OO", "TO"] and not self.has_generic_args:
189
+ return [method_onearg]
190
+
191
+ if self.is_staticmethod:
192
+ if self.use_fastcall:
193
+ return [method_fastcall, method_keywords]
194
+ else:
195
+ return [method_varargs, method_keywords]
196
+ return None
197
+
198
+ def method_function_type(self):
199
+ # Return the C function type
200
+ mflags = self.method_flags()
201
+ kw = "WithKeywords" if (method_keywords in mflags) else ""
202
+ for m in mflags:
203
+ if m == method_noargs or m == method_onearg:
204
+ return "PyCFunction"
205
+ if m == method_varargs:
206
+ return "PyCFunction" + kw
207
+ if m == method_fastcall:
208
+ return "__Pyx_PyCFunction_FastCall" + kw
209
+ return None
210
+
211
+ def with_fastcall(self, fastcall_type=FastcallUsed.YES):
212
+ # Return a copy of this Signature with use_fastcall=True
213
+ sig = copy.copy(self)
214
+ sig.use_fastcall = fastcall_type
215
+ return sig
216
+
217
+ @property
218
+ def fastvar(self):
219
+ # Used to select variants of functions, one dealing with METH_VARARGS
220
+ # and one dealing with __Pyx_METH_FASTCALL
221
+ if self.use_fastcall == self.FastcallUsed.YES:
222
+ return "FASTCALL"
223
+ elif self.use_fastcall == self.FastcallUsed.TP_NEW:
224
+ return "FASTCALL_TPNEW"
225
+ else:
226
+ return "VARARGS"
227
+
228
+ @property
229
+ def fastcall_guard(self):
230
+ if self.use_fastcall == self.FastcallUsed.YES:
231
+ return "CYTHON_VECTORCALL"
232
+ elif self.use_fastcall == self.FastcallUsed.TP_NEW:
233
+ return "CYTHON_VECTORCALL_TPNEW"
234
+ else:
235
+ return "1"
236
+
237
+
238
+ class SlotDescriptor:
239
+ # Abstract base class for type slot descriptors.
240
+ #
241
+ # slot_name string Member name of the slot in the type object
242
+ # is_initialised_dynamically Is initialised by code in the module init function
243
+ # is_inherited Is inherited by subtypes (see PyType_Ready())
244
+ # ifdef Full #ifdef string that slot is wrapped in. Using this causes flags to be ignored.
245
+ # used_ifdef Full #ifdef string that the slot value is wrapped in (otherwise it is assigned NULL)
246
+ # Unlike "ifdef" the slot is defined and this just controls if it receives a value
247
+
248
+ def __init__(self, slot_name, dynamic=False, inherited=False,
249
+ ifdef=None, is_binop=False,
250
+ used_ifdef=None):
251
+ self.slot_name = slot_name
252
+ self.is_initialised_dynamically = dynamic
253
+ self.is_inherited = inherited
254
+ self.ifdef = ifdef
255
+ self.used_ifdef = used_ifdef
256
+ self.is_binop = is_binop
257
+
258
+ def slot_code(self, scope):
259
+ raise NotImplementedError()
260
+
261
+ def spec_value(self, scope):
262
+ return self.slot_code(scope)
263
+
264
+ def preprocessor_guard_code(self):
265
+ ifdef = self.ifdef
266
+ guard = None
267
+ if ifdef:
268
+ guard = "#if %s" % ifdef
269
+ return guard
270
+
271
+ def generate_spec(self, scope, code):
272
+ if self.is_initialised_dynamically:
273
+ return
274
+ value = self.spec_value(scope)
275
+ if value == "0":
276
+ return
277
+ preprocessor_guard = self.preprocessor_guard_code()
278
+ if not preprocessor_guard:
279
+ if self.slot_name.startswith(('bf_', 'am_')):
280
+ # The buffer protocol requires Limited API 3.11 and 'am_send' requires 3.10,
281
+ # so check if the spec slots are available.
282
+ preprocessor_guard = "#if defined(Py_%s)" % self.slot_name
283
+ if preprocessor_guard:
284
+ code.putln(preprocessor_guard)
285
+ if self.used_ifdef:
286
+ # different from preprocessor guard - this defines if we *want* to define it,
287
+ # rather than if the slot exists
288
+ code.putln(f"#if {self.used_ifdef}")
289
+ code.putln("{Py_%s, (void *)%s}," % (self.slot_name, value))
290
+ if self.used_ifdef:
291
+ code.putln("#endif")
292
+ if preprocessor_guard:
293
+ code.putln("#endif")
294
+
295
+ def generate(self, scope, code):
296
+ preprocessor_guard = self.preprocessor_guard_code()
297
+ if preprocessor_guard:
298
+ code.putln(preprocessor_guard)
299
+
300
+ end_pypy_guard = False
301
+ if self.is_initialised_dynamically:
302
+ value = "0"
303
+ else:
304
+ value = self.slot_code(scope)
305
+ if value == "0" and self.is_inherited:
306
+ # PyPy currently has a broken PyType_Ready() that fails to
307
+ # inherit some slots. To work around this, we explicitly
308
+ # set inherited slots here, but only in PyPy since CPython
309
+ # handles this better than we do (except for buffer slots in type specs).
310
+ inherited_value = value
311
+ current_scope = scope
312
+ while (inherited_value == "0"
313
+ and current_scope.parent_type
314
+ and current_scope.parent_type.base_type
315
+ and current_scope.parent_type.base_type.scope):
316
+ current_scope = current_scope.parent_type.base_type.scope
317
+ inherited_value = self.slot_code(current_scope)
318
+ if inherited_value != "0":
319
+ # we always need inherited buffer slots for the type spec
320
+ is_buffer_slot = int(self.slot_name in ("bf_getbuffer", "bf_releasebuffer"))
321
+ code.putln("#if CYTHON_COMPILING_IN_PYPY || %d" % is_buffer_slot)
322
+ code.putln("%s, /*%s*/" % (inherited_value, self.slot_name))
323
+ code.putln("#else")
324
+ end_pypy_guard = True
325
+
326
+ if self.used_ifdef:
327
+ code.putln("#if %s" % self.used_ifdef)
328
+ code.putln("%s, /*%s*/" % (value, self.slot_name))
329
+ if self.used_ifdef:
330
+ code.putln("#else")
331
+ code.putln("NULL, /*%s*/" % self.slot_name)
332
+ code.putln("#endif")
333
+
334
+ if end_pypy_guard:
335
+ code.putln("#endif")
336
+
337
+ if preprocessor_guard:
338
+ code.putln("#endif")
339
+
340
+ # Some C implementations have trouble statically
341
+ # initialising a global with a pointer to an extern
342
+ # function, so we initialise some of the type slots
343
+ # in the module init function instead.
344
+
345
+ def generate_dynamic_init_code(self, scope, code):
346
+ if self.is_initialised_dynamically:
347
+ self.generate_set_slot_code(
348
+ self.slot_code(scope), scope, code)
349
+
350
+ def generate_set_slot_code(self, value, scope, code):
351
+ if value == "0":
352
+ return
353
+
354
+ if scope.parent_type.typeptr_cname:
355
+ target = "%s->%s" % (
356
+ code.typeptr_cname_in_module_state(scope.parent_type), self.slot_name)
357
+ else:
358
+ assert scope.parent_type.typeobj_cname
359
+ target = "%s.%s" % (
360
+ code.name_in_module_state(scope.parent_type.typeobj_cname), self.slot_name)
361
+
362
+ code.putln("%s = %s;" % (target, value))
363
+
364
+
365
+ class FixedSlot(SlotDescriptor):
366
+ # Descriptor for a type slot with a fixed value.
367
+ #
368
+ # value string
369
+
370
+ def __init__(self, slot_name, value, ifdef=None):
371
+ SlotDescriptor.__init__(self, slot_name, ifdef=ifdef)
372
+ self.value = value
373
+
374
+ def slot_code(self, scope):
375
+ return self.value
376
+
377
+
378
+ class EmptySlot(FixedSlot):
379
+ # Descriptor for a type slot whose value is always 0.
380
+
381
+ def __init__(self, slot_name, ifdef=None):
382
+ FixedSlot.__init__(self, slot_name, "0", ifdef=ifdef)
383
+
384
+
385
+ class MethodSlot(SlotDescriptor):
386
+ # Type slot descriptor for a user-definable method.
387
+ #
388
+ # signature Signature
389
+ # method_name string The __xxx__ name of the method
390
+ # alternatives [string] Alternative list of __xxx__ names for the method
391
+
392
+ def __init__(self, signature, slot_name, method_name, method_name_to_slot,
393
+ fallback=None, ifdef=None, inherited=True):
394
+ SlotDescriptor.__init__(self, slot_name,
395
+ ifdef=ifdef, inherited=inherited)
396
+ self.signature = signature
397
+ self.slot_name = slot_name
398
+ self.method_name = method_name
399
+ self.alternatives = []
400
+ method_name_to_slot[method_name] = self
401
+ #
402
+ if fallback:
403
+ self.alternatives.append(fallback)
404
+
405
+ def slot_code(self, scope):
406
+ entry = scope.lookup_here(self.method_name)
407
+ if entry and entry.is_special and entry.func_cname:
408
+ for method_name in self.alternatives:
409
+ alt_entry = scope.lookup_here(method_name)
410
+ if alt_entry:
411
+ warn_once(alt_entry.pos,
412
+ f"{method_name} was removed in Python 3; ignoring it and using {self.method_name} instead",
413
+ 2)
414
+ return entry.func_cname
415
+ for method_name in self.alternatives:
416
+ entry = scope.lookup_here(method_name)
417
+ if entry and entry.is_special and entry.func_cname:
418
+ warn_once(entry.pos,
419
+ f"{method_name} was removed in Python 3; use {self.method_name} instead",
420
+ 2)
421
+ return entry.func_cname
422
+ return "0"
423
+
424
+
425
+ class InternalMethodSlot(SlotDescriptor):
426
+ # Type slot descriptor for a method which is always
427
+ # synthesized by Cython.
428
+ #
429
+ # slot_name string Member name of the slot in the type object
430
+
431
+ def __init__(self, slot_name, **kargs):
432
+ SlotDescriptor.__init__(self, slot_name, **kargs)
433
+
434
+ def slot_code(self, scope):
435
+ return scope.mangle_internal(self.slot_name)
436
+
437
+
438
+ class GCDependentSlot(InternalMethodSlot):
439
+ # Descriptor for a slot whose value depends on whether
440
+ # the type participates in GC.
441
+
442
+ def __init__(self, slot_name, **kargs):
443
+ InternalMethodSlot.__init__(self, slot_name, **kargs)
444
+
445
+ def slot_code(self, scope):
446
+ # We treat external types as needing gc, but don't generate a slot code
447
+ # because we don't know it to be able to call it directly.
448
+ if not scope.needs_gc() or scope.parent_type.is_external:
449
+ return "0"
450
+ if not scope.has_cyclic_pyobject_attrs:
451
+ # if the type does not have GC relevant object attributes, it can
452
+ # delegate GC methods to its parent - iff the parent functions
453
+ # are defined in the same module
454
+ parent_type_scope = scope.parent_type.base_type.scope
455
+ if scope.parent_scope is parent_type_scope.parent_scope:
456
+ entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
457
+ if entry.visibility != 'extern':
458
+ return self.slot_code(parent_type_scope)
459
+ return InternalMethodSlot.slot_code(self, scope)
460
+
461
+
462
+ class GCClearReferencesSlot(GCDependentSlot):
463
+
464
+ def slot_code(self, scope):
465
+ if scope.needs_tp_clear():
466
+ return GCDependentSlot.slot_code(self, scope)
467
+ return "0"
468
+
469
+
470
+ class ConstructorSlot(InternalMethodSlot):
471
+ # Descriptor for tp_new and tp_dealloc.
472
+
473
+ def __init__(self, slot_name, method=None, **kargs):
474
+ InternalMethodSlot.__init__(self, slot_name, **kargs)
475
+ self.method = method
476
+
477
+ def to_vectorcall_slot(self):
478
+ # Return a dummy slot used to implement tp_vectorcall.
479
+ # It has the same rules about when to generate it as tp_new.
480
+ assert self.slot_name == "tp_new"
481
+ self_copy = copy.copy(self)
482
+ self_copy.slot_name = "tp_new_vectorcall"
483
+ return self_copy
484
+
485
+ def _needs_own(self, scope):
486
+ if (scope.parent_type.base_type
487
+ and not scope.has_pyobject_attrs
488
+ and not scope.has_memoryview_attrs
489
+ and not scope.has_explicitly_constructable_attrs
490
+ and not (self.slot_name in ('tp_new', 'tp_new_vectorcall') and scope.parent_type.vtabslot_cname)):
491
+ entry = scope.lookup_here(self.method) if self.method else None
492
+ if not (entry and entry.is_special):
493
+ return False
494
+ # Unless we can safely delegate to the parent, all types need a tp_new().
495
+ return True
496
+
497
+ def _parent_slot_function(self, scope):
498
+ parent_type_scope = scope.parent_type.base_type.scope
499
+ if scope.parent_scope is parent_type_scope.parent_scope:
500
+ entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
501
+ if entry.visibility != 'extern':
502
+ return self.slot_code(parent_type_scope)
503
+ return None
504
+
505
+ def slot_code(self, scope):
506
+ if not self._needs_own(scope):
507
+ # if the type does not have object attributes, it can
508
+ # delegate GC methods to its parent - iff the parent
509
+ # functions are defined in the same module
510
+ slot_code = self._parent_slot_function(scope)
511
+ if slot_code is not None:
512
+ return slot_code
513
+ return InternalMethodSlot.slot_code(self, scope)
514
+
515
+ def generate_dynamic_init_code(self, scope, code):
516
+ if self.slot_code(scope) != '0':
517
+ return
518
+ # If we don't have our own slot function and don't know the
519
+ # parent function statically, copy it dynamically.
520
+ base_type = scope.parent_type.base_type
521
+ if base_type.typeptr_cname:
522
+ base_typeptr_cname = code.typeptr_cname_in_module_state(base_type)
523
+ src = '%s->%s' % (base_typeptr_cname, self.slot_name)
524
+ elif base_type.is_extension_type and base_type.typeobj_cname:
525
+ src = '%s.%s' % (code.typeptr_cname_in_module_state(base_type), self.slot_name)
526
+ else:
527
+ return
528
+
529
+ self.generate_set_slot_code(src, scope, code)
530
+
531
+
532
+ class TpVectorcallSlot(ConstructorSlot):
533
+ def _needs_own(self, scope):
534
+ return True # never inherited
535
+
536
+ def slot_code(self, scope):
537
+ tp = scope.parent_type
538
+ while tp:
539
+ if not tp.is_extension_type:
540
+ return "0"
541
+ if tp.is_external:
542
+ return "0"
543
+ if tp.scope.parent_scope is not scope.parent_scope:
544
+ # In a pxd file. We don't have enough visibility to make this work.
545
+ return "0"
546
+ if tp.multiple_bases:
547
+ return "0" # Can't reason about __init__
548
+ # If we don't have the second overloaded alternative for __cinit__ or __init__
549
+ # this means the signature was wrong and so we haven't generated code for the
550
+ # vectorcall wrappers in DefNode.analyse_declarations.
551
+ # This applies to all base classes (since we need to be able to call their
552
+ # vectorcall-signature __cinit__, and we won't have generated that function
553
+ # unless the base class met all the conditions itself).
554
+ cinit_entry = tp.scope.lookup_here("__cinit__")
555
+ if cinit_entry and not (cinit_entry.is_special and cinit_entry.tp_new_can_be_vectorcall):
556
+ return "0"
557
+ init_entry = tp.scope.lookup_here("__init__")
558
+ if init_entry and not (init_entry.is_special and init_entry.tp_new_can_be_vectorcall):
559
+ return "0"
560
+ tp = tp.base_type
561
+ return super().slot_code(scope)
562
+
563
+ def generate_dynamic_init_code(self, scope, code):
564
+ return # never do anything dynamic here
565
+
566
+
567
+ class SyntheticSlot(InternalMethodSlot):
568
+ # Type slot descriptor for a synthesized method which
569
+ # dispatches to one or more user-defined methods depending
570
+ # on its arguments. If none of the relevant methods are
571
+ # defined, the method will not be synthesized and an
572
+ # alternative default value will be placed in the type
573
+ # slot.
574
+
575
+ def __init__(self, slot_name, user_methods, default_value, **kargs):
576
+ InternalMethodSlot.__init__(self, slot_name, **kargs)
577
+ self.user_methods = user_methods
578
+ self.default_value = default_value
579
+
580
+ def slot_code(self, scope):
581
+ if scope.defines_any_special(self.user_methods):
582
+ return InternalMethodSlot.slot_code(self, scope)
583
+ else:
584
+ return self.default_value
585
+
586
+ def spec_value(self, scope):
587
+ return self.slot_code(scope)
588
+
589
+
590
+ class SubscriptSlot(SyntheticSlot):
591
+ """
592
+ Slot descriptor that implements the functionally overlapping sequence/mapping slots.
593
+ """
594
+ def __init__(self, slot_name, user_methods):
595
+ super().__init__(slot_name, user_methods, "0")
596
+
597
+ _slot_methods = {
598
+ 'sq_item': ['__getitem__'],
599
+ 'sq_ass_item': ['__setitem__', '__delitem__'],
600
+ 'mp_subscript': ['__getitem__'],
601
+ 'mp_ass_subscript': ['__setitem__', '__delitem__'],
602
+ }
603
+
604
+ @staticmethod
605
+ def find_special_method(scope, method_name):
606
+ while True:
607
+ entry = scope.lookup_here(method_name)
608
+ if entry is not None:
609
+ return entry if entry.is_special else None
610
+ base_type = scope.parent_type.base_type
611
+ if base_type is None or base_type.is_external:
612
+ return None
613
+ scope = base_type.scope
614
+
615
+ @classmethod
616
+ def implements_slot(cls, scope, slot_name):
617
+ scope_implements_methods = False
618
+ is_sequence_impl = True
619
+ for method_name in cls._slot_methods[slot_name]:
620
+ entry = cls.find_special_method(scope, method_name)
621
+ if entry is None:
622
+ continue
623
+ if entry.scope is scope:
624
+ scope_implements_methods = True
625
+ if entry.signature != sequence_subscript_signatures[method_name]:
626
+ is_sequence_impl = False
627
+
628
+ if not scope_implements_methods:
629
+ return False
630
+
631
+ if slot_name.startswith('mp_') and scope.parent_type.base_type is not None:
632
+ # Even when implementing the sequence protocol, a base class might have chosen to
633
+ # implement the mapping protocol (or may choose to do so in the future),
634
+ # and that would unfortunately take precedence.
635
+ return True
636
+
637
+ collection_type = scope.directives.get('collection_type')
638
+ if collection_type == 'mapping':
639
+ if slot_name.startswith('mp_'):
640
+ return True
641
+ # Implementing the Sequence slot doesn't hurt because the Mapping protocol takes precedence.
642
+ elif collection_type == 'sequence':
643
+ if slot_name.startswith('sq_'):
644
+ return True
645
+ elif is_sequence_impl:
646
+ # Mapping slot in a Sequence, implemented with sequence signature.
647
+ # By not implementing it, we allow callers to see that it would be inefficient to use.
648
+ return False
649
+
650
+ return True
651
+
652
+ def slot_code(self, scope):
653
+ if self.implements_slot(scope, self.slot_name):
654
+ return InternalMethodSlot.slot_code(self, scope)
655
+ else:
656
+ return self.default_value
657
+
658
+
659
+ class BinopSlot(SyntheticSlot):
660
+ def __init__(self, signature, slot_name, left_method, method_name_to_slot, **kargs):
661
+ assert left_method.startswith('__')
662
+ right_method = '__r' + left_method[2:]
663
+ SyntheticSlot.__init__(
664
+ self, slot_name, [left_method, right_method], "0", is_binop=True, **kargs)
665
+ # MethodSlot causes special method registration.
666
+ self.left_slot = MethodSlot(signature, "", left_method, method_name_to_slot, **kargs)
667
+ self.right_slot = MethodSlot(signature, "", right_method, method_name_to_slot, **kargs)
668
+
669
+
670
+ class InitSlot(MethodSlot):
671
+ def slot_code(self, scope):
672
+ super_slot_code = super().slot_code(scope)
673
+ if super_slot_code != "0":
674
+ entry = scope.lookup(self.method_name)
675
+ if entry and entry.is_special and entry.signature.use_fastcall:
676
+ # we need a wrapper
677
+ return InternalMethodSlot.slot_code(self, scope)
678
+ return super_slot_code
679
+
680
+
681
+ class RichcmpSlot(MethodSlot):
682
+ def slot_code(self, scope):
683
+ entry = scope.lookup_here(self.method_name)
684
+ if entry and entry.is_special and entry.func_cname:
685
+ return entry.func_cname
686
+ elif scope.defines_any_special(richcmp_special_methods):
687
+ return scope.mangle_internal(self.slot_name)
688
+ else:
689
+ return "0"
690
+
691
+
692
+ class TypeFlagsSlot(SlotDescriptor):
693
+ # Descriptor for the type flags slot.
694
+
695
+ def slot_code(self, scope):
696
+ value = "Py_TPFLAGS_DEFAULT"
697
+ if scope.directives['type_version_tag']:
698
+ # No longer used since Py3.11.
699
+ value += "|Py_TPFLAGS_HAVE_VERSION_TAG"
700
+ else:
701
+ # Used to be in 'Py_TPFLAGS_DEFAULT' up to Py3.10.
702
+ value = f"({value}&~Py_TPFLAGS_HAVE_VERSION_TAG)"
703
+ if not scope.parent_type.is_final_type:
704
+ value += "|Py_TPFLAGS_BASETYPE"
705
+ if scope.needs_gc():
706
+ value += "|Py_TPFLAGS_HAVE_GC"
707
+ if scope.parent_type.has_sequence_flag:
708
+ value += "|Py_TPFLAGS_SEQUENCE"
709
+ if scope.parent_type.has_mapping_flag:
710
+ assert not scope.parent_type.has_sequence_flag
711
+ value += "|Py_TPFLAGS_MAPPING"
712
+ return value
713
+
714
+ def generate_spec(self, scope, code):
715
+ # Flags are stored in the PyType_Spec, not in a PyType_Slot.
716
+ return
717
+
718
+
719
+ class DocStringSlot(SlotDescriptor):
720
+ # Descriptor for the docstring slot.
721
+
722
+ def slot_code(self, scope):
723
+ doc = scope.doc
724
+ if doc is None:
725
+ return "0"
726
+ if doc.is_unicode:
727
+ doc = doc.as_utf8_string()
728
+ return "PyDoc_STR(%s)" % doc.as_c_string_literal()
729
+
730
+
731
+ class SuiteSlot(SlotDescriptor):
732
+ # Descriptor for a substructure of the type object.
733
+ #
734
+ # sub_slots [SlotDescriptor]
735
+
736
+ def __init__(self, sub_slots, slot_type, slot_name, substructures, ifdef=None, cast_cname=None):
737
+ SlotDescriptor.__init__(self, slot_name, ifdef=ifdef)
738
+ self.sub_slots = sub_slots
739
+ self.slot_type = slot_type
740
+ self.cast_cname = cast_cname
741
+ substructures.append(self)
742
+
743
+ def is_empty(self, scope):
744
+ for slot in self.sub_slots:
745
+ if slot.slot_code(scope) != "0":
746
+ return False
747
+ return True
748
+
749
+ def substructure_cname(self, scope):
750
+ return "%s%s_%s" % (Naming.pyrex_prefix, self.slot_name, scope.class_name)
751
+
752
+ def slot_code(self, scope):
753
+ if not self.is_empty(scope):
754
+ cast = ""
755
+ if self.cast_cname:
756
+ cast = f"({self.cast_cname}*)"
757
+ return f"{cast}&{self.substructure_cname(scope)}"
758
+ return "0"
759
+
760
+ def generate_substructure(self, scope, code):
761
+ if not self.is_empty(scope):
762
+ code.putln("")
763
+ if self.ifdef:
764
+ code.putln("#if %s" % self.ifdef)
765
+ code.putln(
766
+ "static %s %s = {" % (
767
+ self.slot_type,
768
+ self.substructure_cname(scope)))
769
+ for slot in self.sub_slots:
770
+ slot.generate(scope, code)
771
+ code.putln("};")
772
+ if self.ifdef:
773
+ code.putln("#endif")
774
+
775
+ def generate_spec(self, scope, code):
776
+ for slot in self.sub_slots:
777
+ slot.generate_spec(scope, code)
778
+
779
+ class MethodTableSlot(SlotDescriptor):
780
+ # Slot descriptor for the method table.
781
+
782
+ def slot_code(self, scope):
783
+ if scope.pyfunc_entries:
784
+ return scope.method_table_cname
785
+ else:
786
+ return "0"
787
+
788
+
789
+ class MemberTableSlot(SlotDescriptor):
790
+ # Slot descriptor for the table of Python-accessible attributes.
791
+
792
+ def slot_code(self, scope):
793
+ # Only used in specs.
794
+ return "0"
795
+
796
+ def get_member_specs(self, scope):
797
+ return [
798
+ get_slot_by_name("tp_dictoffset", scope.directives).members_slot_value(scope),
799
+ #get_slot_by_name("tp_weaklistoffset").spec_value(scope),
800
+ ]
801
+
802
+ def is_empty(self, scope):
803
+ for member_entry in self.get_member_specs(scope):
804
+ if member_entry:
805
+ return False
806
+ return True
807
+
808
+ def substructure_cname(self, scope):
809
+ return "%s%s_%s" % (Naming.pyrex_prefix, self.slot_name, scope.class_name)
810
+
811
+ def generate_substructure_spec(self, scope, code):
812
+ if self.is_empty(scope):
813
+ return
814
+ from .Code import UtilityCode
815
+ code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStructmemberH", "ModuleSetupCode.c"))
816
+
817
+ code.putln("static struct PyMemberDef %s[] = {" % self.substructure_cname(scope))
818
+ for member_entry in self.get_member_specs(scope):
819
+ if member_entry:
820
+ code.putln(member_entry)
821
+ code.putln("{NULL, 0, 0, 0, NULL}")
822
+ code.putln("};")
823
+
824
+ def spec_value(self, scope):
825
+ if self.is_empty(scope):
826
+ return "0"
827
+ return self.substructure_cname(scope)
828
+
829
+
830
+ class GetSetSlot(SlotDescriptor):
831
+ # Slot descriptor for the table of attribute get & set methods.
832
+
833
+ def slot_code(self, scope):
834
+ if scope.property_entries:
835
+ return scope.getset_table_cname
836
+ else:
837
+ return "0"
838
+
839
+
840
+ class BaseClassSlot(SlotDescriptor):
841
+ # Slot descriptor for the base class slot.
842
+
843
+ def __init__(self, name):
844
+ SlotDescriptor.__init__(self, name, dynamic=True)
845
+
846
+ def generate_dynamic_init_code(self, scope, code):
847
+ base_type = scope.parent_type.base_type
848
+ if base_type:
849
+ base_typeptr_cname = code.typeptr_cname_in_module_state(base_type)
850
+ code.putln("%s->%s = %s;" % (
851
+ code.typeptr_cname_in_module_state(scope.parent_type),
852
+ self.slot_name,
853
+ base_typeptr_cname))
854
+
855
+
856
+ class DictOffsetSlot(SlotDescriptor):
857
+ # Slot descriptor for a class' dict offset, for dynamic attributes.
858
+
859
+ def slot_code(self, scope):
860
+ dict_entry = scope.lookup_here("__dict__") if not scope.is_closure_class_scope else None
861
+ if dict_entry and dict_entry.is_variable:
862
+ if dict_entry.is_inherited:
863
+ return "0"
864
+ if not dict_entry.type.is_pydict_type:
865
+ error(dict_entry.pos, "__dict__ slot must be of type 'dict'")
866
+ return "0"
867
+ type = scope.parent_type
868
+ if type.typedef_flag:
869
+ objstruct = type.objstruct_cname
870
+ else:
871
+ objstruct = "struct %s" % type.objstruct_cname
872
+ return ("offsetof(%s, %s)" % (
873
+ objstruct,
874
+ dict_entry.cname))
875
+ else:
876
+ return "0"
877
+
878
+ def members_slot_value(self, scope):
879
+ dict_offset = self.slot_code(scope)
880
+ if dict_offset == "0":
881
+ return None
882
+ return '{"__dictoffset__", T_PYSSIZET, %s, READONLY, NULL},' % dict_offset
883
+
884
+ ## The following slots are (or could be) initialised with an
885
+ ## extern function pointer.
886
+ #
887
+ #slots_initialised_from_extern = (
888
+ # "tp_free",
889
+ #)
890
+
891
+ #------------------------------------------------------------------------------------------
892
+ #
893
+ # Utility functions for accessing slot table data structures
894
+ #
895
+ #------------------------------------------------------------------------------------------
896
+
897
+
898
+ def get_property_accessor_signature(name):
899
+ # Return signature of accessor for an extension type
900
+ # property, else None.
901
+ return property_accessor_signatures.get(name)
902
+
903
+
904
+ def get_base_slot_function(scope, slot):
905
+ # Returns the function implementing this slot in the baseclass.
906
+ # This is useful for enabling the compiler to optimize calls
907
+ # that recursively climb the class hierarchy.
908
+ base_type = scope.parent_type.base_type
909
+ if base_type and scope.parent_scope is base_type.scope.parent_scope:
910
+ parent_slot = slot.slot_code(base_type.scope)
911
+ if parent_slot != '0':
912
+ entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name)
913
+ if entry.visibility != 'extern':
914
+ return parent_slot
915
+ return None
916
+
917
+
918
+ def get_slot_function(scope, slot):
919
+ # Returns the function implementing this slot in the baseclass.
920
+ # This is useful for enabling the compiler to optimize calls
921
+ # that recursively climb the class hierarchy.
922
+ slot_code = slot.slot_code(scope)
923
+ if slot_code != '0':
924
+ entry = scope.parent_scope.lookup_here(scope.parent_type.name)
925
+ if entry.visibility != 'extern':
926
+ return slot_code
927
+ return None
928
+
929
+
930
+ def get_slot_by_name(slot_name, compiler_directives):
931
+ # For now, only search the type struct, no referenced sub-structs.
932
+ for slot in get_slot_table(compiler_directives).slot_table:
933
+ if slot.slot_name == slot_name:
934
+ return slot
935
+ assert False, "Slot not found: %s" % slot_name
936
+
937
+
938
+ def get_slot_code_by_name(scope, slot_name):
939
+ slot = get_slot_by_name(slot_name, scope.directives)
940
+ return slot.slot_code(scope)
941
+
942
+ def is_binop_number_slot(name):
943
+ """
944
+ Tries to identify __add__/__radd__ and friends (so the METH_COEXIST flag can be applied).
945
+
946
+ There's no great consequence if it inadvertently identifies a few other methods
947
+ so just use a simple rule rather than an exact list.
948
+ """
949
+ slot_table = get_slot_table(None)
950
+ for meth in get_slot_table(None).PyNumberMethods:
951
+ if meth.is_binop and name in meth.user_methods:
952
+ return True
953
+ return False
954
+
955
+
956
+ #------------------------------------------------------------------------------------------
957
+ #
958
+ # Signatures for generic Python functions and methods.
959
+ #
960
+ #------------------------------------------------------------------------------------------
961
+
962
+ pyfunction_signature = Signature("-*", "O")
963
+ pymethod_signature = Signature("T*", "O")
964
+
965
+ #------------------------------------------------------------------------------------------
966
+ #
967
+ # Signatures for simple Python functions.
968
+ #
969
+ #------------------------------------------------------------------------------------------
970
+
971
+ pyfunction_noargs = Signature("-", "O")
972
+ pyfunction_onearg = Signature("-O", "O")
973
+
974
+ #------------------------------------------------------------------------------------------
975
+ #
976
+ # Signatures for the various kinds of function that
977
+ # can appear in the type object and its substructures.
978
+ #
979
+ #------------------------------------------------------------------------------------------
980
+
981
+ unaryfunc = Signature("T", "O") # typedef PyObject * (*unaryfunc)(PyObject *);
982
+ binaryfunc = Signature("OO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
983
+ ibinaryfunc = Signature("TO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
984
+ powternaryfunc = Signature("OO?", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
985
+ ipowternaryfunc = Signature("TO?", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
986
+ callfunc = Signature("T*", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
987
+ inquiry = Signature("T", "i") # typedef int (*inquiry)(PyObject *);
988
+ lenfunc = Signature("T", "z") # typedef Py_ssize_t (*lenfunc)(PyObject *);
989
+
990
+ # typedef int (*coercion)(PyObject **, PyObject **);
991
+ intargfunc = Signature("Ti", "O") # typedef PyObject *(*intargfunc)(PyObject *, int);
992
+ ssizeargfunc = Signature("Tz", "O") # typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
993
+ intintargfunc = Signature("Tii", "O") # typedef PyObject *(*intintargfunc)(PyObject *, int, int);
994
+ ssizessizeargfunc = Signature("Tzz", "O") # typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
995
+ ssizeargproc = Signature("Tz", "r") # typedef int(*ssizeargfunc)(PyObject *, Py_ssize_t);
996
+ intobjargproc = Signature("TiO", 'r') # typedef int(*intobjargproc)(PyObject *, int, PyObject *);
997
+ ssizeobjargproc = Signature("TzO", 'r') # typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
998
+ intintobjargproc = Signature("TiiO", 'r') # typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *);
999
+ ssizessizeobjargproc = Signature("TzzO", 'r') # typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
1000
+
1001
+ intintargproc = Signature("Tii", 'r')
1002
+ ssizessizeargproc = Signature("Tzz", 'r')
1003
+ objargfunc = Signature("TO", "O")
1004
+ objobjargproc = Signature("TOO", 'r') # typedef int (*objobjargproc)(PyObject *, PyObject *, PyObject *);
1005
+ readbufferproc = Signature("TzP", "z") # typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **);
1006
+ writebufferproc = Signature("TzP", "z") # typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **);
1007
+ segcountproc = Signature("TZ", "z") # typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
1008
+ charbufferproc = Signature("TzS", "z") # typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
1009
+ objargproc = Signature("TO", 'r') # typedef int (*objobjproc)(PyObject *, PyObject *);
1010
+ # typedef int (*visitproc)(PyObject *, void *);
1011
+ # typedef int (*traverseproc)(PyObject *, visitproc, void *);
1012
+
1013
+ destructor = Signature("T", "v") # typedef void (*destructor)(PyObject *);
1014
+ # printfunc = Signature("TFi", 'r') # typedef int (*printfunc)(PyObject *, FILE *, int);
1015
+ # typedef PyObject *(*getattrfunc)(PyObject *, char *);
1016
+ getattrofunc = Signature("TO", "O") # typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
1017
+ # typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
1018
+ setattrofunc = Signature("TOO", 'r') # typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
1019
+ delattrofunc = Signature("TO", 'r')
1020
+ cmpfunc = Signature("TO", "i") # typedef int (*cmpfunc)(PyObject *, PyObject *);
1021
+ reprfunc = Signature("T", "O") # typedef PyObject *(*reprfunc)(PyObject *);
1022
+ hashfunc = Signature("T", "h") # typedef Py_hash_t (*hashfunc)(PyObject *);
1023
+ richcmpfunc = Signature("TOi", "O") # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
1024
+ getiterfunc = Signature("T", "O") # typedef PyObject *(*getiterfunc) (PyObject *);
1025
+ iternextfunc = Signature("T", "O") # typedef PyObject *(*iternextfunc) (PyObject *);
1026
+ descrgetfunc = Signature("TOO", "O") # typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *);
1027
+ descrsetfunc = Signature("TOO", 'r') # typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *);
1028
+ descrdelfunc = Signature("TO", 'r')
1029
+ initproc = Signature("T*", 'r') # typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
1030
+ # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
1031
+ # typedef PyObject *(*allocfunc)(struct _typeobject *, int);
1032
+
1033
+ getbufferproc = Signature("TBi", "r") # typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
1034
+ releasebufferproc = Signature("TB", "v") # typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
1035
+
1036
+ # typedef PySendResult (*sendfunc)(PyObject* iter, PyObject* value, PyObject** result);
1037
+ sendfunc = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
1038
+ return_type=PyrexTypes.PySendResult_type,
1039
+ args=[
1040
+ PyrexTypes.CFuncTypeArg("iter", PyrexTypes.py_object_type),
1041
+ PyrexTypes.CFuncTypeArg("value", PyrexTypes.py_object_type),
1042
+ PyrexTypes.CFuncTypeArg("result", PyrexTypes.CPtrType(PyrexTypes.py_objptr_type)),
1043
+ ],
1044
+ exception_value="PYGEN_ERROR",
1045
+ exception_check=True, # we allow returning PYGEN_ERROR without GeneratorExit / StopIteration
1046
+ ))
1047
+
1048
+ sequence_subscript_signatures = {
1049
+ '__getitem__': ssizeargfunc,
1050
+ '__setitem__': ssizeobjargproc,
1051
+ '__delitem__': ssizeargproc,
1052
+ }
1053
+
1054
+
1055
+ #------------------------------------------------------------------------------------------
1056
+ #
1057
+ # Signatures for accessor methods of properties.
1058
+ #
1059
+ #------------------------------------------------------------------------------------------
1060
+
1061
+ property_accessor_signatures = {
1062
+ '__get__': Signature("T", "O"),
1063
+ '__set__': Signature("TO", 'r'),
1064
+ '__del__': Signature("T", 'r')
1065
+ }
1066
+
1067
+ #------------------------------------------------------------------------------------------
1068
+ #
1069
+ # The main slot table. This table contains descriptors for all the
1070
+ # top-level type slots, beginning with tp_dealloc, in the order they
1071
+ # appear in the type object.
1072
+ #
1073
+ # It depends on some compiler directives (currently c_api_binop_methods), so the
1074
+ # slot tables for each set of compiler directives are generated lazily and put in
1075
+ # the _slot_table_dict
1076
+ #
1077
+ #------------------------------------------------------------------------------------------
1078
+
1079
+ class SlotTable:
1080
+ def __init__(self, old_binops):
1081
+ # The following dictionary maps __xxx__ method names to slot descriptors.
1082
+ method_name_to_slot = {}
1083
+ self._get_slot_by_method_name = method_name_to_slot.get
1084
+ self.substructures = [] # List of all SuiteSlot instances
1085
+
1086
+ bf = binaryfunc if old_binops else ibinaryfunc
1087
+ ptf = powternaryfunc if old_binops else ipowternaryfunc
1088
+
1089
+ # Descriptor tables for the slots of the various type object
1090
+ # substructures, in the order they appear in the structure.
1091
+ self.PyNumberMethods = (
1092
+ BinopSlot(bf, "nb_add", "__add__", method_name_to_slot),
1093
+ BinopSlot(bf, "nb_subtract", "__sub__", method_name_to_slot),
1094
+ BinopSlot(bf, "nb_multiply", "__mul__", method_name_to_slot),
1095
+ BinopSlot(bf, "nb_remainder", "__mod__", method_name_to_slot),
1096
+ BinopSlot(bf, "nb_divmod", "__divmod__", method_name_to_slot),
1097
+ BinopSlot(ptf, "nb_power", "__pow__", method_name_to_slot),
1098
+ MethodSlot(unaryfunc, "nb_negative", "__neg__", method_name_to_slot),
1099
+ MethodSlot(unaryfunc, "nb_positive", "__pos__", method_name_to_slot),
1100
+ MethodSlot(unaryfunc, "nb_absolute", "__abs__", method_name_to_slot),
1101
+ MethodSlot(inquiry, "nb_bool", "__bool__", method_name_to_slot,
1102
+ fallback="__nonzero__"),
1103
+ MethodSlot(unaryfunc, "nb_invert", "__invert__", method_name_to_slot),
1104
+ BinopSlot(bf, "nb_lshift", "__lshift__", method_name_to_slot),
1105
+ BinopSlot(bf, "nb_rshift", "__rshift__", method_name_to_slot),
1106
+ BinopSlot(bf, "nb_and", "__and__", method_name_to_slot),
1107
+ BinopSlot(bf, "nb_xor", "__xor__", method_name_to_slot),
1108
+ BinopSlot(bf, "nb_or", "__or__", method_name_to_slot),
1109
+ MethodSlot(unaryfunc, "nb_int", "__int__", method_name_to_slot, fallback="__long__"),
1110
+ EmptySlot("nb_long (reserved)"),
1111
+ MethodSlot(unaryfunc, "nb_float", "__float__", method_name_to_slot),
1112
+
1113
+ # Added in release 2.0
1114
+ MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__", method_name_to_slot),
1115
+ MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__", method_name_to_slot),
1116
+ MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__", method_name_to_slot),
1117
+ MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__", method_name_to_slot),
1118
+ MethodSlot(ptf, "nb_inplace_power", "__ipow__", method_name_to_slot),
1119
+ MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__", method_name_to_slot),
1120
+ MethodSlot(ibinaryfunc, "nb_inplace_rshift", "__irshift__", method_name_to_slot),
1121
+ MethodSlot(ibinaryfunc, "nb_inplace_and", "__iand__", method_name_to_slot),
1122
+ MethodSlot(ibinaryfunc, "nb_inplace_xor", "__ixor__", method_name_to_slot),
1123
+ MethodSlot(ibinaryfunc, "nb_inplace_or", "__ior__", method_name_to_slot),
1124
+
1125
+ # Added in release 2.2
1126
+ # The following require the Py_TPFLAGS_HAVE_CLASS flag
1127
+ BinopSlot(bf, "nb_floor_divide", "__floordiv__", method_name_to_slot),
1128
+ BinopSlot(bf, "nb_true_divide", "__truediv__", method_name_to_slot),
1129
+ MethodSlot(ibinaryfunc, "nb_inplace_floor_divide", "__ifloordiv__", method_name_to_slot),
1130
+ MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__", method_name_to_slot),
1131
+
1132
+ # Added in release 2.5
1133
+ MethodSlot(unaryfunc, "nb_index", "__index__", method_name_to_slot),
1134
+
1135
+ # Added in release 3.5
1136
+ BinopSlot(bf, "nb_matrix_multiply", "__matmul__", method_name_to_slot),
1137
+ MethodSlot(ibinaryfunc, "nb_inplace_matrix_multiply", "__imatmul__", method_name_to_slot),
1138
+ )
1139
+
1140
+ self.PySequenceMethods = (
1141
+ MethodSlot(lenfunc, "sq_length", "__len__", method_name_to_slot),
1142
+ EmptySlot("sq_concat"), # nb_add used instead
1143
+ EmptySlot("sq_repeat"), # nb_multiply used instead
1144
+ SubscriptSlot("sq_item", ["__getitem__"]),
1145
+ EmptySlot("sq_slice"),
1146
+ SubscriptSlot("sq_ass_item", ["__setitem__", "__delitem__"]),
1147
+ EmptySlot("sq_ass_slice"),
1148
+ MethodSlot(cmpfunc, "sq_contains", "__contains__", method_name_to_slot),
1149
+ EmptySlot("sq_inplace_concat"), # nb_inplace_add used instead
1150
+ EmptySlot("sq_inplace_repeat"), # nb_inplace_multiply used instead
1151
+ )
1152
+
1153
+ self.PyMappingMethods = (
1154
+ MethodSlot(lenfunc, "mp_length", "__len__", method_name_to_slot),
1155
+ SubscriptSlot("mp_subscript", ["__getitem__"]),
1156
+ SubscriptSlot("mp_ass_subscript", ["__setitem__", "__delitem__"]),
1157
+ )
1158
+
1159
+ self.PyBufferProcs = (
1160
+ MethodSlot(getbufferproc, "bf_getbuffer", "__getbuffer__", method_name_to_slot),
1161
+ MethodSlot(releasebufferproc, "bf_releasebuffer", "__releasebuffer__", method_name_to_slot)
1162
+ )
1163
+
1164
+ self.PyAsyncMethods = (
1165
+ MethodSlot(unaryfunc, "am_await", "__await__", method_name_to_slot),
1166
+ MethodSlot(unaryfunc, "am_aiter", "__aiter__", method_name_to_slot),
1167
+ MethodSlot(unaryfunc, "am_anext", "__anext__", method_name_to_slot),
1168
+ # We should not map arbitrary .send() methods to an async slot.
1169
+ #MethodSlot(sendfunc, "am_send", "send", method_name_to_slot),
1170
+ EmptySlot("am_send"),
1171
+ )
1172
+
1173
+ self.slot_table = (
1174
+ ConstructorSlot("tp_dealloc", '__dealloc__'),
1175
+ EmptySlot("tp_vectorcall_offset"),
1176
+ EmptySlot("tp_getattr"),
1177
+ EmptySlot("tp_setattr"),
1178
+
1179
+ SuiteSlot(self. PyAsyncMethods, "__Pyx_PyAsyncMethodsStruct", "tp_as_async",
1180
+ self.substructures, cast_cname="PyAsyncMethods"),
1181
+
1182
+ MethodSlot(reprfunc, "tp_repr", "__repr__", method_name_to_slot),
1183
+
1184
+ SuiteSlot(self.PyNumberMethods, "PyNumberMethods", "tp_as_number", self.substructures),
1185
+ SuiteSlot(self.PySequenceMethods, "PySequenceMethods", "tp_as_sequence", self.substructures),
1186
+ SuiteSlot(self.PyMappingMethods, "PyMappingMethods", "tp_as_mapping", self.substructures),
1187
+
1188
+ MethodSlot(hashfunc, "tp_hash", "__hash__", method_name_to_slot,
1189
+ inherited=False), # Py3 checks for __richcmp__
1190
+ MethodSlot(callfunc, "tp_call", "__call__", method_name_to_slot),
1191
+ MethodSlot(reprfunc, "tp_str", "__str__", method_name_to_slot),
1192
+
1193
+ SyntheticSlot("tp_getattro", ["__getattr__","__getattribute__"], "0"), #"PyObject_GenericGetAttr"),
1194
+ SyntheticSlot("tp_setattro", ["__setattr__", "__delattr__"], "0"), #"PyObject_GenericSetAttr"),
1195
+
1196
+ SuiteSlot(self.PyBufferProcs, "PyBufferProcs", "tp_as_buffer", self.substructures),
1197
+
1198
+ TypeFlagsSlot("tp_flags"),
1199
+ DocStringSlot("tp_doc"),
1200
+
1201
+ GCDependentSlot("tp_traverse"),
1202
+ GCClearReferencesSlot("tp_clear"),
1203
+
1204
+ RichcmpSlot(richcmpfunc, "tp_richcompare", "__richcmp__", method_name_to_slot,
1205
+ inherited=False), # Py3 checks for __hash__
1206
+
1207
+ EmptySlot("tp_weaklistoffset"),
1208
+
1209
+ MethodSlot(getiterfunc, "tp_iter", "__iter__", method_name_to_slot),
1210
+ MethodSlot(iternextfunc, "tp_iternext", "__next__", method_name_to_slot),
1211
+
1212
+ MethodTableSlot("tp_methods"),
1213
+ MemberTableSlot("tp_members"),
1214
+ GetSetSlot("tp_getset"),
1215
+
1216
+ BaseClassSlot("tp_base"), #EmptySlot("tp_base"),
1217
+ EmptySlot("tp_dict"),
1218
+
1219
+ SyntheticSlot("tp_descr_get", ["__get__"], "0"),
1220
+ SyntheticSlot("tp_descr_set", ["__set__", "__delete__"], "0"),
1221
+
1222
+ DictOffsetSlot("tp_dictoffset", ifdef="!CYTHON_USE_TYPE_SPECS"), # otherwise set via "__dictoffset__" member
1223
+
1224
+ InitSlot(initproc, "tp_init", "__init__", method_name_to_slot),
1225
+ EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"),
1226
+ ConstructorSlot("tp_new", "__cinit__"),
1227
+ EmptySlot("tp_free"),
1228
+
1229
+ EmptySlot("tp_is_gc"),
1230
+ EmptySlot("tp_bases"),
1231
+ EmptySlot("tp_mro"),
1232
+ EmptySlot("tp_cache"),
1233
+ EmptySlot("tp_subclasses"),
1234
+ EmptySlot("tp_weaklist"),
1235
+ EmptySlot("tp_del"),
1236
+ EmptySlot("tp_version_tag"),
1237
+ SyntheticSlot("tp_finalize", ["__del__"], "0",
1238
+ used_ifdef="CYTHON_USE_TP_FINALIZE"),
1239
+ TpVectorcallSlot("tp_vectorcall",
1240
+ ifdef="(!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) && "
1241
+ "(!CYTHON_COMPILING_IN_LIMITED_API || __PYX_LIMITED_VERSION_HEX >= 0x030E0000)",
1242
+ used_ifdef="CYTHON_VECTORCALL_TPNEW"),
1243
+ EmptySlot("tp_print", ifdef="__PYX_NEED_TP_PRINT_SLOT == 1"),
1244
+ EmptySlot("tp_watched", ifdef="PY_VERSION_HEX >= 0x030C0000"),
1245
+ EmptySlot("tp_versions_used", ifdef="PY_VERSION_HEX >= 0x030d00A4"),
1246
+ # PyPy specific extension - only here to avoid C compiler warnings.
1247
+ EmptySlot("tp_pypy_flags", ifdef="CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x030a0000"),
1248
+ )
1249
+
1250
+ #------------------------------------------------------------------------------------------
1251
+ #
1252
+ # Descriptors for special methods which don't appear directly
1253
+ # in the type object or its substructures. These methods are
1254
+ # called from slot functions synthesized by Cython.
1255
+ #
1256
+ #------------------------------------------------------------------------------------------
1257
+
1258
+ MethodSlot(initproc, "", "__cinit__", method_name_to_slot)
1259
+ MethodSlot(destructor, "", "__dealloc__", method_name_to_slot)
1260
+ MethodSlot(destructor, "", "__del__", method_name_to_slot)
1261
+ MethodSlot(objargfunc, "", "__getitem__", method_name_to_slot)
1262
+ MethodSlot(objobjargproc, "", "__setitem__", method_name_to_slot)
1263
+ MethodSlot(objargproc, "", "__delitem__", method_name_to_slot)
1264
+ MethodSlot(ssizessizeobjargproc, "", "__setslice__", method_name_to_slot)
1265
+ MethodSlot(ssizessizeargproc, "", "__delslice__", method_name_to_slot)
1266
+ MethodSlot(getattrofunc, "", "__getattr__", method_name_to_slot)
1267
+ MethodSlot(getattrofunc, "", "__getattribute__", method_name_to_slot)
1268
+ MethodSlot(setattrofunc, "", "__setattr__", method_name_to_slot)
1269
+ MethodSlot(delattrofunc, "", "__delattr__", method_name_to_slot)
1270
+ MethodSlot(descrgetfunc, "", "__get__", method_name_to_slot)
1271
+ MethodSlot(descrsetfunc, "", "__set__", method_name_to_slot)
1272
+ MethodSlot(descrdelfunc, "", "__delete__", method_name_to_slot)
1273
+
1274
+ #-------------------------------------------------------------------------
1275
+ #
1276
+ # Legacy "fallback" Py2 slots. Don't appear in the generated slot table,
1277
+ # but match the "fallback" argument of a slot that does
1278
+ #
1279
+ #-------------------------------------------------------------------------
1280
+ MethodSlot(inquiry, "", "__nonzero__", method_name_to_slot)
1281
+ MethodSlot(unaryfunc, "", "__long__", method_name_to_slot)
1282
+
1283
+ def get_special_method_signature(self, name):
1284
+ # Given a method name, if it is a special method,
1285
+ # return its signature, else return None.
1286
+ slot = self._get_slot_by_method_name(name)
1287
+ if slot:
1288
+ return slot.signature
1289
+ elif name in richcmp_special_methods:
1290
+ return ibinaryfunc
1291
+ else:
1292
+ return None
1293
+
1294
+ def get_slot_by_method_name(self, method_name):
1295
+ # For now, only search the type struct, no referenced sub-structs.
1296
+ return self._get_slot_by_method_name(method_name)
1297
+
1298
+ def __iter__(self):
1299
+ # make it easier to iterate over all the slots
1300
+ return iter(self.slot_table)
1301
+
1302
+
1303
+ _slot_table_dict = {}
1304
+
1305
+ def get_slot_table(compiler_directives):
1306
+ if not compiler_directives:
1307
+ # fetch default directives here since the builtin type classes don't have
1308
+ # directives set
1309
+ from .Options import get_directive_defaults
1310
+ compiler_directives = get_directive_defaults()
1311
+
1312
+ old_binops = compiler_directives['c_api_binop_methods']
1313
+ key = (old_binops,)
1314
+ if key not in _slot_table_dict:
1315
+ _slot_table_dict[key] = SlotTable(old_binops=old_binops)
1316
+ return _slot_table_dict[key]
1317
+
1318
+
1319
+ # Populate "special_method_names" based on the default directives (so it can always be accessed quickly).
1320
+ special_method_names = set(get_slot_table(compiler_directives=None))
1321
+
1322
+
1323
+ # Method flags for python-exposed methods.
1324
+
1325
+ method_noargs = "METH_NOARGS"
1326
+ method_onearg = "METH_O"
1327
+ method_varargs = "METH_VARARGS"
1328
+ method_fastcall = "__Pyx_METH_FASTCALL" # Actually VARARGS on versions < 3.7
1329
+ method_keywords = "METH_KEYWORDS"
1330
+ method_coexist = "METH_COEXIST"