Cython 3.1.0__py3-none-any.whl

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