Cython 3.1.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. Cython/Build/BuildExecutable.py +169 -0
  2. Cython/Build/Cache.py +199 -0
  3. Cython/Build/Cythonize.py +250 -0
  4. Cython/Build/Dependencies.py +1275 -0
  5. Cython/Build/Distutils.py +1 -0
  6. Cython/Build/Inline.py +342 -0
  7. Cython/Build/IpythonMagic.py +560 -0
  8. Cython/Build/Tests/TestCyCache.py +119 -0
  9. Cython/Build/Tests/TestCythonizeArgsParser.py +481 -0
  10. Cython/Build/Tests/TestDependencies.py +133 -0
  11. Cython/Build/Tests/TestInline.py +112 -0
  12. Cython/Build/Tests/TestIpythonMagic.py +287 -0
  13. Cython/Build/Tests/TestRecythonize.py +212 -0
  14. Cython/Build/Tests/TestStripLiterals.py +155 -0
  15. Cython/Build/Tests/__init__.py +1 -0
  16. Cython/Build/__init__.py +8 -0
  17. Cython/CodeWriter.py +811 -0
  18. Cython/Compiler/AnalysedTreeTransforms.py +97 -0
  19. Cython/Compiler/Annotate.py +326 -0
  20. Cython/Compiler/AutoDocTransforms.py +314 -0
  21. Cython/Compiler/Buffer.py +680 -0
  22. Cython/Compiler/Builtin.py +862 -0
  23. Cython/Compiler/CmdLine.py +243 -0
  24. Cython/Compiler/Code.pxd +145 -0
  25. Cython/Compiler/Code.py +3328 -0
  26. Cython/Compiler/CodeGeneration.py +33 -0
  27. Cython/Compiler/CythonScope.py +179 -0
  28. Cython/Compiler/Dataclass.py +868 -0
  29. Cython/Compiler/DebugFlags.py +21 -0
  30. Cython/Compiler/Errors.py +295 -0
  31. Cython/Compiler/ExprNodes.py +15051 -0
  32. Cython/Compiler/FlowControl.pxd +97 -0
  33. Cython/Compiler/FlowControl.py +1438 -0
  34. Cython/Compiler/FusedNode.py +998 -0
  35. Cython/Compiler/Future.py +16 -0
  36. Cython/Compiler/Interpreter.py +57 -0
  37. Cython/Compiler/Lexicon.py +340 -0
  38. Cython/Compiler/LineTable.py +114 -0
  39. Cython/Compiler/Main.py +779 -0
  40. Cython/Compiler/MatchCaseNodes.py +259 -0
  41. Cython/Compiler/MemoryView.py +860 -0
  42. Cython/Compiler/ModuleNode.py +4065 -0
  43. Cython/Compiler/Naming.py +369 -0
  44. Cython/Compiler/Nodes.py +10557 -0
  45. Cython/Compiler/Optimize.py +5269 -0
  46. Cython/Compiler/Options.py +828 -0
  47. Cython/Compiler/ParseTreeTransforms.pxd +78 -0
  48. Cython/Compiler/ParseTreeTransforms.py +4441 -0
  49. Cython/Compiler/Parsing.pxd +9 -0
  50. Cython/Compiler/Parsing.py +4797 -0
  51. Cython/Compiler/Pipeline.py +425 -0
  52. Cython/Compiler/PyrexTypes.py +5572 -0
  53. Cython/Compiler/Pythran.py +223 -0
  54. Cython/Compiler/Scanning.pxd +40 -0
  55. Cython/Compiler/Scanning.py +574 -0
  56. Cython/Compiler/StringEncoding.py +347 -0
  57. Cython/Compiler/Symtab.py +2998 -0
  58. Cython/Compiler/Tests/TestBuffer.py +105 -0
  59. Cython/Compiler/Tests/TestBuiltin.py +72 -0
  60. Cython/Compiler/Tests/TestCmdLine.py +573 -0
  61. Cython/Compiler/Tests/TestCode.py +86 -0
  62. Cython/Compiler/Tests/TestFlowControl.py +65 -0
  63. Cython/Compiler/Tests/TestGrammar.py +202 -0
  64. Cython/Compiler/Tests/TestMemView.py +71 -0
  65. Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
  66. Cython/Compiler/Tests/TestScanning.py +134 -0
  67. Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
  68. Cython/Compiler/Tests/TestStringEncoding.py +33 -0
  69. Cython/Compiler/Tests/TestTreeFragment.py +63 -0
  70. Cython/Compiler/Tests/TestTreePath.py +93 -0
  71. Cython/Compiler/Tests/TestTypes.py +75 -0
  72. Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
  73. Cython/Compiler/Tests/TestVisitor.py +61 -0
  74. Cython/Compiler/Tests/Utils.py +36 -0
  75. Cython/Compiler/Tests/__init__.py +1 -0
  76. Cython/Compiler/TreeFragment.py +278 -0
  77. Cython/Compiler/TreePath.py +290 -0
  78. Cython/Compiler/TypeInference.py +584 -0
  79. Cython/Compiler/TypeSlots.py +1181 -0
  80. Cython/Compiler/UFuncs.py +311 -0
  81. Cython/Compiler/UtilNodes.py +387 -0
  82. Cython/Compiler/UtilityCode.py +274 -0
  83. Cython/Compiler/Version.py +8 -0
  84. Cython/Compiler/Visitor.pxd +53 -0
  85. Cython/Compiler/Visitor.py +861 -0
  86. Cython/Compiler/__init__.py +1 -0
  87. Cython/Coverage.py +443 -0
  88. Cython/Debugger/Cygdb.py +179 -0
  89. Cython/Debugger/DebugWriter.py +82 -0
  90. Cython/Debugger/Tests/TestLibCython.py +275 -0
  91. Cython/Debugger/Tests/__init__.py +1 -0
  92. Cython/Debugger/Tests/cfuncs.c +8 -0
  93. Cython/Debugger/Tests/codefile +49 -0
  94. Cython/Debugger/Tests/test_libcython_in_gdb.py +578 -0
  95. Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
  96. Cython/Debugger/__init__.py +1 -0
  97. Cython/Debugger/libcython.py +1549 -0
  98. Cython/Debugger/libpython.py +2821 -0
  99. Cython/Debugging.py +20 -0
  100. Cython/Distutils/__init__.py +2 -0
  101. Cython/Distutils/build_ext.py +137 -0
  102. Cython/Distutils/extension.py +96 -0
  103. Cython/Distutils/old_build_ext.py +351 -0
  104. Cython/Includes/cpython/__init__.pxd +173 -0
  105. Cython/Includes/cpython/array.pxd +174 -0
  106. Cython/Includes/cpython/bool.pxd +37 -0
  107. Cython/Includes/cpython/buffer.pxd +112 -0
  108. Cython/Includes/cpython/bytearray.pxd +33 -0
  109. Cython/Includes/cpython/bytes.pxd +200 -0
  110. Cython/Includes/cpython/cellobject.pxd +35 -0
  111. Cython/Includes/cpython/ceval.pxd +8 -0
  112. Cython/Includes/cpython/codecs.pxd +121 -0
  113. Cython/Includes/cpython/complex.pxd +55 -0
  114. Cython/Includes/cpython/contextvars.pxd +141 -0
  115. Cython/Includes/cpython/conversion.pxd +36 -0
  116. Cython/Includes/cpython/datetime.pxd +384 -0
  117. Cython/Includes/cpython/descr.pxd +26 -0
  118. Cython/Includes/cpython/dict.pxd +187 -0
  119. Cython/Includes/cpython/exc.pxd +263 -0
  120. Cython/Includes/cpython/fileobject.pxd +57 -0
  121. Cython/Includes/cpython/float.pxd +47 -0
  122. Cython/Includes/cpython/function.pxd +65 -0
  123. Cython/Includes/cpython/genobject.pxd +25 -0
  124. Cython/Includes/cpython/getargs.pxd +12 -0
  125. Cython/Includes/cpython/instance.pxd +25 -0
  126. Cython/Includes/cpython/iterator.pxd +36 -0
  127. Cython/Includes/cpython/iterobject.pxd +24 -0
  128. Cython/Includes/cpython/list.pxd +92 -0
  129. Cython/Includes/cpython/long.pxd +149 -0
  130. Cython/Includes/cpython/longintrepr.pxd +19 -0
  131. Cython/Includes/cpython/mapping.pxd +63 -0
  132. Cython/Includes/cpython/marshal.pxd +66 -0
  133. Cython/Includes/cpython/mem.pxd +120 -0
  134. Cython/Includes/cpython/memoryview.pxd +50 -0
  135. Cython/Includes/cpython/method.pxd +49 -0
  136. Cython/Includes/cpython/module.pxd +208 -0
  137. Cython/Includes/cpython/number.pxd +258 -0
  138. Cython/Includes/cpython/object.pxd +433 -0
  139. Cython/Includes/cpython/pycapsule.pxd +143 -0
  140. Cython/Includes/cpython/pylifecycle.pxd +68 -0
  141. Cython/Includes/cpython/pyport.pxd +8 -0
  142. Cython/Includes/cpython/pystate.pxd +95 -0
  143. Cython/Includes/cpython/pythread.pxd +53 -0
  144. Cython/Includes/cpython/ref.pxd +67 -0
  145. Cython/Includes/cpython/sequence.pxd +134 -0
  146. Cython/Includes/cpython/set.pxd +119 -0
  147. Cython/Includes/cpython/slice.pxd +70 -0
  148. Cython/Includes/cpython/time.pxd +129 -0
  149. Cython/Includes/cpython/tuple.pxd +72 -0
  150. Cython/Includes/cpython/type.pxd +53 -0
  151. Cython/Includes/cpython/unicode.pxd +639 -0
  152. Cython/Includes/cpython/version.pxd +32 -0
  153. Cython/Includes/cpython/weakref.pxd +42 -0
  154. Cython/Includes/libc/__init__.pxd +1 -0
  155. Cython/Includes/libc/complex.pxd +35 -0
  156. Cython/Includes/libc/errno.pxd +127 -0
  157. Cython/Includes/libc/float.pxd +43 -0
  158. Cython/Includes/libc/limits.pxd +28 -0
  159. Cython/Includes/libc/locale.pxd +46 -0
  160. Cython/Includes/libc/math.pxd +209 -0
  161. Cython/Includes/libc/setjmp.pxd +10 -0
  162. Cython/Includes/libc/signal.pxd +64 -0
  163. Cython/Includes/libc/stddef.pxd +9 -0
  164. Cython/Includes/libc/stdint.pxd +105 -0
  165. Cython/Includes/libc/stdio.pxd +80 -0
  166. Cython/Includes/libc/stdlib.pxd +72 -0
  167. Cython/Includes/libc/string.pxd +50 -0
  168. Cython/Includes/libc/time.pxd +47 -0
  169. Cython/Includes/libcpp/__init__.pxd +4 -0
  170. Cython/Includes/libcpp/algorithm.pxd +320 -0
  171. Cython/Includes/libcpp/any.pxd +16 -0
  172. Cython/Includes/libcpp/atomic.pxd +59 -0
  173. Cython/Includes/libcpp/bit.pxd +29 -0
  174. Cython/Includes/libcpp/cast.pxd +12 -0
  175. Cython/Includes/libcpp/cmath.pxd +518 -0
  176. Cython/Includes/libcpp/complex.pxd +106 -0
  177. Cython/Includes/libcpp/deque.pxd +165 -0
  178. Cython/Includes/libcpp/execution.pxd +15 -0
  179. Cython/Includes/libcpp/forward_list.pxd +63 -0
  180. Cython/Includes/libcpp/functional.pxd +26 -0
  181. Cython/Includes/libcpp/iterator.pxd +34 -0
  182. Cython/Includes/libcpp/limits.pxd +61 -0
  183. Cython/Includes/libcpp/list.pxd +117 -0
  184. Cython/Includes/libcpp/map.pxd +252 -0
  185. Cython/Includes/libcpp/memory.pxd +115 -0
  186. Cython/Includes/libcpp/numbers.pxd +15 -0
  187. Cython/Includes/libcpp/numeric.pxd +131 -0
  188. Cython/Includes/libcpp/optional.pxd +34 -0
  189. Cython/Includes/libcpp/pair.pxd +1 -0
  190. Cython/Includes/libcpp/queue.pxd +25 -0
  191. Cython/Includes/libcpp/random.pxd +166 -0
  192. Cython/Includes/libcpp/set.pxd +228 -0
  193. Cython/Includes/libcpp/stack.pxd +11 -0
  194. Cython/Includes/libcpp/string.pxd +333 -0
  195. Cython/Includes/libcpp/typeindex.pxd +15 -0
  196. Cython/Includes/libcpp/typeinfo.pxd +10 -0
  197. Cython/Includes/libcpp/unordered_map.pxd +193 -0
  198. Cython/Includes/libcpp/unordered_set.pxd +152 -0
  199. Cython/Includes/libcpp/utility.pxd +30 -0
  200. Cython/Includes/libcpp/vector.pxd +167 -0
  201. Cython/Includes/openmp.pxd +50 -0
  202. Cython/Includes/posix/__init__.pxd +1 -0
  203. Cython/Includes/posix/dlfcn.pxd +14 -0
  204. Cython/Includes/posix/fcntl.pxd +86 -0
  205. Cython/Includes/posix/ioctl.pxd +4 -0
  206. Cython/Includes/posix/mman.pxd +101 -0
  207. Cython/Includes/posix/resource.pxd +57 -0
  208. Cython/Includes/posix/select.pxd +21 -0
  209. Cython/Includes/posix/signal.pxd +73 -0
  210. Cython/Includes/posix/stat.pxd +98 -0
  211. Cython/Includes/posix/stdio.pxd +37 -0
  212. Cython/Includes/posix/stdlib.pxd +29 -0
  213. Cython/Includes/posix/strings.pxd +9 -0
  214. Cython/Includes/posix/time.pxd +71 -0
  215. Cython/Includes/posix/types.pxd +30 -0
  216. Cython/Includes/posix/uio.pxd +26 -0
  217. Cython/Includes/posix/unistd.pxd +271 -0
  218. Cython/Includes/posix/wait.pxd +38 -0
  219. Cython/Plex/Actions.pxd +24 -0
  220. Cython/Plex/Actions.py +119 -0
  221. Cython/Plex/DFA.pxd +14 -0
  222. Cython/Plex/DFA.py +164 -0
  223. Cython/Plex/Errors.py +48 -0
  224. Cython/Plex/Lexicons.py +178 -0
  225. Cython/Plex/Machines.pxd +36 -0
  226. Cython/Plex/Machines.py +238 -0
  227. Cython/Plex/Regexps.py +539 -0
  228. Cython/Plex/Scanners.pxd +47 -0
  229. Cython/Plex/Scanners.py +360 -0
  230. Cython/Plex/Transitions.pxd +14 -0
  231. Cython/Plex/Transitions.py +239 -0
  232. Cython/Plex/__init__.py +34 -0
  233. Cython/Runtime/__init__.py +1 -0
  234. Cython/Runtime/refnanny.pyx +261 -0
  235. Cython/Shadow.py +656 -0
  236. Cython/Shadow.pyi +521 -0
  237. Cython/StringIOTree.py +170 -0
  238. Cython/Tempita/__init__.py +4 -0
  239. Cython/Tempita/_looper.py +154 -0
  240. Cython/Tempita/_tempita.py +1091 -0
  241. Cython/TestUtils.py +417 -0
  242. Cython/Tests/TestCodeWriter.py +128 -0
  243. Cython/Tests/TestCythonUtils.py +202 -0
  244. Cython/Tests/TestJediTyper.py +223 -0
  245. Cython/Tests/TestShadow.py +114 -0
  246. Cython/Tests/TestStringIOTree.py +67 -0
  247. Cython/Tests/TestTestUtils.py +90 -0
  248. Cython/Tests/__init__.py +1 -0
  249. Cython/Tests/xmlrunner.py +390 -0
  250. Cython/Utility/AsyncGen.c +1263 -0
  251. Cython/Utility/Buffer.c +875 -0
  252. Cython/Utility/Builtins.c +660 -0
  253. Cython/Utility/CConvert.pyx +134 -0
  254. Cython/Utility/CMath.c +95 -0
  255. Cython/Utility/CommonStructures.c +139 -0
  256. Cython/Utility/Complex.c +378 -0
  257. Cython/Utility/Coroutine.c +2413 -0
  258. Cython/Utility/CpdefEnums.pyx +108 -0
  259. Cython/Utility/CppConvert.pyx +279 -0
  260. Cython/Utility/CppSupport.cpp +133 -0
  261. Cython/Utility/CythonFunction.c +1851 -0
  262. Cython/Utility/Dataclasses.c +185 -0
  263. Cython/Utility/Dataclasses.py +112 -0
  264. Cython/Utility/Embed.c +125 -0
  265. Cython/Utility/Exceptions.c +1017 -0
  266. Cython/Utility/ExtensionTypes.c +797 -0
  267. Cython/Utility/FunctionArguments.c +573 -0
  268. Cython/Utility/ImportExport.c +912 -0
  269. Cython/Utility/MemoryView.pyx +1478 -0
  270. Cython/Utility/MemoryView_C.c +992 -0
  271. Cython/Utility/ModuleSetupCode.c +2501 -0
  272. Cython/Utility/NumpyImportArray.c +46 -0
  273. Cython/Utility/ObjectHandling.c +3054 -0
  274. Cython/Utility/Optimize.c +1533 -0
  275. Cython/Utility/Overflow.c +404 -0
  276. Cython/Utility/Printing.c +86 -0
  277. Cython/Utility/Profile.c +660 -0
  278. Cython/Utility/StringTools.c +1206 -0
  279. Cython/Utility/TestCyUtilityLoader.pyx +8 -0
  280. Cython/Utility/TestCythonScope.pyx +75 -0
  281. Cython/Utility/TestUtilityLoader.c +12 -0
  282. Cython/Utility/TypeConversion.c +1329 -0
  283. Cython/Utility/UFuncs.pyx +50 -0
  284. Cython/Utility/UFuncs_C.c +89 -0
  285. Cython/Utility/__init__.py +28 -0
  286. Cython/Utility/arrayarray.h +143 -0
  287. Cython/Utils.py +687 -0
  288. Cython/__init__.py +10 -0
  289. Cython/__init__.pyi +7 -0
  290. Cython/py.typed +0 -0
  291. Cython-3.1.0a1.dist-info/COPYING.txt +19 -0
  292. Cython-3.1.0a1.dist-info/LICENSE.txt +176 -0
  293. Cython-3.1.0a1.dist-info/METADATA +67 -0
  294. Cython-3.1.0a1.dist-info/RECORD +301 -0
  295. Cython-3.1.0a1.dist-info/WHEEL +5 -0
  296. Cython-3.1.0a1.dist-info/entry_points.txt +4 -0
  297. Cython-3.1.0a1.dist-info/top_level.txt +3 -0
  298. cython.py +29 -0
  299. pyximport/__init__.py +4 -0
  300. pyximport/pyxbuild.py +160 -0
  301. pyximport/pyximport.py +482 -0
@@ -0,0 +1,261 @@
1
+ # cython: language_level=3, auto_pickle=False
2
+
3
+ from cpython.ref cimport PyObject, Py_INCREF, Py_CLEAR, Py_XDECREF, Py_XINCREF
4
+ from cpython.exc cimport PyErr_Fetch, PyErr_Restore
5
+ from cpython.pystate cimport PyThreadState_Get
6
+
7
+ cimport cython
8
+
9
+ cdef extern from *:
10
+ """
11
+ #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING
12
+ static CYTHON_INLINE int __Pyx_refnanny_init_lock(PyThread_type_lock* lock) {
13
+ *lock = PyThread_allocate_lock();
14
+ if (!*lock) {
15
+ PyErr_NoMemory();
16
+ return -1;
17
+ }
18
+ return 0;
19
+ }
20
+
21
+ static CYTHON_INLINE void __Pyx_refnanny_free_lock(PyThread_type_lock lock) {
22
+ PyThread_free_lock(lock);
23
+ }
24
+
25
+ static CYTHON_INLINE void __Pyx_refnanny_lock_acquire(PyThread_type_lock lock) {
26
+ while (!PyThread_acquire_lock_timed(lock, 100, 0)) {
27
+ // If we can't get the lock, release and acquire the GIL to avoid
28
+ // deadlocking.
29
+ Py_BEGIN_ALLOW_THREADS
30
+ Py_END_ALLOW_THREADS
31
+ }
32
+ }
33
+
34
+ static CYTHON_INLINE void __Pyx_refnanny_lock_release(PyThread_type_lock lock) {
35
+ PyThread_release_lock(lock);
36
+ }
37
+ #else
38
+ #define __Pyx_refnanny_init_lock(lock) 0
39
+ #define __Pyx_refnanny_free_lock(lock)
40
+ #define __Pyx_refnanny_lock_acquire(lock)
41
+ #define __Pyx_refnanny_lock_release(lock)
42
+ #endif
43
+ """
44
+ ctypedef void *PyThread_type_lock
45
+ int __Pyx_refnanny_init_lock(PyThread_type_lock* lock) except -1
46
+ void __Pyx_refnanny_free_lock(PyThread_type_lock lock)
47
+ void __Pyx_refnanny_lock_acquire(PyThread_type_lock lock)
48
+ void __Pyx_refnanny_lock_release(PyThread_type_lock lock)
49
+
50
+ loglevel = 0
51
+ reflog = []
52
+
53
+ cdef int log(int level, action, obj, lineno) except -1:
54
+ if (<int> loglevel) >= level:
55
+ if reflog is None:
56
+ # can happen during finalisation
57
+ return 0
58
+ reflog.append((lineno, action, id(obj)))
59
+ return 0
60
+
61
+ LOG_NONE, LOG_ALL = range(2)
62
+ cdef int _LOG_NONE = LOG_NONE
63
+ cdef int _LOG_ALL = LOG_ALL
64
+
65
+ cdef object NO_REFS = (0, None)
66
+
67
+
68
+ @cython.final
69
+ cdef class Context(object):
70
+ cdef readonly object name, filename
71
+ cdef readonly dict refs
72
+ cdef readonly list errors
73
+ cdef readonly Py_ssize_t start
74
+ cdef PyThread_type_lock lock
75
+
76
+ def __cinit__(self, name, line=0, filename=None):
77
+ __Pyx_refnanny_init_lock(&self.lock)
78
+ self.name = name
79
+ self.start = line
80
+ self.filename = filename
81
+ self.refs = {} # id -> (count, [lineno])
82
+ self.errors = []
83
+
84
+ def __dealloc__(self):
85
+ __Pyx_refnanny_free_lock(self.lock)
86
+
87
+ cdef void acquire_lock(self) noexcept:
88
+ __Pyx_refnanny_lock_acquire(self.lock)
89
+
90
+ cdef void release_lock(self) noexcept:
91
+ __Pyx_refnanny_lock_release(self.lock)
92
+
93
+ cdef int regref(self, obj, Py_ssize_t lineno, bint is_null) except -1:
94
+ log(_LOG_ALL, u'regref', u"<NULL>" if is_null else obj, lineno)
95
+ if is_null:
96
+ self.errors.append(f"NULL argument on line {lineno}")
97
+ return 0
98
+ id_ = id(obj)
99
+ count, linenumbers = self.refs.get(id_, NO_REFS)
100
+ if linenumbers is None:
101
+ linenumbers = []
102
+ self.refs[id_] = (count + 1, linenumbers)
103
+ linenumbers.append(lineno)
104
+ return 0
105
+
106
+ cdef bint delref(self, obj, Py_ssize_t lineno, bint is_null) except -1:
107
+ # returns whether it is ok to do the decref operation
108
+ log(_LOG_ALL, u'delref', u"<NULL>" if is_null else obj, lineno)
109
+ if is_null:
110
+ self.errors.append(f"NULL argument on line {lineno}")
111
+ return False
112
+ id_ = id(obj)
113
+ count, linenumbers = self.refs.get(id_, NO_REFS)
114
+ if linenumbers is None:
115
+ linenumbers = []
116
+ if count == 0:
117
+ self.errors.append(f"Too many decrefs on line {lineno}, reference acquired on lines {linenumbers!r}")
118
+ return False
119
+ if count == 1:
120
+ del self.refs[id_]
121
+ else:
122
+ self.refs[id_] = (count - 1, linenumbers)
123
+ return True
124
+
125
+ cdef end(self):
126
+ if self.refs:
127
+ msg = u"References leaked:"
128
+ for count, linenos in self.refs.values():
129
+ msg += f"\n ({count}) acquired on lines: {u', '.join([f'{x}' for x in linenos])}"
130
+ self.errors.append(msg)
131
+ return u"\n".join([f'REFNANNY: {error}' for error in self.errors]) if self.errors else None
132
+
133
+
134
+ cdef void report_unraisable(filename, Py_ssize_t lineno, object e=None) noexcept:
135
+ try:
136
+ if e is None:
137
+ import sys
138
+ e = sys.exc_info()[1]
139
+ print(f"refnanny raised an exception from {filename}:{lineno}: {e}")
140
+ finally:
141
+ return # We absolutely cannot exit with an exception
142
+
143
+
144
+ # All Python operations must happen after any existing
145
+ # exception has been fetched, in case we are called from
146
+ # exception-handling code.
147
+
148
+ cdef PyObject* SetupContext(char* funcname, Py_ssize_t lineno, char* filename) except NULL:
149
+ if Context is None:
150
+ # Context may be None during finalize phase.
151
+ # In that case, we don't want to be doing anything fancy
152
+ # like caching and resetting exceptions.
153
+ return NULL
154
+ cdef (PyObject*) type = NULL, value = NULL, tb = NULL, result = NULL
155
+ PyThreadState_Get() # Check that we hold the GIL
156
+ PyErr_Fetch(&type, &value, &tb)
157
+ try:
158
+ ctx = Context.__new__(Context, funcname, lineno, filename)
159
+ Py_INCREF(ctx)
160
+ result = <PyObject*>ctx
161
+ except Exception, e:
162
+ report_unraisable(filename, lineno, e)
163
+ PyErr_Restore(type, value, tb)
164
+ return result
165
+
166
+ cdef void GOTREF(PyObject* _ctx, PyObject* p_obj, Py_ssize_t lineno):
167
+ if _ctx == NULL: return
168
+ cdef (PyObject*) type = NULL, value = NULL, tb = NULL
169
+ cdef Context ctx = <Context> _ctx
170
+ ctx.acquire_lock()
171
+ PyErr_Fetch(&type, &value, &tb)
172
+ try:
173
+ ctx.regref(
174
+ <object>p_obj if p_obj is not NULL else None,
175
+ lineno,
176
+ is_null=p_obj is NULL,
177
+ )
178
+ except:
179
+ report_unraisable(ctx.filename, lineno=ctx.start)
180
+ finally:
181
+ PyErr_Restore(type, value, tb)
182
+ ctx.release_lock()
183
+ return # swallow any exceptions
184
+
185
+ cdef bint GIVEREF_and_report(PyObject* _ctx, PyObject* p_obj, Py_ssize_t lineno):
186
+ if _ctx == NULL: return 1
187
+ cdef (PyObject*) type = NULL, value = NULL, tb = NULL
188
+ cdef bint decref_ok = False
189
+ cdef Context ctx = <Context> _ctx
190
+ ctx.acquire_lock()
191
+ PyErr_Fetch(&type, &value, &tb)
192
+ try:
193
+ decref_ok = ctx.delref(
194
+ <object>p_obj if p_obj is not NULL else None,
195
+ lineno,
196
+ is_null=p_obj is NULL,
197
+ )
198
+ except:
199
+ report_unraisable(ctx.filename, lineno=ctx.start)
200
+ finally:
201
+ PyErr_Restore(type, value, tb)
202
+ ctx.release_lock()
203
+ return decref_ok # swallow any exceptions
204
+
205
+ cdef void GIVEREF(PyObject* ctx, PyObject* p_obj, Py_ssize_t lineno):
206
+ GIVEREF_and_report(ctx, p_obj, lineno)
207
+
208
+ cdef void INCREF(PyObject* ctx, PyObject* obj, Py_ssize_t lineno):
209
+ Py_XINCREF(obj)
210
+ PyThreadState_Get() # Check that we hold the GIL
211
+ GOTREF(ctx, obj, lineno)
212
+
213
+ cdef void DECREF(PyObject* ctx, PyObject* obj, Py_ssize_t lineno):
214
+ if GIVEREF_and_report(ctx, obj, lineno):
215
+ Py_XDECREF(obj)
216
+ PyThreadState_Get() # Check that we hold the GIL
217
+
218
+ cdef void FinishContext(PyObject** ctx):
219
+ if ctx == NULL or ctx[0] == NULL: return
220
+ cdef (PyObject*) type = NULL, value = NULL, tb = NULL
221
+ cdef object errors = None
222
+ cdef Context context
223
+ PyThreadState_Get() # Check that we hold the GIL
224
+ PyErr_Fetch(&type, &value, &tb)
225
+ try:
226
+ context = <Context>ctx[0]
227
+ errors = context.end()
228
+ if errors:
229
+ print(f"{context.filename.decode('latin1')}: {context.name.decode('latin1')}()")
230
+ print(errors)
231
+ context = None
232
+ except:
233
+ report_unraisable(
234
+ context.filename if context is not None else None,
235
+ lineno=context.start if context is not None else 0,
236
+ )
237
+ finally:
238
+ Py_CLEAR(ctx[0])
239
+ PyErr_Restore(type, value, tb)
240
+ return # swallow any exceptions
241
+
242
+ ctypedef struct RefNannyAPIStruct:
243
+ void (*INCREF)(PyObject*, PyObject*, Py_ssize_t)
244
+ void (*DECREF)(PyObject*, PyObject*, Py_ssize_t)
245
+ void (*GOTREF)(PyObject*, PyObject*, Py_ssize_t)
246
+ void (*GIVEREF)(PyObject*, PyObject*, Py_ssize_t)
247
+ PyObject* (*SetupContext)(char*, Py_ssize_t, char*) except NULL
248
+ void (*FinishContext)(PyObject**)
249
+
250
+ cdef RefNannyAPIStruct api
251
+ api.INCREF = INCREF
252
+ api.DECREF = DECREF
253
+ api.GOTREF = GOTREF
254
+ api.GIVEREF = GIVEREF
255
+ api.SetupContext = SetupContext
256
+ api.FinishContext = FinishContext
257
+
258
+ cdef extern from "Python.h":
259
+ object PyLong_FromVoidPtr(void*)
260
+
261
+ RefNannyAPI = PyLong_FromVoidPtr(<void*>&api)