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.
- Cython/Build/BuildExecutable.py +169 -0
- Cython/Build/Cache.py +199 -0
- Cython/Build/Cythonize.py +323 -0
- Cython/Build/Dependencies.py +1306 -0
- Cython/Build/Distutils.py +1 -0
- Cython/Build/Inline.py +463 -0
- Cython/Build/IpythonMagic.py +560 -0
- Cython/Build/SharedModule.py +76 -0
- Cython/Build/Tests/TestCyCache.py +194 -0
- Cython/Build/Tests/TestCythonizeArgsParser.py +481 -0
- Cython/Build/Tests/TestDependencies.py +133 -0
- Cython/Build/Tests/TestInline.py +177 -0
- Cython/Build/Tests/TestIpythonMagic.py +287 -0
- Cython/Build/Tests/TestRecythonize.py +212 -0
- Cython/Build/Tests/TestStripLiterals.py +155 -0
- Cython/Build/Tests/__init__.py +1 -0
- Cython/Build/__init__.py +8 -0
- Cython/CodeWriter.py +811 -0
- Cython/Compiler/AnalysedTreeTransforms.py +97 -0
- Cython/Compiler/Annotate.py +326 -0
- Cython/Compiler/AutoDocTransforms.py +320 -0
- Cython/Compiler/Buffer.py +680 -0
- Cython/Compiler/Builtin.py +934 -0
- Cython/Compiler/CmdLine.py +259 -0
- Cython/Compiler/Code.pxd +148 -0
- Cython/Compiler/Code.py +3375 -0
- Cython/Compiler/CodeGeneration.py +33 -0
- Cython/Compiler/CythonScope.py +187 -0
- Cython/Compiler/Dataclass.py +868 -0
- Cython/Compiler/DebugFlags.py +24 -0
- Cython/Compiler/Errors.py +295 -0
- Cython/Compiler/ExprNodes.py +15267 -0
- Cython/Compiler/FlowControl.pxd +97 -0
- Cython/Compiler/FlowControl.py +1455 -0
- Cython/Compiler/FusedNode.py +1002 -0
- Cython/Compiler/Future.py +16 -0
- Cython/Compiler/Interpreter.py +57 -0
- Cython/Compiler/Lexicon.py +340 -0
- Cython/Compiler/LineTable.py +114 -0
- Cython/Compiler/Main.py +853 -0
- Cython/Compiler/MatchCaseNodes.py +259 -0
- Cython/Compiler/MemoryView.py +922 -0
- Cython/Compiler/ModuleNode.py +4024 -0
- Cython/Compiler/Naming.py +374 -0
- Cython/Compiler/Nodes.py +10826 -0
- Cython/Compiler/Optimize.py +5256 -0
- Cython/Compiler/Options.py +835 -0
- Cython/Compiler/ParseTreeTransforms.pxd +77 -0
- Cython/Compiler/ParseTreeTransforms.py +4509 -0
- Cython/Compiler/Parsing.pxd +9 -0
- Cython/Compiler/Parsing.py +4789 -0
- Cython/Compiler/Pipeline.py +439 -0
- Cython/Compiler/PyrexTypes.py +5762 -0
- Cython/Compiler/Pythran.py +232 -0
- Cython/Compiler/Scanning.pxd +40 -0
- Cython/Compiler/Scanning.py +577 -0
- Cython/Compiler/StringEncoding.py +347 -0
- Cython/Compiler/Symtab.py +3080 -0
- Cython/Compiler/Tests/TestBuffer.py +105 -0
- Cython/Compiler/Tests/TestBuiltin.py +72 -0
- Cython/Compiler/Tests/TestCmdLine.py +586 -0
- Cython/Compiler/Tests/TestCode.py +86 -0
- Cython/Compiler/Tests/TestFlowControl.py +65 -0
- Cython/Compiler/Tests/TestGrammar.py +202 -0
- Cython/Compiler/Tests/TestMemView.py +71 -0
- Cython/Compiler/Tests/TestParseTreeTransforms.py +285 -0
- Cython/Compiler/Tests/TestScanning.py +134 -0
- Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
- Cython/Compiler/Tests/TestStringEncoding.py +33 -0
- Cython/Compiler/Tests/TestTreeFragment.py +63 -0
- Cython/Compiler/Tests/TestTreePath.py +103 -0
- Cython/Compiler/Tests/TestTypes.py +75 -0
- Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
- Cython/Compiler/Tests/TestVisitor.py +61 -0
- Cython/Compiler/Tests/Utils.py +36 -0
- Cython/Compiler/Tests/__init__.py +1 -0
- Cython/Compiler/TreeFragment.py +278 -0
- Cython/Compiler/TreePath.py +303 -0
- Cython/Compiler/TypeInference.py +584 -0
- Cython/Compiler/TypeSlots.py +1181 -0
- Cython/Compiler/UFuncs.py +311 -0
- Cython/Compiler/UtilNodes.py +389 -0
- Cython/Compiler/UtilityCode.py +344 -0
- Cython/Compiler/Version.py +8 -0
- Cython/Compiler/Visitor.pxd +53 -0
- Cython/Compiler/Visitor.py +861 -0
- Cython/Compiler/__init__.py +1 -0
- Cython/Coverage.py +448 -0
- Cython/Debugger/Cygdb.py +175 -0
- Cython/Debugger/DebugWriter.py +82 -0
- Cython/Debugger/Tests/TestLibCython.py +275 -0
- Cython/Debugger/Tests/__init__.py +1 -0
- Cython/Debugger/Tests/cfuncs.c +8 -0
- Cython/Debugger/Tests/codefile +49 -0
- Cython/Debugger/Tests/test_libcython_in_gdb.py +578 -0
- Cython/Debugger/Tests/test_libpython_in_gdb.py +90 -0
- Cython/Debugger/__init__.py +1 -0
- Cython/Debugger/libcython.py +1548 -0
- Cython/Debugger/libpython.py +2821 -0
- Cython/Debugging.py +20 -0
- Cython/Distutils/__init__.py +2 -0
- Cython/Distutils/build_ext.py +139 -0
- Cython/Distutils/extension.py +96 -0
- Cython/Distutils/old_build_ext.py +351 -0
- Cython/Includes/cpython/__init__.pxd +173 -0
- Cython/Includes/cpython/array.pxd +174 -0
- Cython/Includes/cpython/bool.pxd +37 -0
- Cython/Includes/cpython/buffer.pxd +112 -0
- Cython/Includes/cpython/bytearray.pxd +33 -0
- Cython/Includes/cpython/bytes.pxd +200 -0
- Cython/Includes/cpython/cellobject.pxd +35 -0
- Cython/Includes/cpython/ceval.pxd +8 -0
- Cython/Includes/cpython/codecs.pxd +121 -0
- Cython/Includes/cpython/complex.pxd +60 -0
- Cython/Includes/cpython/contextvars.pxd +145 -0
- Cython/Includes/cpython/conversion.pxd +36 -0
- Cython/Includes/cpython/datetime.pxd +395 -0
- Cython/Includes/cpython/descr.pxd +26 -0
- Cython/Includes/cpython/dict.pxd +187 -0
- Cython/Includes/cpython/exc.pxd +263 -0
- Cython/Includes/cpython/fileobject.pxd +57 -0
- Cython/Includes/cpython/float.pxd +47 -0
- Cython/Includes/cpython/function.pxd +65 -0
- Cython/Includes/cpython/genobject.pxd +25 -0
- Cython/Includes/cpython/getargs.pxd +12 -0
- Cython/Includes/cpython/instance.pxd +25 -0
- Cython/Includes/cpython/iterator.pxd +36 -0
- Cython/Includes/cpython/iterobject.pxd +24 -0
- Cython/Includes/cpython/list.pxd +92 -0
- Cython/Includes/cpython/long.pxd +149 -0
- Cython/Includes/cpython/longintrepr.pxd +14 -0
- Cython/Includes/cpython/mapping.pxd +63 -0
- Cython/Includes/cpython/marshal.pxd +66 -0
- Cython/Includes/cpython/mem.pxd +120 -0
- Cython/Includes/cpython/memoryview.pxd +50 -0
- Cython/Includes/cpython/method.pxd +49 -0
- Cython/Includes/cpython/module.pxd +208 -0
- Cython/Includes/cpython/number.pxd +258 -0
- Cython/Includes/cpython/object.pxd +433 -0
- Cython/Includes/cpython/pycapsule.pxd +143 -0
- Cython/Includes/cpython/pylifecycle.pxd +68 -0
- Cython/Includes/cpython/pyport.pxd +8 -0
- Cython/Includes/cpython/pystate.pxd +95 -0
- Cython/Includes/cpython/pythread.pxd +53 -0
- Cython/Includes/cpython/ref.pxd +67 -0
- Cython/Includes/cpython/sequence.pxd +134 -0
- Cython/Includes/cpython/set.pxd +119 -0
- Cython/Includes/cpython/slice.pxd +70 -0
- Cython/Includes/cpython/time.pxd +129 -0
- Cython/Includes/cpython/tuple.pxd +72 -0
- Cython/Includes/cpython/type.pxd +53 -0
- Cython/Includes/cpython/unicode.pxd +639 -0
- Cython/Includes/cpython/version.pxd +32 -0
- Cython/Includes/cpython/weakref.pxd +78 -0
- Cython/Includes/libc/__init__.pxd +1 -0
- Cython/Includes/libc/complex.pxd +35 -0
- Cython/Includes/libc/errno.pxd +127 -0
- Cython/Includes/libc/float.pxd +43 -0
- Cython/Includes/libc/limits.pxd +28 -0
- Cython/Includes/libc/locale.pxd +46 -0
- Cython/Includes/libc/math.pxd +209 -0
- Cython/Includes/libc/setjmp.pxd +10 -0
- Cython/Includes/libc/signal.pxd +64 -0
- Cython/Includes/libc/stddef.pxd +9 -0
- Cython/Includes/libc/stdint.pxd +105 -0
- Cython/Includes/libc/stdio.pxd +80 -0
- Cython/Includes/libc/stdlib.pxd +72 -0
- Cython/Includes/libc/string.pxd +50 -0
- Cython/Includes/libc/threads.pxd +84 -0
- Cython/Includes/libc/time.pxd +51 -0
- Cython/Includes/libcpp/__init__.pxd +4 -0
- Cython/Includes/libcpp/algorithm.pxd +320 -0
- Cython/Includes/libcpp/any.pxd +16 -0
- Cython/Includes/libcpp/atomic.pxd +59 -0
- Cython/Includes/libcpp/barrier.pxd +22 -0
- Cython/Includes/libcpp/bit.pxd +29 -0
- Cython/Includes/libcpp/cast.pxd +12 -0
- Cython/Includes/libcpp/cmath.pxd +518 -0
- Cython/Includes/libcpp/complex.pxd +106 -0
- Cython/Includes/libcpp/deque.pxd +165 -0
- Cython/Includes/libcpp/exception.pxd +86 -0
- Cython/Includes/libcpp/execution.pxd +15 -0
- Cython/Includes/libcpp/forward_list.pxd +63 -0
- Cython/Includes/libcpp/functional.pxd +26 -0
- Cython/Includes/libcpp/future.pxd +103 -0
- Cython/Includes/libcpp/iterator.pxd +34 -0
- Cython/Includes/libcpp/latch.pxd +17 -0
- Cython/Includes/libcpp/limits.pxd +61 -0
- Cython/Includes/libcpp/list.pxd +117 -0
- Cython/Includes/libcpp/map.pxd +252 -0
- Cython/Includes/libcpp/memory.pxd +115 -0
- Cython/Includes/libcpp/mutex.pxd +130 -0
- Cython/Includes/libcpp/numbers.pxd +15 -0
- Cython/Includes/libcpp/numeric.pxd +131 -0
- Cython/Includes/libcpp/optional.pxd +34 -0
- Cython/Includes/libcpp/pair.pxd +1 -0
- Cython/Includes/libcpp/queue.pxd +25 -0
- Cython/Includes/libcpp/random.pxd +166 -0
- Cython/Includes/libcpp/semaphore.pxd +44 -0
- Cython/Includes/libcpp/set.pxd +228 -0
- Cython/Includes/libcpp/shared_mutex.pxd +72 -0
- Cython/Includes/libcpp/span.pxd +87 -0
- Cython/Includes/libcpp/stack.pxd +11 -0
- Cython/Includes/libcpp/stop_token.pxd +105 -0
- Cython/Includes/libcpp/string.pxd +355 -0
- Cython/Includes/libcpp/string_view.pxd +181 -0
- Cython/Includes/libcpp/typeindex.pxd +15 -0
- Cython/Includes/libcpp/typeinfo.pxd +10 -0
- Cython/Includes/libcpp/unordered_map.pxd +193 -0
- Cython/Includes/libcpp/unordered_set.pxd +152 -0
- Cython/Includes/libcpp/utility.pxd +30 -0
- Cython/Includes/libcpp/vector.pxd +186 -0
- Cython/Includes/openmp.pxd +50 -0
- Cython/Includes/posix/__init__.pxd +1 -0
- Cython/Includes/posix/dlfcn.pxd +14 -0
- Cython/Includes/posix/fcntl.pxd +86 -0
- Cython/Includes/posix/ioctl.pxd +4 -0
- Cython/Includes/posix/mman.pxd +101 -0
- Cython/Includes/posix/resource.pxd +57 -0
- Cython/Includes/posix/select.pxd +21 -0
- Cython/Includes/posix/signal.pxd +73 -0
- Cython/Includes/posix/stat.pxd +98 -0
- Cython/Includes/posix/stdio.pxd +37 -0
- Cython/Includes/posix/stdlib.pxd +29 -0
- Cython/Includes/posix/strings.pxd +9 -0
- Cython/Includes/posix/time.pxd +71 -0
- Cython/Includes/posix/types.pxd +30 -0
- Cython/Includes/posix/uio.pxd +26 -0
- Cython/Includes/posix/unistd.pxd +271 -0
- Cython/Includes/posix/wait.pxd +38 -0
- Cython/Plex/Actions.pxd +24 -0
- Cython/Plex/Actions.py +119 -0
- Cython/Plex/DFA.pxd +14 -0
- Cython/Plex/DFA.py +164 -0
- Cython/Plex/Errors.py +48 -0
- Cython/Plex/Lexicons.py +178 -0
- Cython/Plex/Machines.pxd +36 -0
- Cython/Plex/Machines.py +238 -0
- Cython/Plex/Regexps.py +539 -0
- Cython/Plex/Scanners.pxd +47 -0
- Cython/Plex/Scanners.py +360 -0
- Cython/Plex/Transitions.pxd +14 -0
- Cython/Plex/Transitions.py +239 -0
- Cython/Plex/__init__.py +34 -0
- Cython/Runtime/__init__.py +1 -0
- Cython/Runtime/refnanny.pyx +237 -0
- Cython/Shadow.py +690 -0
- Cython/Shadow.pyi +521 -0
- Cython/StringIOTree.py +170 -0
- Cython/Tempita/__init__.py +4 -0
- Cython/Tempita/_looper.py +154 -0
- Cython/Tempita/_tempita.py +1091 -0
- Cython/TestUtils.py +410 -0
- Cython/Tests/TestCodeWriter.py +128 -0
- Cython/Tests/TestCythonUtils.py +202 -0
- Cython/Tests/TestJediTyper.py +223 -0
- Cython/Tests/TestShadow.py +114 -0
- Cython/Tests/TestStringIOTree.py +67 -0
- Cython/Tests/TestTestUtils.py +90 -0
- Cython/Tests/__init__.py +1 -0
- Cython/Tests/xmlrunner.py +390 -0
- Cython/Utility/AsyncGen.c +1002 -0
- Cython/Utility/Buffer.c +875 -0
- Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
- Cython/Utility/Builtins.c +776 -0
- Cython/Utility/CConvert.pyx +134 -0
- Cython/Utility/CMath.c +104 -0
- Cython/Utility/CommonStructures.c +118 -0
- Cython/Utility/Complex.c +378 -0
- Cython/Utility/Coroutine.c +2206 -0
- Cython/Utility/CpdefEnums.pyx +103 -0
- Cython/Utility/CppConvert.pyx +279 -0
- Cython/Utility/CppSupport.cpp +143 -0
- Cython/Utility/CythonFunction.c +1794 -0
- Cython/Utility/Dataclasses.c +185 -0
- Cython/Utility/Dataclasses.py +112 -0
- Cython/Utility/Embed.c +125 -0
- Cython/Utility/Exceptions.c +1012 -0
- Cython/Utility/ExtensionTypes.c +809 -0
- Cython/Utility/FunctionArguments.c +965 -0
- Cython/Utility/ImportExport.c +987 -0
- Cython/Utility/Lock.c +136 -0
- Cython/Utility/MemoryView.pxd +187 -0
- Cython/Utility/MemoryView.pyx +1481 -0
- Cython/Utility/MemoryView_C.c +1046 -0
- Cython/Utility/ModuleSetupCode.c +3059 -0
- Cython/Utility/NumpyImportArray.c +46 -0
- Cython/Utility/ObjectHandling.c +3342 -0
- Cython/Utility/Optimize.c +1589 -0
- Cython/Utility/Overflow.c +404 -0
- Cython/Utility/Printing.c +86 -0
- Cython/Utility/Profile.c +709 -0
- Cython/Utility/StringTools.c +1259 -0
- Cython/Utility/TestCyUtilityLoader.pyx +8 -0
- Cython/Utility/TestCythonScope.pyx +75 -0
- Cython/Utility/TestUtilityLoader.c +12 -0
- Cython/Utility/TypeConversion.c +1284 -0
- Cython/Utility/UFuncs.pyx +50 -0
- Cython/Utility/UFuncs_C.c +89 -0
- Cython/Utility/__init__.py +28 -0
- Cython/Utility/arrayarray.h +148 -0
- Cython/Utils.py +687 -0
- Cython/__init__.py +10 -0
- Cython/__init__.pyi +7 -0
- Cython/py.typed +0 -0
- cython-3.1.0.dist-info/COPYING.txt +19 -0
- cython-3.1.0.dist-info/LICENSE.txt +176 -0
- cython-3.1.0.dist-info/METADATA +636 -0
- cython-3.1.0.dist-info/RECORD +316 -0
- cython-3.1.0.dist-info/WHEEL +5 -0
- cython-3.1.0.dist-info/entry_points.txt +4 -0
- cython-3.1.0.dist-info/top_level.txt +3 -0
- cython.py +29 -0
- pyximport/__init__.py +4 -0
- pyximport/pyxbuild.py +160 -0
- pyximport/pyximport.py +482 -0
|
@@ -0,0 +1,2206 @@
|
|
|
1
|
+
// ### CPython revisions to investigate for potential changes:
|
|
2
|
+
|
|
3
|
+
// 2f180ce2cb6 (bpo-44530: Add co_qualname field to PyCodeObject (GH-26941))
|
|
4
|
+
// a4760cc32d9 (bpo-42747: Remove Py_TPFLAGS_HAVE_AM_SEND and make Py_TPFLAGS_HAVE_VERSION_TAG no-op (GH-27260))
|
|
5
|
+
// ae0a2b75625 (bpo-44590: Lazily allocate frame objects (GH-27077))
|
|
6
|
+
// 69806b9516d (bpo-46009: Do not exhaust generator when send() method raises (GH-29986))
|
|
7
|
+
// b04dfbbe4bd (bpo-46409: Make generators in bytecode (GH-30633) -- ".gi_suspended")
|
|
8
|
+
// 304197b3820 (bpo-46944: use FASTCALL calling convention in generator.throw (GH-31723))
|
|
9
|
+
// 8be7c2bc5ad (bpo-14911: Corrected generator.throw() documentation (GH-32207))
|
|
10
|
+
// 5bfb3c372bd (GH-90997: Wrap yield from/await in a virtual try/except StopIteration (GH-96010))
|
|
11
|
+
// 83a3de4e063 (gh-96348: Deprecate the 3-arg signature of coroutine.throw and generator.throw (GH-96428))
|
|
12
|
+
// f4adb975061 (GH-96793: Implement PEP 479 in bytecode. (GH-99006))
|
|
13
|
+
// f02fa64bf2d (GH-100762: Don't call `gen.throw()` in `gen.close()`, unless necessary. (GH-101013))
|
|
14
|
+
// 11a2c6ce516 (gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (in Objects/) (#102218))
|
|
15
|
+
// ced13c96a4e (gh-79940: add introspection API for asynchronous generators to `inspect` module (#11590) -- ".ag_suspended")
|
|
16
|
+
// d56c933992c (gh-104770: Let generator.close() return value (#104771))
|
|
17
|
+
// 7fc542c88dc (GH-89091: raise `RuntimeWarning` for unawaited async generator methods (#104611))
|
|
18
|
+
// 0d30a5a4096 (GH-100964: Break cycles involving exception state when returning from generator (GH-107563))
|
|
19
|
+
// 7d369d471cf (GH-117536: GH-117894: fix athrow().throw(...) unawaited warning (GH-117851))
|
|
20
|
+
// fc7e1aa3c00 (GH-117881: fix athrow().throw()/asend().throw() concurrent access (GH-117882))
|
|
21
|
+
// e5c699280de (GH-117714: implement athrow().close() and asend().close() using throw (GH-117906))
|
|
22
|
+
// 2c7209a3bdf (gh-114091: Reword error message for unawaitable types (#114090))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
//////////////////// CoroutineSetYieldFrom ////////////////////
|
|
26
|
+
|
|
27
|
+
static void
|
|
28
|
+
__Pyx_Coroutine_Set_Owned_Yield_From(__pyx_CoroutineObject *gen, PyObject *yf) {
|
|
29
|
+
// NOTE: steals a reference to yf by transferring it to 'gen->yieldfrom' !
|
|
30
|
+
assert (!gen->yieldfrom);
|
|
31
|
+
#if CYTHON_USE_AM_SEND
|
|
32
|
+
assert (!gen->yieldfrom_am_send);
|
|
33
|
+
#if PY_VERSION_HEX < 0x030A00F0
|
|
34
|
+
if (__Pyx_PyType_HasFeature(Py_TYPE(yf), __Pyx_TPFLAGS_HAVE_AM_SEND))
|
|
35
|
+
#endif
|
|
36
|
+
{
|
|
37
|
+
__Pyx_pyiter_sendfunc am_send;
|
|
38
|
+
#if __PYX_LIMITED_VERSION_HEX >= 0x030A0000
|
|
39
|
+
am_send = __Pyx_PyObject_TryGetSubSlot(yf, tp_as_async, am_send, __Pyx_pyiter_sendfunc);
|
|
40
|
+
#else
|
|
41
|
+
__Pyx_PyAsyncMethodsStruct* tp_as_async = (__Pyx_PyAsyncMethodsStruct*) Py_TYPE(yf)->tp_as_async;
|
|
42
|
+
am_send = tp_as_async ? tp_as_async->am_send : NULL;
|
|
43
|
+
#endif
|
|
44
|
+
if (likely(am_send)) {
|
|
45
|
+
// Keep a direct reference to am->am_send, if provided.
|
|
46
|
+
gen->yieldfrom_am_send = am_send;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
#endif
|
|
50
|
+
gen->yieldfrom = yf;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
//////////////////// GeneratorYieldFrom.proto ////////////////////
|
|
55
|
+
|
|
56
|
+
static CYTHON_INLINE __Pyx_PySendResult __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source, PyObject **retval);
|
|
57
|
+
|
|
58
|
+
//////////////////// GeneratorYieldFrom ////////////////////
|
|
59
|
+
//@requires: Generator
|
|
60
|
+
//@requires: CoroutineSetYieldFrom
|
|
61
|
+
//@requires: ObjectHandling.c::IterNextPlain
|
|
62
|
+
|
|
63
|
+
#if CYTHON_USE_TYPE_SLOTS
|
|
64
|
+
static void __Pyx_PyIter_CheckErrorAndDecref(PyObject *source) {
|
|
65
|
+
__Pyx_TypeName source_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(source));
|
|
66
|
+
PyErr_Format(PyExc_TypeError,
|
|
67
|
+
"iter() returned non-iterator of type '" __Pyx_FMT_TYPENAME "'", source_type_name);
|
|
68
|
+
__Pyx_DECREF_TypeName(source_type_name);
|
|
69
|
+
Py_DECREF(source);
|
|
70
|
+
}
|
|
71
|
+
#endif
|
|
72
|
+
|
|
73
|
+
static CYTHON_INLINE __Pyx_PySendResult __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source, PyObject **retval) {
|
|
74
|
+
PyObject *source_gen;
|
|
75
|
+
__Pyx_PySendResult result;
|
|
76
|
+
#ifdef __Pyx_Coroutine_USED
|
|
77
|
+
if (__Pyx_Coroutine_Check(source)) {
|
|
78
|
+
// TODO: this should only happen for types.coroutine()ed generators, but we can't determine that here
|
|
79
|
+
Py_INCREF(source);
|
|
80
|
+
source_gen = source;
|
|
81
|
+
result = __Pyx_Coroutine_AmSend(source, Py_None, retval);
|
|
82
|
+
} else
|
|
83
|
+
#endif
|
|
84
|
+
{
|
|
85
|
+
#if CYTHON_USE_TYPE_SLOTS
|
|
86
|
+
if (likely(Py_TYPE(source)->tp_iter)) {
|
|
87
|
+
source_gen = Py_TYPE(source)->tp_iter(source);
|
|
88
|
+
if (unlikely(!source_gen)) {
|
|
89
|
+
*retval = NULL;
|
|
90
|
+
return PYGEN_ERROR;
|
|
91
|
+
}
|
|
92
|
+
if (unlikely(!PyIter_Check(source_gen))) {
|
|
93
|
+
__Pyx_PyIter_CheckErrorAndDecref(source_gen);
|
|
94
|
+
*retval = NULL;
|
|
95
|
+
return PYGEN_ERROR;
|
|
96
|
+
}
|
|
97
|
+
} else
|
|
98
|
+
// CPython also allows non-iterable sequences to be iterated over
|
|
99
|
+
#endif
|
|
100
|
+
{
|
|
101
|
+
source_gen = PyObject_GetIter(source);
|
|
102
|
+
if (unlikely(!source_gen)) {
|
|
103
|
+
*retval = NULL;
|
|
104
|
+
return PYGEN_ERROR;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// source_gen is now the iterator, make the first next() call
|
|
108
|
+
*retval = __Pyx_PyIter_Next_Plain(source_gen);
|
|
109
|
+
result = __Pyx_Coroutine_status_from_result(retval);
|
|
110
|
+
}
|
|
111
|
+
if (likely(result == PYGEN_NEXT)) {
|
|
112
|
+
__Pyx_Coroutine_Set_Owned_Yield_From(gen, source_gen);
|
|
113
|
+
return PYGEN_NEXT;
|
|
114
|
+
}
|
|
115
|
+
Py_DECREF(source_gen);
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
//////////////////// CoroutineYieldFrom.proto ////////////////////
|
|
121
|
+
|
|
122
|
+
static CYTHON_INLINE __Pyx_PySendResult __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject *gen, PyObject *source, PyObject **retval); /*proto*/
|
|
123
|
+
|
|
124
|
+
//////////////////// CoroutineYieldFrom ////////////////////
|
|
125
|
+
//@requires: Coroutine
|
|
126
|
+
//@requires: GetAwaitIter
|
|
127
|
+
//@requires: CoroutineSetYieldFrom
|
|
128
|
+
//@requires: ObjectHandling.c::IterNextPlain
|
|
129
|
+
|
|
130
|
+
static __Pyx_PySendResult __Pyx_Coroutine_Yield_From_Coroutine(__pyx_CoroutineObject *gen, PyObject *source, PyObject **retval) {
|
|
131
|
+
__Pyx_PySendResult result;
|
|
132
|
+
if (unlikely(((__pyx_CoroutineObject*)source)->yieldfrom)) {
|
|
133
|
+
PyErr_SetString(
|
|
134
|
+
PyExc_RuntimeError,
|
|
135
|
+
"coroutine is being awaited already");
|
|
136
|
+
return PYGEN_ERROR;
|
|
137
|
+
}
|
|
138
|
+
result = __Pyx_Coroutine_AmSend(source, Py_None, retval);
|
|
139
|
+
if (result == PYGEN_NEXT) {
|
|
140
|
+
Py_INCREF(source);
|
|
141
|
+
__Pyx_Coroutine_Set_Owned_Yield_From(gen, source);
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
static __Pyx_PySendResult __Pyx_Coroutine_Yield_From_Generic(__pyx_CoroutineObject *gen, PyObject *source, PyObject **retval) {
|
|
147
|
+
__Pyx_PySendResult result;
|
|
148
|
+
PyObject *source_gen = NULL;
|
|
149
|
+
|
|
150
|
+
source_gen = __Pyx_Coroutine_GetAwaitableIter(source);
|
|
151
|
+
if (unlikely(!source_gen)) return PYGEN_ERROR;
|
|
152
|
+
|
|
153
|
+
// source_gen is now the iterator, make the first next() call
|
|
154
|
+
if (__Pyx_Coroutine_Check(source_gen)) {
|
|
155
|
+
result = __Pyx_Coroutine_Yield_From_Coroutine(gen, source_gen, retval);
|
|
156
|
+
Py_DECREF(source_gen);
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
*retval = __Pyx_PyIter_Next_Plain(source_gen);
|
|
161
|
+
if (*retval) {
|
|
162
|
+
__Pyx_Coroutine_Set_Owned_Yield_From(gen, source_gen);
|
|
163
|
+
return PYGEN_NEXT;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
result = __Pyx_Coroutine_status_from_result(retval);
|
|
167
|
+
Py_XDECREF(source_gen);
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static CYTHON_INLINE __Pyx_PySendResult __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject *gen, PyObject *source, PyObject **retval) {
|
|
172
|
+
if (__Pyx_Coroutine_Check(source)) {
|
|
173
|
+
return __Pyx_Coroutine_Yield_From_Coroutine(gen, source, retval);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
177
|
+
// Inlined "__pyx_PyAsyncGenASend" handling to avoid the series of generic calls.
|
|
178
|
+
if (__pyx_PyAsyncGenASend_CheckExact(source)) {
|
|
179
|
+
*retval = __Pyx_async_gen_asend_iternext(source);
|
|
180
|
+
if (*retval) {
|
|
181
|
+
Py_INCREF(source);
|
|
182
|
+
__Pyx_Coroutine_Set_Owned_Yield_From(gen, source);
|
|
183
|
+
return PYGEN_NEXT;
|
|
184
|
+
}
|
|
185
|
+
return __Pyx_Coroutine_status_from_result(retval);
|
|
186
|
+
}
|
|
187
|
+
#endif
|
|
188
|
+
|
|
189
|
+
return __Pyx_Coroutine_Yield_From_Generic(gen, source, retval);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
//////////////////// GetAwaitIter.proto ////////////////////
|
|
194
|
+
|
|
195
|
+
static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAwaitableIter(PyObject *o); /*proto*/
|
|
196
|
+
static PyObject *__Pyx__Coroutine_GetAwaitableIter(PyObject *o); /*proto*/
|
|
197
|
+
|
|
198
|
+
//////////////////// GetAwaitIter ////////////////////
|
|
199
|
+
//@requires: ObjectHandling.c::PyObjectGetMethod
|
|
200
|
+
//@requires: ObjectHandling.c::PyObjectCallNoArg
|
|
201
|
+
//@requires: ObjectHandling.c::PyObjectCallOneArg
|
|
202
|
+
//@requires: Coro_CheckExact
|
|
203
|
+
|
|
204
|
+
static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAwaitableIter(PyObject *o) {
|
|
205
|
+
#ifdef __Pyx_Coroutine_USED
|
|
206
|
+
if (__Pyx_Coroutine_Check(o)) {
|
|
207
|
+
return __Pyx_NewRef(o);
|
|
208
|
+
}
|
|
209
|
+
#endif
|
|
210
|
+
return __Pyx__Coroutine_GetAwaitableIter(o);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
static void __Pyx_Coroutine_AwaitableIterError(PyObject *source) {
|
|
215
|
+
#if (PY_VERSION_HEX < 0x030d0000 || defined(_PyErr_FormatFromCause)) && !CYTHON_COMPILING_IN_LIMITED_API
|
|
216
|
+
__Pyx_TypeName source_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(source));
|
|
217
|
+
_PyErr_FormatFromCause(PyExc_TypeError,
|
|
218
|
+
"'async for' received an invalid object from __anext__: " __Pyx_FMT_TYPENAME, source_type_name);
|
|
219
|
+
__Pyx_DECREF_TypeName(source_type_name);
|
|
220
|
+
#else
|
|
221
|
+
PyObject *exc, *val, *val2, *tb;
|
|
222
|
+
__Pyx_TypeName source_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(source));
|
|
223
|
+
assert(PyErr_Occurred());
|
|
224
|
+
PyErr_Fetch(&exc, &val, &tb);
|
|
225
|
+
PyErr_NormalizeException(&exc, &val, &tb);
|
|
226
|
+
if (tb != NULL) {
|
|
227
|
+
PyException_SetTraceback(val, tb);
|
|
228
|
+
Py_DECREF(tb);
|
|
229
|
+
}
|
|
230
|
+
Py_DECREF(exc);
|
|
231
|
+
assert(!PyErr_Occurred());
|
|
232
|
+
PyErr_Format(PyExc_TypeError,
|
|
233
|
+
"'async for' received an invalid object from __anext__: " __Pyx_FMT_TYPENAME, source_type_name);
|
|
234
|
+
__Pyx_DECREF_TypeName(source_type_name);
|
|
235
|
+
|
|
236
|
+
PyErr_Fetch(&exc, &val2, &tb);
|
|
237
|
+
PyErr_NormalizeException(&exc, &val2, &tb);
|
|
238
|
+
Py_INCREF(val);
|
|
239
|
+
PyException_SetCause(val2, val);
|
|
240
|
+
PyException_SetContext(val2, val);
|
|
241
|
+
PyErr_Restore(exc, val2, tb);
|
|
242
|
+
#endif
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// adapted from genobject.c in Py3.5
|
|
246
|
+
static PyObject *__Pyx__Coroutine_GetAwaitableIter(PyObject *obj) {
|
|
247
|
+
PyObject *res;
|
|
248
|
+
unaryfunc am_await;
|
|
249
|
+
am_await = __Pyx_PyObject_TryGetSubSlot(obj, tp_as_async, am_await, unaryfunc);
|
|
250
|
+
if (likely(am_await)) {
|
|
251
|
+
res = (*am_await)(obj);
|
|
252
|
+
} else
|
|
253
|
+
#if CYTHON_COMPILING_IN_CPYTHON && defined(CO_ITERABLE_COROUTINE)
|
|
254
|
+
#if PY_VERSION_HEX >= 0x030C00A6
|
|
255
|
+
if (PyGen_CheckExact(obj) && (PyGen_GetCode((PyGenObject*)obj)->co_flags & CO_ITERABLE_COROUTINE)) {
|
|
256
|
+
#else
|
|
257
|
+
if (PyGen_CheckExact(obj) && ((PyGenObject*)obj)->gi_code && ((PyCodeObject *)((PyGenObject*)obj)->gi_code)->co_flags & CO_ITERABLE_COROUTINE) {
|
|
258
|
+
#endif
|
|
259
|
+
// Python generator marked with "@types.coroutine" decorator
|
|
260
|
+
return __Pyx_NewRef(obj);
|
|
261
|
+
} else
|
|
262
|
+
#endif
|
|
263
|
+
{
|
|
264
|
+
PyObject *method = NULL;
|
|
265
|
+
int is_method = __Pyx_PyObject_GetMethod(obj, PYIDENT("__await__"), &method);
|
|
266
|
+
if (likely(is_method)) {
|
|
267
|
+
res = __Pyx_PyObject_CallOneArg(method, obj);
|
|
268
|
+
} else if (likely(method)) {
|
|
269
|
+
res = __Pyx_PyObject_CallNoArg(method);
|
|
270
|
+
} else
|
|
271
|
+
goto slot_error;
|
|
272
|
+
Py_DECREF(method);
|
|
273
|
+
}
|
|
274
|
+
if (unlikely(!res)) {
|
|
275
|
+
// surprisingly, CPython replaces the exception here...
|
|
276
|
+
__Pyx_Coroutine_AwaitableIterError(obj);
|
|
277
|
+
goto bad;
|
|
278
|
+
}
|
|
279
|
+
if (unlikely(!PyIter_Check(res))) {
|
|
280
|
+
__Pyx_TypeName res_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(res));
|
|
281
|
+
PyErr_Format(PyExc_TypeError,
|
|
282
|
+
"__await__() returned non-iterator of type '" __Pyx_FMT_TYPENAME "'", res_type_name);
|
|
283
|
+
__Pyx_DECREF_TypeName(res_type_name);
|
|
284
|
+
Py_CLEAR(res);
|
|
285
|
+
} else {
|
|
286
|
+
int is_coroutine = 0;
|
|
287
|
+
#ifdef __Pyx_Coroutine_USED
|
|
288
|
+
is_coroutine |= __Pyx_Coroutine_Check(res);
|
|
289
|
+
#endif
|
|
290
|
+
is_coroutine |= __Pyx_PyCoro_CheckExact(res);
|
|
291
|
+
if (unlikely(is_coroutine)) {
|
|
292
|
+
/* __await__ must return an *iterator*, not
|
|
293
|
+
a coroutine or another awaitable (see PEP 492) */
|
|
294
|
+
PyErr_SetString(PyExc_TypeError,
|
|
295
|
+
"__await__() returned a coroutine");
|
|
296
|
+
Py_CLEAR(res);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return res;
|
|
300
|
+
slot_error:
|
|
301
|
+
{
|
|
302
|
+
__Pyx_TypeName obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj));
|
|
303
|
+
PyErr_Format(PyExc_TypeError,
|
|
304
|
+
"object " __Pyx_FMT_TYPENAME " can't be used in 'await' expression", obj_type_name);
|
|
305
|
+
__Pyx_DECREF_TypeName(obj_type_name);
|
|
306
|
+
}
|
|
307
|
+
bad:
|
|
308
|
+
return NULL;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
//////////////////// AsyncIter.proto ////////////////////
|
|
313
|
+
|
|
314
|
+
static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAsyncIter(PyObject *o); /*proto*/
|
|
315
|
+
static CYTHON_INLINE PyObject *__Pyx_Coroutine_AsyncIterNext(PyObject *o); /*proto*/
|
|
316
|
+
|
|
317
|
+
//////////////////// AsyncIter ////////////////////
|
|
318
|
+
//@requires: GetAwaitIter
|
|
319
|
+
|
|
320
|
+
static PyObject *__Pyx_Coroutine_GetAsyncIter_Fail(PyObject *obj) {
|
|
321
|
+
__Pyx_TypeName obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj));
|
|
322
|
+
PyErr_Format(PyExc_TypeError,
|
|
323
|
+
"'async for' requires an object with __aiter__ method, got " __Pyx_FMT_TYPENAME, obj_type_name);
|
|
324
|
+
__Pyx_DECREF_TypeName(obj_type_name);
|
|
325
|
+
return NULL;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAsyncIter(PyObject *obj) {
|
|
330
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
331
|
+
if (__Pyx_AsyncGen_CheckExact(obj)) {
|
|
332
|
+
return __Pyx_NewRef(obj);
|
|
333
|
+
}
|
|
334
|
+
#endif
|
|
335
|
+
{
|
|
336
|
+
unaryfunc am_aiter = __Pyx_PyObject_TryGetSubSlot(obj, tp_as_async, am_aiter, unaryfunc);
|
|
337
|
+
if (likely(am_aiter)) {
|
|
338
|
+
return (*am_aiter)(obj);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return __Pyx_Coroutine_GetAsyncIter_Fail(obj);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
static PyObject *__Pyx_Coroutine_AsyncIterNext_Fail(PyObject *obj) {
|
|
346
|
+
__Pyx_TypeName obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj));
|
|
347
|
+
PyErr_Format(PyExc_TypeError,
|
|
348
|
+
"'async for' requires an object with __anext__ method, got " __Pyx_FMT_TYPENAME, obj_type_name);
|
|
349
|
+
__Pyx_DECREF_TypeName(obj_type_name);
|
|
350
|
+
return NULL;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
static CYTHON_INLINE PyObject *__Pyx_Coroutine_AsyncIterNext(PyObject *obj) {
|
|
355
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
356
|
+
if (__Pyx_AsyncGen_CheckExact(obj)) {
|
|
357
|
+
return __Pyx_async_gen_anext(obj);
|
|
358
|
+
}
|
|
359
|
+
#endif
|
|
360
|
+
{
|
|
361
|
+
unaryfunc am_anext = __Pyx_PyObject_TryGetSubSlot(obj, tp_as_async, am_anext, unaryfunc);
|
|
362
|
+
if (likely(am_anext)) {
|
|
363
|
+
return (*am_anext)(obj);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return __Pyx_Coroutine_AsyncIterNext_Fail(obj);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
//////////////////// pep479.proto ////////////////////
|
|
371
|
+
|
|
372
|
+
static void __Pyx_Generator_Replace_StopIteration(int in_async_gen); /*proto*/
|
|
373
|
+
|
|
374
|
+
//////////////////// pep479 ////////////////////
|
|
375
|
+
//@requires: Exceptions.c::GetException
|
|
376
|
+
|
|
377
|
+
static void __Pyx_Generator_Replace_StopIteration(int in_async_gen) {
|
|
378
|
+
PyObject *exc, *val, *tb, *cur_exc, *new_exc;
|
|
379
|
+
__Pyx_PyThreadState_declare
|
|
380
|
+
int is_async_stopiteration = 0;
|
|
381
|
+
CYTHON_MAYBE_UNUSED_VAR(in_async_gen);
|
|
382
|
+
|
|
383
|
+
__Pyx_PyThreadState_assign
|
|
384
|
+
cur_exc = __Pyx_PyErr_CurrentExceptionType();
|
|
385
|
+
if (likely(!__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopIteration))) {
|
|
386
|
+
if (in_async_gen && unlikely(__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopAsyncIteration))) {
|
|
387
|
+
is_async_stopiteration = 1;
|
|
388
|
+
} else {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Explicitly chain the Stop(Async)Iteration by moving it to exc_info before creating the RuntimeError.
|
|
394
|
+
__Pyx_GetException(&exc, &val, &tb);
|
|
395
|
+
Py_XDECREF(exc);
|
|
396
|
+
Py_XDECREF(tb);
|
|
397
|
+
new_exc = PyObject_CallFunction(PyExc_RuntimeError, "s",
|
|
398
|
+
is_async_stopiteration ? "async generator raised StopAsyncIteration" :
|
|
399
|
+
in_async_gen ? "async generator raised StopIteration" :
|
|
400
|
+
"generator raised StopIteration");
|
|
401
|
+
if (!new_exc) {
|
|
402
|
+
Py_XDECREF(val);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
PyException_SetCause(new_exc, val); // steals ref to val
|
|
406
|
+
PyErr_SetObject(PyExc_RuntimeError, new_exc);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
//////////////////// CoroutineBase.proto ////////////////////
|
|
411
|
+
//@substitute: naming
|
|
412
|
+
|
|
413
|
+
struct __pyx_CoroutineObject;
|
|
414
|
+
typedef PyObject *(*__pyx_coroutine_body_t)(struct __pyx_CoroutineObject *, PyThreadState *, PyObject *);
|
|
415
|
+
|
|
416
|
+
#if CYTHON_USE_EXC_INFO_STACK
|
|
417
|
+
// See https://bugs.python.org/issue25612
|
|
418
|
+
#define __Pyx_ExcInfoStruct _PyErr_StackItem
|
|
419
|
+
#else
|
|
420
|
+
// Minimal replacement struct for Py<3.7, without the Py3.7 exception state stack.
|
|
421
|
+
typedef struct {
|
|
422
|
+
PyObject *exc_type;
|
|
423
|
+
PyObject *exc_value;
|
|
424
|
+
PyObject *exc_traceback;
|
|
425
|
+
} __Pyx_ExcInfoStruct;
|
|
426
|
+
#endif
|
|
427
|
+
|
|
428
|
+
typedef struct __pyx_CoroutineObject {
|
|
429
|
+
PyObject_HEAD
|
|
430
|
+
__pyx_coroutine_body_t body;
|
|
431
|
+
PyObject *closure;
|
|
432
|
+
__Pyx_ExcInfoStruct gi_exc_state;
|
|
433
|
+
PyObject *gi_weakreflist;
|
|
434
|
+
PyObject *classobj;
|
|
435
|
+
PyObject *yieldfrom;
|
|
436
|
+
// "yieldfrom_am_send" is always included to avoid changing the struct layout.
|
|
437
|
+
__Pyx_pyiter_sendfunc yieldfrom_am_send;
|
|
438
|
+
PyObject *gi_name;
|
|
439
|
+
PyObject *gi_qualname;
|
|
440
|
+
PyObject *gi_modulename;
|
|
441
|
+
PyObject *gi_code;
|
|
442
|
+
PyObject *gi_frame;
|
|
443
|
+
#if CYTHON_USE_SYS_MONITORING && (CYTHON_PROFILE || CYTHON_TRACE)
|
|
444
|
+
PyMonitoringState $monitoring_states_cname[__Pyx_MonitoringEventTypes_CyGen_count];
|
|
445
|
+
uint64_t $monitoring_version_cname;
|
|
446
|
+
#endif
|
|
447
|
+
int resume_label;
|
|
448
|
+
// is_running is the main thread-safety mechanism for coroutines, so treat it carefully
|
|
449
|
+
char is_running;
|
|
450
|
+
} __pyx_CoroutineObject;
|
|
451
|
+
|
|
452
|
+
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
|
|
453
|
+
PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
|
|
454
|
+
PyObject *name, PyObject *qualname, PyObject *module_name); /*proto*/
|
|
455
|
+
|
|
456
|
+
static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
|
|
457
|
+
__pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
|
|
458
|
+
PyObject *name, PyObject *qualname, PyObject *module_name); /*proto*/
|
|
459
|
+
|
|
460
|
+
static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self);
|
|
461
|
+
static int __Pyx_Coroutine_clear(PyObject *self); /*proto*/
|
|
462
|
+
static __Pyx_PySendResult __Pyx_Coroutine_AmSend(PyObject *self, PyObject *value, PyObject **retval); /*proto*/
|
|
463
|
+
static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); /*proto*/
|
|
464
|
+
static __Pyx_PySendResult __Pyx_Coroutine_Close(PyObject *self, PyObject **retval); /*proto*/
|
|
465
|
+
static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); /*proto*/
|
|
466
|
+
|
|
467
|
+
// macros for exception state swapping instead of inline functions to make use of the local thread state context
|
|
468
|
+
#if CYTHON_USE_EXC_INFO_STACK
|
|
469
|
+
#define __Pyx_Coroutine_SwapException(self)
|
|
470
|
+
#define __Pyx_Coroutine_ResetAndClearException(self) __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state)
|
|
471
|
+
#else
|
|
472
|
+
#define __Pyx_Coroutine_SwapException(self) { \
|
|
473
|
+
__Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback); \
|
|
474
|
+
__Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state); \
|
|
475
|
+
}
|
|
476
|
+
#define __Pyx_Coroutine_ResetAndClearException(self) { \
|
|
477
|
+
__Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback); \
|
|
478
|
+
(self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL; \
|
|
479
|
+
}
|
|
480
|
+
#endif
|
|
481
|
+
|
|
482
|
+
#if CYTHON_FAST_THREAD_STATE
|
|
483
|
+
#define __Pyx_PyGen_FetchStopIterationValue(pvalue) \
|
|
484
|
+
__Pyx_PyGen__FetchStopIterationValue($local_tstate_cname, pvalue)
|
|
485
|
+
#else
|
|
486
|
+
#define __Pyx_PyGen_FetchStopIterationValue(pvalue) \
|
|
487
|
+
__Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue)
|
|
488
|
+
#endif
|
|
489
|
+
static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); /*proto*/
|
|
490
|
+
static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); /*proto*/
|
|
491
|
+
|
|
492
|
+
static char __Pyx_Coroutine_test_and_set_is_running(__pyx_CoroutineObject *gen);
|
|
493
|
+
static void __Pyx_Coroutine_unset_is_running(__pyx_CoroutineObject *gen);
|
|
494
|
+
static char __Pyx_Coroutine_get_is_running(__pyx_CoroutineObject *gen);
|
|
495
|
+
static PyObject *__Pyx_Coroutine_get_is_running_getter(PyObject *gen, void *closure);
|
|
496
|
+
|
|
497
|
+
#if __PYX_HAS_PY_AM_SEND == 2
|
|
498
|
+
static void __Pyx_SetBackportTypeAmSend(PyTypeObject *type, __Pyx_PyAsyncMethodsStruct *static_amsend_methods, __Pyx_pyiter_sendfunc am_send); /* proto */
|
|
499
|
+
#endif
|
|
500
|
+
|
|
501
|
+
//////////////////// Coroutine.proto ////////////////////
|
|
502
|
+
|
|
503
|
+
#define __Pyx_Coroutine_USED
|
|
504
|
+
#define __Pyx_Coroutine_CheckExact(obj) __Pyx_IS_TYPE(obj, CGLOBAL(__pyx_CoroutineType))
|
|
505
|
+
// __Pyx_Coroutine_Check(obj): see override for IterableCoroutine below
|
|
506
|
+
#define __Pyx_Coroutine_Check(obj) __Pyx_Coroutine_CheckExact(obj)
|
|
507
|
+
#define __Pyx_CoroutineAwait_CheckExact(obj) __Pyx_IS_TYPE(obj, CGLOBAL(__pyx_CoroutineAwaitType))
|
|
508
|
+
|
|
509
|
+
#define __Pyx_Coroutine_New(body, code, closure, name, qualname, module_name) \
|
|
510
|
+
__Pyx__Coroutine_New(CGLOBAL(__pyx_CoroutineType), body, code, closure, name, qualname, module_name)
|
|
511
|
+
|
|
512
|
+
static int __pyx_Coroutine_init(PyObject *module); /*proto*/
|
|
513
|
+
static PyObject *__Pyx__Coroutine_await(PyObject *coroutine); /*proto*/
|
|
514
|
+
|
|
515
|
+
typedef struct {
|
|
516
|
+
PyObject_HEAD
|
|
517
|
+
PyObject *coroutine;
|
|
518
|
+
} __pyx_CoroutineAwaitObject;
|
|
519
|
+
|
|
520
|
+
static __Pyx_PySendResult __Pyx_CoroutineAwait_Close(__pyx_CoroutineAwaitObject *self); /*proto*/
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
//////////////////// Generator.proto ////////////////////
|
|
524
|
+
|
|
525
|
+
#define __Pyx_Generator_USED
|
|
526
|
+
#define __Pyx_Generator_CheckExact(obj) __Pyx_IS_TYPE(obj, CGLOBAL(__pyx_GeneratorType))
|
|
527
|
+
|
|
528
|
+
#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name) \
|
|
529
|
+
__Pyx__Coroutine_New(CGLOBAL(__pyx_GeneratorType), body, code, closure, name, qualname, module_name)
|
|
530
|
+
|
|
531
|
+
static PyObject *__Pyx_Generator_Next(PyObject *self);
|
|
532
|
+
static int __pyx_Generator_init(PyObject *module); /*proto*/
|
|
533
|
+
static CYTHON_INLINE PyObject *__Pyx_Generator_GetInlinedResult(PyObject *self); /*proto*/
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
//////////////////// AsyncGen ////////////////////
|
|
537
|
+
//@requires: AsyncGen.c::AsyncGenerator
|
|
538
|
+
// -> empty, only delegates to separate file
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
//////////////////// CoroutineBase ////////////////////
|
|
542
|
+
//@substitute: naming
|
|
543
|
+
//@requires: ReturnWithStopIteration
|
|
544
|
+
//@requires: Exceptions.c::PyErrFetchRestore
|
|
545
|
+
//@requires: Exceptions.c::PyThreadStateGet
|
|
546
|
+
//@requires: Exceptions.c::SwapException
|
|
547
|
+
//@requires: Exceptions.c::RaiseException
|
|
548
|
+
//@requires: Exceptions.c::SaveResetException
|
|
549
|
+
//@requires: ObjectHandling.c::PyObjectCallMethod1
|
|
550
|
+
//@requires: ObjectHandling.c::PyObjectCallNoArg
|
|
551
|
+
//@requires: ObjectHandling.c::PyObjectCallOneArg
|
|
552
|
+
//@requires: ObjectHandling.c::PyObjectFastCall
|
|
553
|
+
//@requires: ObjectHandling.c::PyObjectGetAttrStr
|
|
554
|
+
//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
|
|
555
|
+
//@requires: ObjectHandling.c::IterNextPlain
|
|
556
|
+
//@requires: CommonStructures.c::FetchCommonType
|
|
557
|
+
//@requires: ModuleSetupCode.c::IncludeStructmemberH
|
|
558
|
+
//@requires: ExtensionTypes.c::CallTypeTraverse
|
|
559
|
+
|
|
560
|
+
#if !CYTHON_COMPILING_IN_LIMITED_API
|
|
561
|
+
#include <frameobject.h>
|
|
562
|
+
#if PY_VERSION_HEX >= 0x030b00a6 && !defined(PYPY_VERSION)
|
|
563
|
+
#ifndef Py_BUILD_CORE
|
|
564
|
+
#define Py_BUILD_CORE 1
|
|
565
|
+
#endif
|
|
566
|
+
#include "internal/pycore_frame.h"
|
|
567
|
+
#endif
|
|
568
|
+
#endif // CYTHON_COMPILING_IN_LIMITED_API
|
|
569
|
+
|
|
570
|
+
static CYTHON_INLINE void
|
|
571
|
+
__Pyx_Coroutine_Undelegate(__pyx_CoroutineObject *gen) {
|
|
572
|
+
#if CYTHON_USE_AM_SEND
|
|
573
|
+
gen->yieldfrom_am_send = NULL;
|
|
574
|
+
#endif
|
|
575
|
+
Py_CLEAR(gen->yieldfrom);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// If StopIteration exception is set, fetches its 'value'
|
|
579
|
+
// attribute if any, otherwise sets pvalue to None.
|
|
580
|
+
//
|
|
581
|
+
// Returns 0 if no exception or StopIteration is set.
|
|
582
|
+
// If any other exception is set, returns -1 and leaves
|
|
583
|
+
// pvalue unchanged.
|
|
584
|
+
static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *$local_tstate_cname, PyObject **pvalue) {
|
|
585
|
+
PyObject *et, *ev, *tb;
|
|
586
|
+
PyObject *value = NULL;
|
|
587
|
+
CYTHON_UNUSED_VAR($local_tstate_cname);
|
|
588
|
+
|
|
589
|
+
__Pyx_ErrFetch(&et, &ev, &tb);
|
|
590
|
+
|
|
591
|
+
if (!et) {
|
|
592
|
+
Py_XDECREF(tb);
|
|
593
|
+
Py_XDECREF(ev);
|
|
594
|
+
Py_INCREF(Py_None);
|
|
595
|
+
*pvalue = Py_None;
|
|
596
|
+
return 0;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// most common case: plain StopIteration without or with separate argument
|
|
600
|
+
if (likely(et == PyExc_StopIteration)) {
|
|
601
|
+
if (!ev) {
|
|
602
|
+
Py_INCREF(Py_None);
|
|
603
|
+
value = Py_None;
|
|
604
|
+
}
|
|
605
|
+
else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) {
|
|
606
|
+
#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL
|
|
607
|
+
value = PyObject_GetAttr(ev, PYIDENT("value"));
|
|
608
|
+
if (unlikely(!value)) goto limited_api_failure;
|
|
609
|
+
#else
|
|
610
|
+
value = ((PyStopIterationObject *)ev)->value;
|
|
611
|
+
Py_INCREF(value);
|
|
612
|
+
#endif
|
|
613
|
+
Py_DECREF(ev);
|
|
614
|
+
}
|
|
615
|
+
// PyErr_SetObject() and friends put the value directly into ev
|
|
616
|
+
else if (unlikely(PyTuple_Check(ev))) {
|
|
617
|
+
// if it's a tuple, it is interpreted as separate constructor arguments (surprise!)
|
|
618
|
+
Py_ssize_t tuple_size = __Pyx_PyTuple_GET_SIZE(ev);
|
|
619
|
+
#if !CYTHON_ASSUME_SAFE_SIZE
|
|
620
|
+
if (unlikely(tuple_size < 0)) {
|
|
621
|
+
Py_XDECREF(tb);
|
|
622
|
+
Py_DECREF(ev);
|
|
623
|
+
Py_DECREF(et);
|
|
624
|
+
return -1;
|
|
625
|
+
}
|
|
626
|
+
#endif
|
|
627
|
+
if (tuple_size >= 1) {
|
|
628
|
+
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
|
|
629
|
+
value = PyTuple_GET_ITEM(ev, 0);
|
|
630
|
+
Py_INCREF(value);
|
|
631
|
+
#elif CYTHON_ASSUME_SAFE_MACROS
|
|
632
|
+
value = PySequence_ITEM(ev, 0);
|
|
633
|
+
#else
|
|
634
|
+
value = PySequence_GetItem(ev, 0);
|
|
635
|
+
if (!value) goto limited_api_failure;
|
|
636
|
+
#endif
|
|
637
|
+
} else {
|
|
638
|
+
Py_INCREF(Py_None);
|
|
639
|
+
value = Py_None;
|
|
640
|
+
}
|
|
641
|
+
Py_DECREF(ev);
|
|
642
|
+
}
|
|
643
|
+
else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) {
|
|
644
|
+
// 'steal' reference to ev
|
|
645
|
+
value = ev;
|
|
646
|
+
}
|
|
647
|
+
if (likely(value)) {
|
|
648
|
+
Py_XDECREF(tb);
|
|
649
|
+
Py_DECREF(et);
|
|
650
|
+
*pvalue = value;
|
|
651
|
+
return 0;
|
|
652
|
+
}
|
|
653
|
+
} else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) {
|
|
654
|
+
__Pyx_ErrRestore(et, ev, tb);
|
|
655
|
+
return -1;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// otherwise: normalise and check what that gives us
|
|
659
|
+
PyErr_NormalizeException(&et, &ev, &tb);
|
|
660
|
+
if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) {
|
|
661
|
+
// looks like normalisation failed - raise the new exception
|
|
662
|
+
__Pyx_ErrRestore(et, ev, tb);
|
|
663
|
+
return -1;
|
|
664
|
+
}
|
|
665
|
+
Py_XDECREF(tb);
|
|
666
|
+
Py_DECREF(et);
|
|
667
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
668
|
+
value = PyObject_GetAttr(ev, PYIDENT("value"));
|
|
669
|
+
#else
|
|
670
|
+
value = ((PyStopIterationObject *)ev)->value;
|
|
671
|
+
Py_INCREF(value);
|
|
672
|
+
#endif
|
|
673
|
+
Py_DECREF(ev);
|
|
674
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
675
|
+
if (unlikely(!value)) return -1;
|
|
676
|
+
#endif
|
|
677
|
+
*pvalue = value;
|
|
678
|
+
return 0;
|
|
679
|
+
|
|
680
|
+
#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL || !CYTHON_ASSUME_SAFE_MACROS
|
|
681
|
+
limited_api_failure:
|
|
682
|
+
Py_XDECREF(et);
|
|
683
|
+
Py_XDECREF(tb);
|
|
684
|
+
Py_XDECREF(ev);
|
|
685
|
+
return -1;
|
|
686
|
+
#endif
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
static CYTHON_INLINE
|
|
690
|
+
__Pyx_PySendResult __Pyx_Coroutine_status_from_result(PyObject **retval) {
|
|
691
|
+
if (*retval) {
|
|
692
|
+
return PYGEN_NEXT;
|
|
693
|
+
} else if (likely(__Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, retval) == 0)) {
|
|
694
|
+
//assert (*retval == Py_None);
|
|
695
|
+
return PYGEN_RETURN;
|
|
696
|
+
} else {
|
|
697
|
+
return PYGEN_ERROR;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
static CYTHON_INLINE
|
|
702
|
+
void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) {
|
|
703
|
+
#if PY_VERSION_HEX >= 0x030B00a4
|
|
704
|
+
Py_CLEAR(exc_state->exc_value);
|
|
705
|
+
#else
|
|
706
|
+
PyObject *t, *v, *tb;
|
|
707
|
+
t = exc_state->exc_type;
|
|
708
|
+
v = exc_state->exc_value;
|
|
709
|
+
tb = exc_state->exc_traceback;
|
|
710
|
+
|
|
711
|
+
exc_state->exc_type = NULL;
|
|
712
|
+
exc_state->exc_value = NULL;
|
|
713
|
+
exc_state->exc_traceback = NULL;
|
|
714
|
+
|
|
715
|
+
Py_XDECREF(t);
|
|
716
|
+
Py_XDECREF(v);
|
|
717
|
+
Py_XDECREF(tb);
|
|
718
|
+
#endif
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
#define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL)
|
|
722
|
+
static void __Pyx__Coroutine_AlreadyRunningError(__pyx_CoroutineObject *gen) {
|
|
723
|
+
const char *msg;
|
|
724
|
+
CYTHON_MAYBE_UNUSED_VAR(gen);
|
|
725
|
+
if ((0)) {
|
|
726
|
+
#ifdef __Pyx_Coroutine_USED
|
|
727
|
+
} else if (__Pyx_Coroutine_Check((PyObject*)gen)) {
|
|
728
|
+
msg = "coroutine already executing";
|
|
729
|
+
#endif
|
|
730
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
731
|
+
} else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) {
|
|
732
|
+
msg = "async generator already executing";
|
|
733
|
+
#endif
|
|
734
|
+
} else {
|
|
735
|
+
msg = "generator already executing";
|
|
736
|
+
}
|
|
737
|
+
PyErr_SetString(PyExc_ValueError, msg);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
static void __Pyx_Coroutine_AlreadyTerminatedError(PyObject *gen, PyObject *value, int closing) {
|
|
741
|
+
CYTHON_MAYBE_UNUSED_VAR(gen);
|
|
742
|
+
CYTHON_MAYBE_UNUSED_VAR(closing);
|
|
743
|
+
#ifdef __Pyx_Coroutine_USED
|
|
744
|
+
if (!closing && __Pyx_Coroutine_Check(gen)) {
|
|
745
|
+
// `self` is an exhausted coroutine: raise an error,
|
|
746
|
+
// except when called from gen_close(), which should
|
|
747
|
+
// always be a silent method.
|
|
748
|
+
PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine");
|
|
749
|
+
} else
|
|
750
|
+
#endif
|
|
751
|
+
if (value) {
|
|
752
|
+
// `gen` is an exhausted generator:
|
|
753
|
+
// only set exception if called from send().
|
|
754
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
755
|
+
if (__Pyx_AsyncGen_CheckExact(gen))
|
|
756
|
+
PyErr_SetNone(PyExc_StopAsyncIteration);
|
|
757
|
+
else
|
|
758
|
+
#endif
|
|
759
|
+
PyErr_SetNone(PyExc_StopIteration);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
static
|
|
764
|
+
__Pyx_PySendResult __Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, PyObject **result, int closing) {
|
|
765
|
+
__Pyx_PyThreadState_declare
|
|
766
|
+
PyThreadState *tstate;
|
|
767
|
+
__Pyx_ExcInfoStruct *exc_state;
|
|
768
|
+
PyObject *retval;
|
|
769
|
+
|
|
770
|
+
assert(__Pyx_Coroutine_get_is_running(self)); // Callers should ensure is_running
|
|
771
|
+
|
|
772
|
+
if (unlikely(self->resume_label == -1)) {
|
|
773
|
+
__Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing);
|
|
774
|
+
return PYGEN_ERROR;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
#if CYTHON_FAST_THREAD_STATE
|
|
778
|
+
__Pyx_PyThreadState_assign
|
|
779
|
+
tstate = $local_tstate_cname;
|
|
780
|
+
#else
|
|
781
|
+
tstate = __Pyx_PyThreadState_Current;
|
|
782
|
+
#endif
|
|
783
|
+
|
|
784
|
+
// Traceback/Frame rules pre-Py3.7:
|
|
785
|
+
// - on entry, save external exception state in self->gi_exc_state, restore it on exit
|
|
786
|
+
// - on exit, keep internally generated exceptions in self->gi_exc_state, clear everything else
|
|
787
|
+
// - on entry, set "f_back" pointer of internal exception traceback to (current) outer call frame
|
|
788
|
+
// - on exit, clear "f_back" of internal exception traceback
|
|
789
|
+
// - do not touch external frames and tracebacks
|
|
790
|
+
|
|
791
|
+
// Traceback/Frame rules for Py3.7+ (CYTHON_USE_EXC_INFO_STACK):
|
|
792
|
+
// - on entry, push internal exception state in self->gi_exc_state on the exception stack
|
|
793
|
+
// - on exit, keep internally generated exceptions in self->gi_exc_state, clear everything else
|
|
794
|
+
// - on entry, set "f_back" pointer of internal exception traceback to (current) outer call frame
|
|
795
|
+
// - on exit, clear "f_back" of internal exception traceback
|
|
796
|
+
// - do not touch external frames and tracebacks
|
|
797
|
+
|
|
798
|
+
// In the Limited API/PyPy
|
|
799
|
+
// - on entry, save external exception state in self->gi_exc_state, restore it on exit
|
|
800
|
+
// - on exit, keep internally generated exceptions in self->gi_exc_state, clear everything else
|
|
801
|
+
// - don't mess with f_back because we can't work out how to do that
|
|
802
|
+
// - do not touch external frames and tracebacks
|
|
803
|
+
|
|
804
|
+
exc_state = &self->gi_exc_state;
|
|
805
|
+
if (exc_state->exc_value) {
|
|
806
|
+
#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY
|
|
807
|
+
// FIXME - it'd be nice to handle f_back
|
|
808
|
+
#else
|
|
809
|
+
// Generators always return to their most recent caller, not
|
|
810
|
+
// necessarily their creator.
|
|
811
|
+
PyObject *exc_tb;
|
|
812
|
+
#if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON
|
|
813
|
+
// owned reference!
|
|
814
|
+
exc_tb = PyException_GetTraceback(exc_state->exc_value);
|
|
815
|
+
#elif PY_VERSION_HEX >= 0x030B00a4
|
|
816
|
+
exc_tb = ((PyBaseExceptionObject*) exc_state->exc_value)->traceback;
|
|
817
|
+
#else
|
|
818
|
+
exc_tb = exc_state->exc_traceback;
|
|
819
|
+
#endif
|
|
820
|
+
if (exc_tb) {
|
|
821
|
+
PyTracebackObject *tb = (PyTracebackObject *) exc_tb;
|
|
822
|
+
PyFrameObject *f = tb->tb_frame;
|
|
823
|
+
|
|
824
|
+
assert(f->f_back == NULL);
|
|
825
|
+
#if PY_VERSION_HEX >= 0x030B00A1
|
|
826
|
+
// PyThreadState_GetFrame returns NULL if there isn't a current frame
|
|
827
|
+
// which is a valid state so no need to check
|
|
828
|
+
f->f_back = PyThreadState_GetFrame(tstate);
|
|
829
|
+
#else
|
|
830
|
+
Py_XINCREF(tstate->frame);
|
|
831
|
+
f->f_back = tstate->frame;
|
|
832
|
+
#endif
|
|
833
|
+
#if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON
|
|
834
|
+
Py_DECREF(exc_tb);
|
|
835
|
+
#endif
|
|
836
|
+
}
|
|
837
|
+
#endif
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
#if CYTHON_USE_EXC_INFO_STACK
|
|
841
|
+
// See https://bugs.python.org/issue25612
|
|
842
|
+
exc_state->previous_item = tstate->exc_info;
|
|
843
|
+
tstate->exc_info = exc_state;
|
|
844
|
+
#else
|
|
845
|
+
if (exc_state->exc_type) {
|
|
846
|
+
// We were in an except handler when we left,
|
|
847
|
+
// restore the exception state which was put aside.
|
|
848
|
+
__Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback);
|
|
849
|
+
// self->exc_* now holds the exception state of the caller
|
|
850
|
+
} else {
|
|
851
|
+
// save away the exception state of the caller
|
|
852
|
+
__Pyx_Coroutine_ExceptionClear(exc_state);
|
|
853
|
+
__Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback);
|
|
854
|
+
}
|
|
855
|
+
#endif
|
|
856
|
+
|
|
857
|
+
retval = self->body(self, tstate, value);
|
|
858
|
+
|
|
859
|
+
#if CYTHON_USE_EXC_INFO_STACK
|
|
860
|
+
// See https://bugs.python.org/issue25612
|
|
861
|
+
exc_state = &self->gi_exc_state;
|
|
862
|
+
tstate->exc_info = exc_state->previous_item;
|
|
863
|
+
exc_state->previous_item = NULL;
|
|
864
|
+
// Cut off the exception frame chain so that we can reconnect it on re-entry above.
|
|
865
|
+
__Pyx_Coroutine_ResetFrameBackpointer(exc_state);
|
|
866
|
+
#endif
|
|
867
|
+
|
|
868
|
+
*result = retval;
|
|
869
|
+
|
|
870
|
+
if (self->resume_label == -1) {
|
|
871
|
+
// terminated => return or error?
|
|
872
|
+
return likely(retval) ? PYGEN_RETURN : PYGEN_ERROR;
|
|
873
|
+
}
|
|
874
|
+
return PYGEN_NEXT;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) {
|
|
878
|
+
// Don't keep the reference to f_back any longer than necessary. It
|
|
879
|
+
// may keep a chain of frames alive or it could create a reference
|
|
880
|
+
// cycle.
|
|
881
|
+
#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API
|
|
882
|
+
// FIXME: what to do in PyPy?
|
|
883
|
+
CYTHON_UNUSED_VAR(exc_state);
|
|
884
|
+
#else
|
|
885
|
+
PyObject *exc_tb;
|
|
886
|
+
|
|
887
|
+
#if PY_VERSION_HEX >= 0x030B00a4
|
|
888
|
+
if (!exc_state->exc_value) return;
|
|
889
|
+
// owned reference!
|
|
890
|
+
exc_tb = PyException_GetTraceback(exc_state->exc_value);
|
|
891
|
+
#else
|
|
892
|
+
exc_tb = exc_state->exc_traceback;
|
|
893
|
+
#endif
|
|
894
|
+
|
|
895
|
+
if (likely(exc_tb)) {
|
|
896
|
+
PyTracebackObject *tb = (PyTracebackObject *) exc_tb;
|
|
897
|
+
PyFrameObject *f = tb->tb_frame;
|
|
898
|
+
Py_CLEAR(f->f_back);
|
|
899
|
+
#if PY_VERSION_HEX >= 0x030B00a4
|
|
900
|
+
Py_DECREF(exc_tb);
|
|
901
|
+
#endif
|
|
902
|
+
}
|
|
903
|
+
#endif
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
#define __Pyx_Coroutine_MethodReturnFromResult(gen, result, retval, iternext) \
|
|
907
|
+
((result) == PYGEN_NEXT ? (retval) : __Pyx__Coroutine_MethodReturnFromResult(gen, result, retval, iternext))
|
|
908
|
+
|
|
909
|
+
static PyObject *
|
|
910
|
+
__Pyx__Coroutine_MethodReturnFromResult(PyObject* gen, __Pyx_PySendResult result, PyObject *retval, int iternext) {
|
|
911
|
+
CYTHON_MAYBE_UNUSED_VAR(gen);
|
|
912
|
+
if (likely(result == PYGEN_RETURN)) {
|
|
913
|
+
// return values pass through StopIteration or StopAsyncIteration
|
|
914
|
+
int is_async = 0;
|
|
915
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
916
|
+
is_async = __Pyx_AsyncGen_CheckExact(gen);
|
|
917
|
+
#endif
|
|
918
|
+
__Pyx_ReturnWithStopIteration(retval, is_async, iternext);
|
|
919
|
+
Py_XDECREF(retval);
|
|
920
|
+
}
|
|
921
|
+
return NULL;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
#if CYTHON_COMPILING_IN_CPYTHON
|
|
925
|
+
static CYTHON_INLINE
|
|
926
|
+
PyObject *__Pyx_PyGen_Send(PyGenObject *gen, PyObject *arg) {
|
|
927
|
+
#if PY_VERSION_HEX <= 0x030A00A1
|
|
928
|
+
return _PyGen_Send(gen, arg);
|
|
929
|
+
#else
|
|
930
|
+
PyObject *result;
|
|
931
|
+
// PyIter_Send() asserts non-NULL arg
|
|
932
|
+
if (PyIter_Send((PyObject*)gen, arg ? arg : Py_None, &result) == PYGEN_RETURN) {
|
|
933
|
+
if (PyAsyncGen_CheckExact(gen)) {
|
|
934
|
+
assert(result == Py_None);
|
|
935
|
+
PyErr_SetNone(PyExc_StopAsyncIteration);
|
|
936
|
+
}
|
|
937
|
+
else if (result == Py_None) {
|
|
938
|
+
PyErr_SetNone(PyExc_StopIteration);
|
|
939
|
+
}
|
|
940
|
+
else {
|
|
941
|
+
#if PY_VERSION_HEX < 0x030d00A1
|
|
942
|
+
_PyGen_SetStopIterationValue(result);
|
|
943
|
+
#else
|
|
944
|
+
if (!PyTuple_Check(result) && !PyExceptionInstance_Check(result)) {
|
|
945
|
+
// delay instantiation if possible
|
|
946
|
+
PyErr_SetObject(PyExc_StopIteration, result);
|
|
947
|
+
} else {
|
|
948
|
+
PyObject *exc = __Pyx_PyObject_CallOneArg(PyExc_StopIteration, result);
|
|
949
|
+
if (likely(exc != NULL)) {
|
|
950
|
+
PyErr_SetObject(PyExc_StopIteration, exc);
|
|
951
|
+
Py_DECREF(exc);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
#endif
|
|
955
|
+
}
|
|
956
|
+
Py_DECREF(result);
|
|
957
|
+
result = NULL;
|
|
958
|
+
}
|
|
959
|
+
return result;
|
|
960
|
+
#endif
|
|
961
|
+
}
|
|
962
|
+
#endif
|
|
963
|
+
|
|
964
|
+
static CYTHON_INLINE __Pyx_PySendResult
|
|
965
|
+
__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen, PyObject** retval) {
|
|
966
|
+
__Pyx_PySendResult result;
|
|
967
|
+
PyObject *val = NULL;
|
|
968
|
+
assert(__Pyx_Coroutine_get_is_running(gen));
|
|
969
|
+
__Pyx_Coroutine_Undelegate(gen);
|
|
970
|
+
__Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val);
|
|
971
|
+
// val == NULL on failure => pass on exception
|
|
972
|
+
result = __Pyx_Coroutine_SendEx(gen, val, retval, 0);
|
|
973
|
+
Py_XDECREF(val);
|
|
974
|
+
return result;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
#if CYTHON_USE_AM_SEND
|
|
978
|
+
static __Pyx_PySendResult
|
|
979
|
+
__Pyx_Coroutine_SendToDelegate(__pyx_CoroutineObject *gen, __Pyx_pyiter_sendfunc gen_am_send, PyObject *value, PyObject **retval) {
|
|
980
|
+
PyObject *ret = NULL;
|
|
981
|
+
__Pyx_PySendResult result;
|
|
982
|
+
assert(__Pyx_Coroutine_get_is_running(gen));
|
|
983
|
+
// we assume that gen->yieldfrom cannot change as long as 'gen->is_running' is set => no safety INCREF()
|
|
984
|
+
result = gen_am_send(gen->yieldfrom, value, &ret);
|
|
985
|
+
if (result == PYGEN_NEXT) {
|
|
986
|
+
assert (ret != NULL);
|
|
987
|
+
*retval = ret;
|
|
988
|
+
return PYGEN_NEXT;
|
|
989
|
+
}
|
|
990
|
+
//assert (result == PYGEN_ERROR ? ret == NULL : ret != NULL);
|
|
991
|
+
assert (result != PYGEN_ERROR || ret == NULL);
|
|
992
|
+
__Pyx_Coroutine_Undelegate(gen);
|
|
993
|
+
return __Pyx_Coroutine_SendEx(gen, ret, retval, 0);
|
|
994
|
+
}
|
|
995
|
+
#endif
|
|
996
|
+
|
|
997
|
+
static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) {
|
|
998
|
+
PyObject *retval = NULL;
|
|
999
|
+
__Pyx_PySendResult result = __Pyx_Coroutine_AmSend(self, value, &retval);
|
|
1000
|
+
return __Pyx_Coroutine_MethodReturnFromResult(self, result, retval, 0);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
static __Pyx_PySendResult
|
|
1004
|
+
__Pyx_Coroutine_AmSend(PyObject *self, PyObject *value, PyObject **retval) {
|
|
1005
|
+
__Pyx_PySendResult result;
|
|
1006
|
+
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
|
|
1007
|
+
if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) {
|
|
1008
|
+
*retval = __Pyx_Coroutine_AlreadyRunningError(gen);
|
|
1009
|
+
return PYGEN_ERROR;
|
|
1010
|
+
}
|
|
1011
|
+
#if CYTHON_USE_AM_SEND
|
|
1012
|
+
if (gen->yieldfrom_am_send) {
|
|
1013
|
+
result = __Pyx_Coroutine_SendToDelegate(gen, gen->yieldfrom_am_send, value, retval);
|
|
1014
|
+
} else
|
|
1015
|
+
#endif
|
|
1016
|
+
if (gen->yieldfrom) {
|
|
1017
|
+
PyObject *yf = gen->yieldfrom;
|
|
1018
|
+
PyObject *ret;
|
|
1019
|
+
#if !CYTHON_USE_AM_SEND
|
|
1020
|
+
// Py3.10 puts "am_send" into "gen->yieldfrom_am_send" instead of using these special cases.
|
|
1021
|
+
// See "__Pyx_Coroutine_Set_Owned_Yield_From()" above.
|
|
1022
|
+
#ifdef __Pyx_Generator_USED
|
|
1023
|
+
if (__Pyx_Generator_CheckExact(yf)) {
|
|
1024
|
+
ret = __Pyx_Coroutine_Send(yf, value);
|
|
1025
|
+
} else
|
|
1026
|
+
#endif
|
|
1027
|
+
#ifdef __Pyx_Coroutine_USED
|
|
1028
|
+
if (__Pyx_Coroutine_Check(yf)) {
|
|
1029
|
+
ret = __Pyx_Coroutine_Send(yf, value);
|
|
1030
|
+
} else
|
|
1031
|
+
#endif
|
|
1032
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
1033
|
+
if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
|
|
1034
|
+
ret = __Pyx_async_gen_asend_send(yf, value);
|
|
1035
|
+
} else
|
|
1036
|
+
#endif
|
|
1037
|
+
#if CYTHON_COMPILING_IN_CPYTHON
|
|
1038
|
+
if (PyGen_CheckExact(yf)) {
|
|
1039
|
+
ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value);
|
|
1040
|
+
} else
|
|
1041
|
+
if (PyCoro_CheckExact(yf)) {
|
|
1042
|
+
ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value);
|
|
1043
|
+
} else
|
|
1044
|
+
#endif
|
|
1045
|
+
#endif
|
|
1046
|
+
{
|
|
1047
|
+
#if !CYTHON_COMPILING_IN_LIMITED_API || __PYX_LIMITED_VERSION_HEX >= 0x03080000
|
|
1048
|
+
// PyIter_Check() is needed here but broken in the Py3.7 Limited API.
|
|
1049
|
+
if (value == Py_None && PyIter_Check(yf))
|
|
1050
|
+
ret = __Pyx_PyIter_Next_Plain(yf);
|
|
1051
|
+
else
|
|
1052
|
+
#endif
|
|
1053
|
+
ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value);
|
|
1054
|
+
}
|
|
1055
|
+
if (likely(ret)) {
|
|
1056
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1057
|
+
*retval = ret;
|
|
1058
|
+
return PYGEN_NEXT;
|
|
1059
|
+
}
|
|
1060
|
+
result = __Pyx_Coroutine_FinishDelegation(gen, retval);
|
|
1061
|
+
} else {
|
|
1062
|
+
result = __Pyx_Coroutine_SendEx(gen, value, retval, 0);
|
|
1063
|
+
}
|
|
1064
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1065
|
+
return result;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// This helper function is used by gen_close and gen_throw to
|
|
1069
|
+
// close a subiterator being delegated to by yield-from.
|
|
1070
|
+
static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) {
|
|
1071
|
+
__Pyx_PySendResult result;
|
|
1072
|
+
PyObject *retval = NULL;
|
|
1073
|
+
CYTHON_UNUSED_VAR(gen);
|
|
1074
|
+
|
|
1075
|
+
assert(__Pyx_Coroutine_get_is_running(gen));
|
|
1076
|
+
|
|
1077
|
+
#ifdef __Pyx_Generator_USED
|
|
1078
|
+
if (__Pyx_Generator_CheckExact(yf)) {
|
|
1079
|
+
result = __Pyx_Coroutine_Close(yf, &retval);
|
|
1080
|
+
} else
|
|
1081
|
+
#endif
|
|
1082
|
+
#ifdef __Pyx_Coroutine_USED
|
|
1083
|
+
if (__Pyx_Coroutine_Check(yf)) {
|
|
1084
|
+
result = __Pyx_Coroutine_Close(yf, &retval);
|
|
1085
|
+
} else
|
|
1086
|
+
if (__Pyx_CoroutineAwait_CheckExact(yf)) {
|
|
1087
|
+
result = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf);
|
|
1088
|
+
} else
|
|
1089
|
+
#endif
|
|
1090
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
1091
|
+
if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
|
|
1092
|
+
retval = __Pyx_async_gen_asend_close(yf, NULL);
|
|
1093
|
+
// cannot fail
|
|
1094
|
+
result = PYGEN_RETURN;
|
|
1095
|
+
} else
|
|
1096
|
+
if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) {
|
|
1097
|
+
retval = __Pyx_async_gen_athrow_close(yf, NULL);
|
|
1098
|
+
// cannot fail
|
|
1099
|
+
result = PYGEN_RETURN;
|
|
1100
|
+
} else
|
|
1101
|
+
#endif
|
|
1102
|
+
{
|
|
1103
|
+
PyObject *meth;
|
|
1104
|
+
result = PYGEN_RETURN;
|
|
1105
|
+
meth = __Pyx_PyObject_GetAttrStrNoError(yf, PYIDENT("close"));
|
|
1106
|
+
if (unlikely(!meth)) {
|
|
1107
|
+
if (unlikely(PyErr_Occurred())) {
|
|
1108
|
+
PyErr_WriteUnraisable(yf);
|
|
1109
|
+
}
|
|
1110
|
+
} else {
|
|
1111
|
+
retval = __Pyx_PyObject_CallNoArg(meth);
|
|
1112
|
+
Py_DECREF(meth);
|
|
1113
|
+
if (unlikely(!retval)) {
|
|
1114
|
+
result = PYGEN_ERROR;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
Py_XDECREF(retval);
|
|
1119
|
+
return result == PYGEN_ERROR ? -1 : 0;
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
static PyObject *__Pyx_Generator_Next(PyObject *self) {
|
|
1123
|
+
__Pyx_PySendResult result;
|
|
1124
|
+
PyObject *retval = NULL;
|
|
1125
|
+
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
|
|
1126
|
+
if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) {
|
|
1127
|
+
return __Pyx_Coroutine_AlreadyRunningError(gen);
|
|
1128
|
+
}
|
|
1129
|
+
#if CYTHON_USE_AM_SEND
|
|
1130
|
+
if (gen->yieldfrom_am_send) {
|
|
1131
|
+
result = __Pyx_Coroutine_SendToDelegate(gen, gen->yieldfrom_am_send, Py_None, &retval);
|
|
1132
|
+
} else
|
|
1133
|
+
#endif
|
|
1134
|
+
if (gen->yieldfrom) {
|
|
1135
|
+
PyObject *yf = gen->yieldfrom;
|
|
1136
|
+
PyObject *ret;
|
|
1137
|
+
// YieldFrom code ensures that yf is an iterator
|
|
1138
|
+
#ifdef __Pyx_Generator_USED
|
|
1139
|
+
if (__Pyx_Generator_CheckExact(yf)) {
|
|
1140
|
+
ret = __Pyx_Generator_Next(yf);
|
|
1141
|
+
} else
|
|
1142
|
+
#endif
|
|
1143
|
+
#ifdef __Pyx_Coroutine_USED
|
|
1144
|
+
// See https://github.com/cython/cython/issues/1999
|
|
1145
|
+
if (__Pyx_Coroutine_CheckExact(yf)) {
|
|
1146
|
+
ret = __Pyx_Coroutine_Send(yf, Py_None);
|
|
1147
|
+
} else
|
|
1148
|
+
#endif
|
|
1149
|
+
#if CYTHON_COMPILING_IN_CPYTHON && (PY_VERSION_HEX < 0x030A00A3 || !CYTHON_USE_AM_SEND)
|
|
1150
|
+
// _PyGen_Send() is not needed in 3.10+ due to "am_send"
|
|
1151
|
+
if (PyGen_CheckExact(yf)) {
|
|
1152
|
+
ret = __Pyx_PyGen_Send((PyGenObject*)yf, NULL);
|
|
1153
|
+
} else
|
|
1154
|
+
#endif
|
|
1155
|
+
ret = __Pyx_PyIter_Next_Plain(yf);
|
|
1156
|
+
if (likely(ret)) {
|
|
1157
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1158
|
+
return ret;
|
|
1159
|
+
}
|
|
1160
|
+
result = __Pyx_Coroutine_FinishDelegation(gen, &retval);
|
|
1161
|
+
} else {
|
|
1162
|
+
result = __Pyx_Coroutine_SendEx(gen, Py_None, &retval, 0);
|
|
1163
|
+
}
|
|
1164
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1165
|
+
|
|
1166
|
+
return __Pyx_Coroutine_MethodReturnFromResult(self, result, retval, 1);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, PyObject *arg) {
|
|
1170
|
+
PyObject *retval = NULL;
|
|
1171
|
+
__Pyx_PySendResult result;
|
|
1172
|
+
CYTHON_UNUSED_VAR(arg);
|
|
1173
|
+
result = __Pyx_Coroutine_Close(self, &retval);
|
|
1174
|
+
if (unlikely(result == PYGEN_ERROR))
|
|
1175
|
+
return NULL;
|
|
1176
|
+
Py_XDECREF(retval);
|
|
1177
|
+
Py_RETURN_NONE;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
static __Pyx_PySendResult
|
|
1181
|
+
__Pyx_Coroutine_Close(PyObject *self, PyObject **retval) {
|
|
1182
|
+
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
|
|
1183
|
+
__Pyx_PySendResult result;
|
|
1184
|
+
PyObject *yf;
|
|
1185
|
+
int err = 0;
|
|
1186
|
+
|
|
1187
|
+
if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) {
|
|
1188
|
+
*retval = __Pyx_Coroutine_AlreadyRunningError(gen);
|
|
1189
|
+
return PYGEN_ERROR;
|
|
1190
|
+
}
|
|
1191
|
+
yf = gen->yieldfrom;
|
|
1192
|
+
|
|
1193
|
+
if (yf) {
|
|
1194
|
+
Py_INCREF(yf);
|
|
1195
|
+
err = __Pyx_Coroutine_CloseIter(gen, yf);
|
|
1196
|
+
__Pyx_Coroutine_Undelegate(gen);
|
|
1197
|
+
Py_DECREF(yf);
|
|
1198
|
+
}
|
|
1199
|
+
if (err == 0)
|
|
1200
|
+
PyErr_SetNone(PyExc_GeneratorExit);
|
|
1201
|
+
result = __Pyx_Coroutine_SendEx(gen, NULL, retval, 1);
|
|
1202
|
+
if (result == PYGEN_ERROR) {
|
|
1203
|
+
// WARNING: *retval == NULL !
|
|
1204
|
+
__Pyx_PyThreadState_declare
|
|
1205
|
+
__Pyx_PyThreadState_assign
|
|
1206
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1207
|
+
if (!__Pyx_PyErr_Occurred()) {
|
|
1208
|
+
return PYGEN_RETURN;
|
|
1209
|
+
} else if (likely(__Pyx_PyErr_ExceptionMatches2(PyExc_GeneratorExit, PyExc_StopIteration))) {
|
|
1210
|
+
__Pyx_PyErr_Clear();
|
|
1211
|
+
return PYGEN_RETURN;
|
|
1212
|
+
}
|
|
1213
|
+
return PYGEN_ERROR;
|
|
1214
|
+
} else if (likely(result == PYGEN_RETURN && *retval == Py_None)) {
|
|
1215
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1216
|
+
return PYGEN_RETURN;
|
|
1217
|
+
} else {
|
|
1218
|
+
const char *msg;
|
|
1219
|
+
Py_DECREF(*retval);
|
|
1220
|
+
*retval = NULL;
|
|
1221
|
+
if ((0)) {
|
|
1222
|
+
#ifdef __Pyx_Coroutine_USED
|
|
1223
|
+
} else if (__Pyx_Coroutine_Check(self)) {
|
|
1224
|
+
msg = "coroutine ignored GeneratorExit";
|
|
1225
|
+
#endif
|
|
1226
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
1227
|
+
} else if (__Pyx_AsyncGen_CheckExact(self)) {
|
|
1228
|
+
msg = "async generator ignored GeneratorExit";
|
|
1229
|
+
#endif
|
|
1230
|
+
} else {
|
|
1231
|
+
msg = "generator ignored GeneratorExit";
|
|
1232
|
+
}
|
|
1233
|
+
PyErr_SetString(PyExc_RuntimeError, msg);
|
|
1234
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1235
|
+
return PYGEN_ERROR;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb,
|
|
1240
|
+
PyObject *args, int close_on_genexit) {
|
|
1241
|
+
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
|
|
1242
|
+
PyObject *yf;
|
|
1243
|
+
|
|
1244
|
+
if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen)))
|
|
1245
|
+
return __Pyx_Coroutine_AlreadyRunningError(gen);
|
|
1246
|
+
|
|
1247
|
+
yf = gen->yieldfrom;
|
|
1248
|
+
if (yf) {
|
|
1249
|
+
__Pyx_PySendResult result;
|
|
1250
|
+
PyObject *ret;
|
|
1251
|
+
Py_INCREF(yf);
|
|
1252
|
+
if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) {
|
|
1253
|
+
// Asynchronous generators *should not* be closed right away.
|
|
1254
|
+
// We have to allow some awaits to work it through, hence the
|
|
1255
|
+
// `close_on_genexit` parameter here.
|
|
1256
|
+
int err = __Pyx_Coroutine_CloseIter(gen, yf);
|
|
1257
|
+
Py_DECREF(yf);
|
|
1258
|
+
__Pyx_Coroutine_Undelegate(gen);
|
|
1259
|
+
if (err < 0)
|
|
1260
|
+
goto propagate_exception;
|
|
1261
|
+
goto throw_here;
|
|
1262
|
+
}
|
|
1263
|
+
if (0
|
|
1264
|
+
#ifdef __Pyx_Generator_USED
|
|
1265
|
+
|| __Pyx_Generator_CheckExact(yf)
|
|
1266
|
+
#endif
|
|
1267
|
+
#ifdef __Pyx_Coroutine_USED
|
|
1268
|
+
|| __Pyx_Coroutine_Check(yf)
|
|
1269
|
+
#endif
|
|
1270
|
+
) {
|
|
1271
|
+
ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit);
|
|
1272
|
+
#ifdef __Pyx_Coroutine_USED
|
|
1273
|
+
} else if (__Pyx_CoroutineAwait_CheckExact(yf)) {
|
|
1274
|
+
ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit);
|
|
1275
|
+
#endif
|
|
1276
|
+
} else {
|
|
1277
|
+
PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, PYIDENT("throw"));
|
|
1278
|
+
if (unlikely(!meth)) {
|
|
1279
|
+
Py_DECREF(yf);
|
|
1280
|
+
if (unlikely(PyErr_Occurred())) {
|
|
1281
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1282
|
+
return NULL;
|
|
1283
|
+
}
|
|
1284
|
+
__Pyx_Coroutine_Undelegate(gen);
|
|
1285
|
+
goto throw_here;
|
|
1286
|
+
}
|
|
1287
|
+
if (likely(args)) {
|
|
1288
|
+
ret = __Pyx_PyObject_Call(meth, args, NULL);
|
|
1289
|
+
} else {
|
|
1290
|
+
// "tb" or even "val" might be NULL, but that also correctly terminates the argument list
|
|
1291
|
+
PyObject *cargs[4] = {NULL, typ, val, tb};
|
|
1292
|
+
ret = __Pyx_PyObject_FastCall(meth, cargs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
|
|
1293
|
+
}
|
|
1294
|
+
Py_DECREF(meth);
|
|
1295
|
+
}
|
|
1296
|
+
Py_DECREF(yf);
|
|
1297
|
+
if (ret) {
|
|
1298
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1299
|
+
return ret;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
result = __Pyx_Coroutine_FinishDelegation(gen, &ret);
|
|
1303
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1304
|
+
return __Pyx_Coroutine_MethodReturnFromResult(self, result, ret, 0);
|
|
1305
|
+
}
|
|
1306
|
+
throw_here:
|
|
1307
|
+
__Pyx_Raise(typ, val, tb, NULL);
|
|
1308
|
+
|
|
1309
|
+
propagate_exception:
|
|
1310
|
+
{
|
|
1311
|
+
PyObject *retval = NULL;
|
|
1312
|
+
__Pyx_PySendResult result = __Pyx_Coroutine_SendEx(gen, NULL, &retval, 0);
|
|
1313
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
1314
|
+
return __Pyx_Coroutine_MethodReturnFromResult(self, result, retval, 0);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) {
|
|
1319
|
+
PyObject *typ;
|
|
1320
|
+
PyObject *val = NULL;
|
|
1321
|
+
PyObject *tb = NULL;
|
|
1322
|
+
|
|
1323
|
+
if (unlikely(!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb)))
|
|
1324
|
+
return NULL;
|
|
1325
|
+
|
|
1326
|
+
return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1);
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) {
|
|
1330
|
+
#if PY_VERSION_HEX >= 0x030B00a4
|
|
1331
|
+
Py_VISIT(exc_state->exc_value);
|
|
1332
|
+
#else
|
|
1333
|
+
Py_VISIT(exc_state->exc_type);
|
|
1334
|
+
Py_VISIT(exc_state->exc_value);
|
|
1335
|
+
Py_VISIT(exc_state->exc_traceback);
|
|
1336
|
+
#endif
|
|
1337
|
+
return 0;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) {
|
|
1341
|
+
{
|
|
1342
|
+
int e = __Pyx_call_type_traverse((PyObject*)gen, 1, visit, arg);
|
|
1343
|
+
if (e) return e;
|
|
1344
|
+
}
|
|
1345
|
+
Py_VISIT(gen->closure);
|
|
1346
|
+
Py_VISIT(gen->classobj);
|
|
1347
|
+
Py_VISIT(gen->yieldfrom);
|
|
1348
|
+
return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
static int __Pyx_Coroutine_clear(PyObject *self) {
|
|
1352
|
+
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
|
|
1353
|
+
|
|
1354
|
+
Py_CLEAR(gen->closure);
|
|
1355
|
+
Py_CLEAR(gen->classobj);
|
|
1356
|
+
__Pyx_Coroutine_Undelegate(gen);
|
|
1357
|
+
__Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state);
|
|
1358
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
1359
|
+
if (__Pyx_AsyncGen_CheckExact(self)) {
|
|
1360
|
+
Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer);
|
|
1361
|
+
}
|
|
1362
|
+
#endif
|
|
1363
|
+
Py_CLEAR(gen->gi_code);
|
|
1364
|
+
Py_CLEAR(gen->gi_frame);
|
|
1365
|
+
Py_CLEAR(gen->gi_name);
|
|
1366
|
+
Py_CLEAR(gen->gi_qualname);
|
|
1367
|
+
Py_CLEAR(gen->gi_modulename);
|
|
1368
|
+
return 0;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
static void __Pyx_Coroutine_dealloc(PyObject *self) {
|
|
1372
|
+
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
|
|
1373
|
+
|
|
1374
|
+
PyObject_GC_UnTrack(gen);
|
|
1375
|
+
if (gen->gi_weakreflist != NULL)
|
|
1376
|
+
PyObject_ClearWeakRefs(self);
|
|
1377
|
+
|
|
1378
|
+
if (gen->resume_label >= 0) {
|
|
1379
|
+
// Generator is paused or unstarted, so we need to close
|
|
1380
|
+
PyObject_GC_Track(self);
|
|
1381
|
+
#if CYTHON_USE_TP_FINALIZE
|
|
1382
|
+
if (unlikely(PyObject_CallFinalizerFromDealloc(self)))
|
|
1383
|
+
#else
|
|
1384
|
+
{
|
|
1385
|
+
destructor del = __Pyx_PyObject_GetSlot(gen, tp_del, destructor);
|
|
1386
|
+
if (del) del(self);
|
|
1387
|
+
}
|
|
1388
|
+
if (unlikely(Py_REFCNT(self) > 0))
|
|
1389
|
+
#endif
|
|
1390
|
+
{
|
|
1391
|
+
// resurrected. :(
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
PyObject_GC_UnTrack(self);
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
1398
|
+
if (__Pyx_AsyncGen_CheckExact(self)) {
|
|
1399
|
+
/* We have to handle this case for asynchronous generators
|
|
1400
|
+
right here, because this code has to be between UNTRACK
|
|
1401
|
+
and GC_Del. */
|
|
1402
|
+
Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer);
|
|
1403
|
+
}
|
|
1404
|
+
#endif
|
|
1405
|
+
__Pyx_Coroutine_clear(self);
|
|
1406
|
+
__Pyx_PyHeapTypeObject_GC_Del(gen);
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
#if CYTHON_USE_TP_FINALIZE
|
|
1410
|
+
static void __Pyx_Coroutine_del(PyObject *self) {
|
|
1411
|
+
PyObject *error_type, *error_value, *error_traceback;
|
|
1412
|
+
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
|
|
1413
|
+
__Pyx_PyThreadState_declare
|
|
1414
|
+
|
|
1415
|
+
if (gen->resume_label < 0) {
|
|
1416
|
+
// already terminated => nothing to clean up
|
|
1417
|
+
return;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
__Pyx_PyThreadState_assign
|
|
1421
|
+
|
|
1422
|
+
// Save the current exception, if any.
|
|
1423
|
+
__Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
|
|
1424
|
+
|
|
1425
|
+
#ifdef __Pyx_AsyncGen_USED
|
|
1426
|
+
if (__Pyx_AsyncGen_CheckExact(self)) {
|
|
1427
|
+
__pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self;
|
|
1428
|
+
PyObject *finalizer = agen->ag_finalizer;
|
|
1429
|
+
if (finalizer && !agen->ag_closed) {
|
|
1430
|
+
PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self);
|
|
1431
|
+
if (unlikely(!res)) {
|
|
1432
|
+
PyErr_WriteUnraisable(self);
|
|
1433
|
+
} else {
|
|
1434
|
+
Py_DECREF(res);
|
|
1435
|
+
}
|
|
1436
|
+
// Restore the saved exception.
|
|
1437
|
+
__Pyx_ErrRestore(error_type, error_value, error_traceback);
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
#endif
|
|
1442
|
+
|
|
1443
|
+
if (unlikely(gen->resume_label == 0 && !error_value)) {
|
|
1444
|
+
#ifdef __Pyx_Coroutine_USED
|
|
1445
|
+
#ifdef __Pyx_Generator_USED
|
|
1446
|
+
// only warn about (async) coroutines
|
|
1447
|
+
if (!__Pyx_Generator_CheckExact(self))
|
|
1448
|
+
#endif
|
|
1449
|
+
{
|
|
1450
|
+
// untrack dead object as we are executing Python code (which might trigger GC)
|
|
1451
|
+
PyObject_GC_UnTrack(self);
|
|
1452
|
+
if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0))
|
|
1453
|
+
PyErr_WriteUnraisable(self);
|
|
1454
|
+
PyObject_GC_Track(self);
|
|
1455
|
+
}
|
|
1456
|
+
#endif /*__Pyx_Coroutine_USED*/
|
|
1457
|
+
} else {
|
|
1458
|
+
PyObject *retval = NULL;
|
|
1459
|
+
__Pyx_PySendResult result = __Pyx_Coroutine_Close(self, &retval);
|
|
1460
|
+
if (result == PYGEN_ERROR) {
|
|
1461
|
+
PyErr_WriteUnraisable(self);
|
|
1462
|
+
} else {
|
|
1463
|
+
Py_XDECREF(retval);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
// Restore the saved exception.
|
|
1468
|
+
__Pyx_ErrRestore(error_type, error_value, error_traceback);
|
|
1469
|
+
}
|
|
1470
|
+
#endif
|
|
1471
|
+
|
|
1472
|
+
static PyObject *
|
|
1473
|
+
__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, void *context)
|
|
1474
|
+
{
|
|
1475
|
+
PyObject *name = self->gi_name;
|
|
1476
|
+
CYTHON_UNUSED_VAR(context);
|
|
1477
|
+
// avoid NULL pointer dereference during garbage collection
|
|
1478
|
+
if (unlikely(!name)) name = Py_None;
|
|
1479
|
+
Py_INCREF(name);
|
|
1480
|
+
return name;
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
static int
|
|
1484
|
+
__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, void *context)
|
|
1485
|
+
{
|
|
1486
|
+
CYTHON_UNUSED_VAR(context);
|
|
1487
|
+
if (unlikely(value == NULL || !PyUnicode_Check(value))) {
|
|
1488
|
+
PyErr_SetString(PyExc_TypeError,
|
|
1489
|
+
"__name__ must be set to a string object");
|
|
1490
|
+
return -1;
|
|
1491
|
+
}
|
|
1492
|
+
Py_INCREF(value);
|
|
1493
|
+
__Pyx_Py_XDECREF_SET(self->gi_name, value);
|
|
1494
|
+
return 0;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
static PyObject *
|
|
1498
|
+
__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, void *context)
|
|
1499
|
+
{
|
|
1500
|
+
PyObject *name = self->gi_qualname;
|
|
1501
|
+
CYTHON_UNUSED_VAR(context);
|
|
1502
|
+
// avoid NULL pointer dereference during garbage collection
|
|
1503
|
+
if (unlikely(!name)) name = Py_None;
|
|
1504
|
+
Py_INCREF(name);
|
|
1505
|
+
return name;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
static int
|
|
1509
|
+
__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, void *context)
|
|
1510
|
+
{
|
|
1511
|
+
CYTHON_UNUSED_VAR(context);
|
|
1512
|
+
if (unlikely(value == NULL || !PyUnicode_Check(value))) {
|
|
1513
|
+
PyErr_SetString(PyExc_TypeError,
|
|
1514
|
+
"__qualname__ must be set to a string object");
|
|
1515
|
+
return -1;
|
|
1516
|
+
}
|
|
1517
|
+
Py_INCREF(value);
|
|
1518
|
+
__Pyx_Py_XDECREF_SET(self->gi_qualname, value);
|
|
1519
|
+
return 0;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
static PyObject *
|
|
1523
|
+
__Pyx__Coroutine_get_frame(__pyx_CoroutineObject *self)
|
|
1524
|
+
{
|
|
1525
|
+
#if !CYTHON_COMPILING_IN_LIMITED_API
|
|
1526
|
+
PyObject *frame;
|
|
1527
|
+
#if PY_VERSION_HEX >= 0x030d0000
|
|
1528
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1529
|
+
#endif
|
|
1530
|
+
frame = self->gi_frame;
|
|
1531
|
+
if (!frame) {
|
|
1532
|
+
if (unlikely(!self->gi_code)) {
|
|
1533
|
+
// Avoid doing something stupid, e.g. during garbage collection.
|
|
1534
|
+
Py_RETURN_NONE;
|
|
1535
|
+
}
|
|
1536
|
+
// The coroutine doesn't know what module it's in so can't fill in proper globals.
|
|
1537
|
+
// In principle this could be solved by storing a reference to the module in the coroutine,
|
|
1538
|
+
// but in practice it probably isn't worth the extra memory.
|
|
1539
|
+
// Therefore, just supply a blank dict.
|
|
1540
|
+
PyObject *globals = PyDict_New();
|
|
1541
|
+
if (unlikely(!globals)) return NULL;
|
|
1542
|
+
frame = (PyObject *) PyFrame_New(
|
|
1543
|
+
PyThreadState_Get(), /*PyThreadState *tstate,*/
|
|
1544
|
+
(PyCodeObject*) self->gi_code, /*PyCodeObject *code,*/
|
|
1545
|
+
globals, /*PyObject *globals,*/
|
|
1546
|
+
0 /*PyObject *locals*/
|
|
1547
|
+
);
|
|
1548
|
+
Py_DECREF(globals);
|
|
1549
|
+
if (unlikely(!frame))
|
|
1550
|
+
return NULL;
|
|
1551
|
+
// handle potential race initializing the frame
|
|
1552
|
+
if (unlikely(self->gi_frame)) {
|
|
1553
|
+
Py_DECREF(frame);
|
|
1554
|
+
frame = self->gi_frame;
|
|
1555
|
+
} else {
|
|
1556
|
+
// keep the frame cached once it's created
|
|
1557
|
+
self->gi_frame = frame;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
Py_INCREF(frame);
|
|
1561
|
+
#if PY_VERSION_HEX >= 0x030d0000
|
|
1562
|
+
Py_END_CRITICAL_SECTION();
|
|
1563
|
+
#endif
|
|
1564
|
+
return frame;
|
|
1565
|
+
#else
|
|
1566
|
+
// In the limited API there probably isn't much we can usefully do to get a frame
|
|
1567
|
+
CYTHON_UNUSED_VAR(self);
|
|
1568
|
+
Py_RETURN_NONE;
|
|
1569
|
+
#endif
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
static PyObject *
|
|
1573
|
+
__Pyx_Coroutine_get_frame(__pyx_CoroutineObject *self, void *context) {
|
|
1574
|
+
CYTHON_UNUSED_VAR(context);
|
|
1575
|
+
PyObject *frame = self->gi_frame;
|
|
1576
|
+
if (frame)
|
|
1577
|
+
return __Pyx_NewRef(frame);
|
|
1578
|
+
return __Pyx__Coroutine_get_frame(self);
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
|
|
1582
|
+
PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
|
|
1583
|
+
PyObject *name, PyObject *qualname, PyObject *module_name) {
|
|
1584
|
+
__pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type);
|
|
1585
|
+
if (unlikely(!gen))
|
|
1586
|
+
return NULL;
|
|
1587
|
+
return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name);
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
|
|
1591
|
+
__pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
|
|
1592
|
+
PyObject *name, PyObject *qualname, PyObject *module_name) {
|
|
1593
|
+
gen->body = body;
|
|
1594
|
+
gen->closure = closure;
|
|
1595
|
+
Py_XINCREF(closure);
|
|
1596
|
+
gen->is_running = 0;
|
|
1597
|
+
gen->resume_label = 0;
|
|
1598
|
+
gen->classobj = NULL;
|
|
1599
|
+
gen->yieldfrom = NULL;
|
|
1600
|
+
gen->yieldfrom_am_send = NULL;
|
|
1601
|
+
#if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_LIMITED_API
|
|
1602
|
+
gen->gi_exc_state.exc_value = NULL;
|
|
1603
|
+
#else
|
|
1604
|
+
gen->gi_exc_state.exc_type = NULL;
|
|
1605
|
+
gen->gi_exc_state.exc_value = NULL;
|
|
1606
|
+
gen->gi_exc_state.exc_traceback = NULL;
|
|
1607
|
+
#endif
|
|
1608
|
+
#if CYTHON_USE_EXC_INFO_STACK
|
|
1609
|
+
gen->gi_exc_state.previous_item = NULL;
|
|
1610
|
+
#endif
|
|
1611
|
+
gen->gi_weakreflist = NULL;
|
|
1612
|
+
Py_XINCREF(qualname);
|
|
1613
|
+
gen->gi_qualname = qualname;
|
|
1614
|
+
Py_XINCREF(name);
|
|
1615
|
+
gen->gi_name = name;
|
|
1616
|
+
Py_XINCREF(module_name);
|
|
1617
|
+
gen->gi_modulename = module_name;
|
|
1618
|
+
Py_XINCREF(code);
|
|
1619
|
+
gen->gi_code = code;
|
|
1620
|
+
gen->gi_frame = NULL;
|
|
1621
|
+
|
|
1622
|
+
PyObject_GC_Track(gen);
|
|
1623
|
+
return gen;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
|
|
1627
|
+
static char __Pyx_Coroutine_test_and_set_is_running(__pyx_CoroutineObject *gen) {
|
|
1628
|
+
// Working on the basis that:
|
|
1629
|
+
// 1. is_running is the main thing needed to keep generators thread-safe. They can't be
|
|
1630
|
+
// run simultaneously from multiple threads so as long as we track this correctly
|
|
1631
|
+
// then all is good.
|
|
1632
|
+
// 2. They aren't *ultra* high performance, and so critical sections (locking) is appropriate
|
|
1633
|
+
// instead of atomics.
|
|
1634
|
+
char result;
|
|
1635
|
+
#if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API
|
|
1636
|
+
Py_BEGIN_CRITICAL_SECTION(gen);
|
|
1637
|
+
#endif
|
|
1638
|
+
result = gen->is_running;
|
|
1639
|
+
gen->is_running = 1;
|
|
1640
|
+
#if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API
|
|
1641
|
+
Py_END_CRITICAL_SECTION();
|
|
1642
|
+
#endif
|
|
1643
|
+
return result;
|
|
1644
|
+
}
|
|
1645
|
+
static void __Pyx_Coroutine_unset_is_running(__pyx_CoroutineObject *gen) {
|
|
1646
|
+
#if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API
|
|
1647
|
+
Py_BEGIN_CRITICAL_SECTION(gen);
|
|
1648
|
+
#endif
|
|
1649
|
+
assert(gen->is_running);
|
|
1650
|
+
gen->is_running = 0;
|
|
1651
|
+
#if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API
|
|
1652
|
+
Py_END_CRITICAL_SECTION();
|
|
1653
|
+
#endif
|
|
1654
|
+
}
|
|
1655
|
+
static char __Pyx_Coroutine_get_is_running(__pyx_CoroutineObject *gen) {
|
|
1656
|
+
char result;
|
|
1657
|
+
#if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API
|
|
1658
|
+
Py_BEGIN_CRITICAL_SECTION(gen);
|
|
1659
|
+
#endif
|
|
1660
|
+
result = gen->is_running;
|
|
1661
|
+
#if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API
|
|
1662
|
+
Py_END_CRITICAL_SECTION();
|
|
1663
|
+
#endif
|
|
1664
|
+
return result;
|
|
1665
|
+
}
|
|
1666
|
+
static PyObject *__Pyx_Coroutine_get_is_running_getter(PyObject *gen, void *closure) {
|
|
1667
|
+
CYTHON_UNUSED_VAR(closure);
|
|
1668
|
+
char result = __Pyx_Coroutine_get_is_running((__pyx_CoroutineObject*)gen);
|
|
1669
|
+
if (result) Py_RETURN_TRUE;
|
|
1670
|
+
else Py_RETURN_FALSE;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
#if __PYX_HAS_PY_AM_SEND == 2
|
|
1674
|
+
static void __Pyx_SetBackportTypeAmSend(PyTypeObject *type, __Pyx_PyAsyncMethodsStruct *static_amsend_methods, __Pyx_pyiter_sendfunc am_send) {
|
|
1675
|
+
Py_ssize_t ptr_offset = (char*)(type->tp_as_async) - (char*)type;
|
|
1676
|
+
if (ptr_offset < 0 || ptr_offset > type->tp_basicsize) {
|
|
1677
|
+
// The pointer isn't to somewhere within the type. This must be a cached type that's already been updated.
|
|
1678
|
+
return;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
// Copy the standard Python bits of it.
|
|
1682
|
+
memcpy((void*)static_amsend_methods, (void*)(type->tp_as_async), sizeof(*type->tp_as_async));
|
|
1683
|
+
static_amsend_methods->am_send = am_send;
|
|
1684
|
+
|
|
1685
|
+
// Replace.
|
|
1686
|
+
type->tp_as_async = __Pyx_SlotTpAsAsync(static_amsend_methods);
|
|
1687
|
+
}
|
|
1688
|
+
#endif
|
|
1689
|
+
|
|
1690
|
+
//////////////////// Coroutine ////////////////////
|
|
1691
|
+
//@requires: CoroutineBase
|
|
1692
|
+
//@requires: ExtensionTypes.c::CallTypeTraverse
|
|
1693
|
+
//@substitute: naming
|
|
1694
|
+
|
|
1695
|
+
static void __Pyx_CoroutineAwait_dealloc(PyObject *self) {
|
|
1696
|
+
PyObject_GC_UnTrack(self);
|
|
1697
|
+
Py_CLEAR(((__pyx_CoroutineAwaitObject*)self)->coroutine);
|
|
1698
|
+
__Pyx_PyHeapTypeObject_GC_Del(self);
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
static int __Pyx_CoroutineAwait_traverse(__pyx_CoroutineAwaitObject *self, visitproc visit, void *arg) {
|
|
1702
|
+
{
|
|
1703
|
+
int e = __Pyx_call_type_traverse((PyObject*)self, 1, visit, arg);
|
|
1704
|
+
if (e) return e;
|
|
1705
|
+
}
|
|
1706
|
+
Py_VISIT(self->coroutine);
|
|
1707
|
+
return 0;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
static int __Pyx_CoroutineAwait_clear(__pyx_CoroutineAwaitObject *self) {
|
|
1711
|
+
Py_CLEAR(self->coroutine);
|
|
1712
|
+
return 0;
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
static PyObject *__Pyx_CoroutineAwait_Next(__pyx_CoroutineAwaitObject *self) {
|
|
1716
|
+
return __Pyx_Generator_Next(self->coroutine);
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
static PyObject *__Pyx_CoroutineAwait_Send(__pyx_CoroutineAwaitObject *self, PyObject *value) {
|
|
1720
|
+
return __Pyx_Coroutine_Send(self->coroutine, value);
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
#if __PYX_HAS_PY_AM_SEND
|
|
1724
|
+
static __Pyx_PySendResult __Pyx_CoroutineAwait_AmSend(PyObject *self, PyObject *value, PyObject **retval) {
|
|
1725
|
+
return __Pyx_Coroutine_AmSend(((__pyx_CoroutineAwaitObject*)self)->coroutine, value, retval);
|
|
1726
|
+
}
|
|
1727
|
+
#endif
|
|
1728
|
+
|
|
1729
|
+
static PyObject *__Pyx_CoroutineAwait_Throw(__pyx_CoroutineAwaitObject *self, PyObject *args) {
|
|
1730
|
+
return __Pyx_Coroutine_Throw(self->coroutine, args);
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
static __Pyx_PySendResult __Pyx_CoroutineAwait_Close(__pyx_CoroutineAwaitObject *self) {
|
|
1734
|
+
PyObject *retval = NULL;
|
|
1735
|
+
__Pyx_PySendResult result = __Pyx_Coroutine_Close(self->coroutine, &retval);
|
|
1736
|
+
Py_XDECREF(retval);
|
|
1737
|
+
return result;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
static PyObject *__Pyx_CoroutineAwait_Close_Method(__pyx_CoroutineAwaitObject *self, PyObject *arg) {
|
|
1741
|
+
PyObject *retval = NULL;
|
|
1742
|
+
__Pyx_PySendResult result;
|
|
1743
|
+
CYTHON_UNUSED_VAR(arg);
|
|
1744
|
+
result = __Pyx_Coroutine_Close(self->coroutine, &retval);
|
|
1745
|
+
if (unlikely(result == PYGEN_ERROR))
|
|
1746
|
+
return NULL;
|
|
1747
|
+
Py_XDECREF(retval);
|
|
1748
|
+
Py_RETURN_NONE;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
static PyObject *__Pyx_CoroutineAwait_self(PyObject *self) {
|
|
1752
|
+
Py_INCREF(self);
|
|
1753
|
+
return self;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
1757
|
+
static PyObject *__Pyx_CoroutineAwait_no_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
|
|
1758
|
+
CYTHON_UNUSED_VAR(type);
|
|
1759
|
+
CYTHON_UNUSED_VAR(args);
|
|
1760
|
+
CYTHON_UNUSED_VAR(kwargs);
|
|
1761
|
+
PyErr_SetString(PyExc_TypeError, "cannot instantiate type, use 'await coroutine' instead");
|
|
1762
|
+
return NULL;
|
|
1763
|
+
}
|
|
1764
|
+
#endif
|
|
1765
|
+
|
|
1766
|
+
// In earlier versions of Python an object with no __dict__ and not __slots__ is assumed
|
|
1767
|
+
// to be pickleable by default. Coroutine-wrappers have significant state so shouldn't be.
|
|
1768
|
+
// Therefore provide a default implementation.
|
|
1769
|
+
// Something similar applies to heaptypes (i.e. with type_specs) with protocols 0 and 1
|
|
1770
|
+
// even in more recent versions.
|
|
1771
|
+
// We are applying this to all Python versions (hence the commented out version guard)
|
|
1772
|
+
// to make the behaviour explicit.
|
|
1773
|
+
// #if CYTHON_USE_TYPE_SPECS
|
|
1774
|
+
static PyObject *__Pyx_CoroutineAwait_reduce_ex(__pyx_CoroutineAwaitObject *self, PyObject *arg) {
|
|
1775
|
+
CYTHON_UNUSED_VAR(arg);
|
|
1776
|
+
|
|
1777
|
+
__Pyx_TypeName self_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE((PyObject*)self));
|
|
1778
|
+
PyErr_Format(PyExc_TypeError, "cannot pickle '" __Pyx_FMT_TYPENAME "' object",
|
|
1779
|
+
self_type_name);
|
|
1780
|
+
__Pyx_DECREF_TypeName(self_type_name);
|
|
1781
|
+
return NULL;
|
|
1782
|
+
}
|
|
1783
|
+
// #endif
|
|
1784
|
+
|
|
1785
|
+
static PyMethodDef __pyx_CoroutineAwait_methods[] = {
|
|
1786
|
+
{"send", (PyCFunction) __Pyx_CoroutineAwait_Send, METH_O,
|
|
1787
|
+
PyDoc_STR("send(arg) -> send 'arg' into coroutine,\nreturn next yielded value or raise StopIteration.")},
|
|
1788
|
+
{"throw", (PyCFunction) __Pyx_CoroutineAwait_Throw, METH_VARARGS,
|
|
1789
|
+
PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in coroutine,\nreturn next yielded value or raise StopIteration.")},
|
|
1790
|
+
{"close", (PyCFunction) __Pyx_CoroutineAwait_Close_Method, METH_NOARGS, PyDoc_STR("close() -> raise GeneratorExit inside coroutine.")},
|
|
1791
|
+
// only needed with type-specs, but included in all versions for clarity
|
|
1792
|
+
// #if CYTHON_USE_TYPE_SPECS
|
|
1793
|
+
{"__reduce_ex__", (PyCFunction) __Pyx_CoroutineAwait_reduce_ex, METH_O, 0},
|
|
1794
|
+
{"__reduce__", (PyCFunction) __Pyx_CoroutineAwait_reduce_ex, METH_NOARGS, 0},
|
|
1795
|
+
// #endif
|
|
1796
|
+
{0, 0, 0, 0}
|
|
1797
|
+
};
|
|
1798
|
+
|
|
1799
|
+
static PyType_Slot __pyx_CoroutineAwaitType_slots[] = {
|
|
1800
|
+
{Py_tp_dealloc, (void *)__Pyx_CoroutineAwait_dealloc},
|
|
1801
|
+
{Py_tp_traverse, (void *)__Pyx_CoroutineAwait_traverse},
|
|
1802
|
+
{Py_tp_clear, (void *)__Pyx_CoroutineAwait_clear},
|
|
1803
|
+
#if !CYTHON_COMPILING_IN_PYPY
|
|
1804
|
+
{Py_tp_new, (void *)__Pyx_CoroutineAwait_no_new},
|
|
1805
|
+
#endif
|
|
1806
|
+
{Py_tp_methods, (void *)__pyx_CoroutineAwait_methods},
|
|
1807
|
+
{Py_tp_iter, (void *)__Pyx_CoroutineAwait_self},
|
|
1808
|
+
{Py_tp_iternext, (void *)__Pyx_CoroutineAwait_Next},
|
|
1809
|
+
#if __PYX_HAS_PY_AM_SEND == 1
|
|
1810
|
+
{Py_am_send, (void *)__Pyx_CoroutineAwait_AmSend},
|
|
1811
|
+
#endif
|
|
1812
|
+
{0, 0},
|
|
1813
|
+
};
|
|
1814
|
+
|
|
1815
|
+
static PyType_Spec __pyx_CoroutineAwaitType_spec = {
|
|
1816
|
+
__PYX_TYPE_MODULE_PREFIX "coroutine_wrapper",
|
|
1817
|
+
sizeof(__pyx_CoroutineAwaitObject),
|
|
1818
|
+
0,
|
|
1819
|
+
#if PY_VERSION_HEX >= 0x030A0000
|
|
1820
|
+
Py_TPFLAGS_IMMUTABLETYPE |
|
|
1821
|
+
#endif
|
|
1822
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | __Pyx_TPFLAGS_HAVE_AM_SEND, /*tp_flags*/
|
|
1823
|
+
__pyx_CoroutineAwaitType_slots
|
|
1824
|
+
};
|
|
1825
|
+
|
|
1826
|
+
#if __PYX_HAS_PY_AM_SEND == 2 // backport
|
|
1827
|
+
static __Pyx_PyAsyncMethodsStruct __pyx_CoroutineAwait_as_async;
|
|
1828
|
+
#endif
|
|
1829
|
+
|
|
1830
|
+
static CYTHON_INLINE PyObject *__Pyx__Coroutine_await(PyObject *coroutine) {
|
|
1831
|
+
__pyx_CoroutineAwaitObject *await = PyObject_GC_New(__pyx_CoroutineAwaitObject, CGLOBAL(__pyx_CoroutineAwaitType));
|
|
1832
|
+
if (unlikely(!await)) return NULL;
|
|
1833
|
+
Py_INCREF(coroutine);
|
|
1834
|
+
await->coroutine = coroutine;
|
|
1835
|
+
PyObject_GC_Track(await);
|
|
1836
|
+
return (PyObject*)await;
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
static PyObject *__Pyx_Coroutine_await(PyObject *coroutine) {
|
|
1840
|
+
if (unlikely(!coroutine || !__Pyx_Coroutine_Check(coroutine))) {
|
|
1841
|
+
PyErr_SetString(PyExc_TypeError, "invalid input, expected coroutine");
|
|
1842
|
+
return NULL;
|
|
1843
|
+
}
|
|
1844
|
+
return __Pyx__Coroutine_await(coroutine);
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
static PyMethodDef __pyx_Coroutine_methods[] = {
|
|
1848
|
+
{"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O,
|
|
1849
|
+
PyDoc_STR("send(arg) -> send 'arg' into coroutine,\nreturn next iterated value or raise StopIteration.")},
|
|
1850
|
+
{"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS,
|
|
1851
|
+
PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in coroutine,\nreturn next iterated value or raise StopIteration.")},
|
|
1852
|
+
{"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS, PyDoc_STR("close() -> raise GeneratorExit inside coroutine.")},
|
|
1853
|
+
{0, 0, 0, 0}
|
|
1854
|
+
};
|
|
1855
|
+
|
|
1856
|
+
static PyMemberDef __pyx_Coroutine_memberlist[] = {
|
|
1857
|
+
{"cr_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
|
|
1858
|
+
PyDoc_STR("object being awaited, or None")},
|
|
1859
|
+
{"cr_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL},
|
|
1860
|
+
{"__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0},
|
|
1861
|
+
{"__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0},
|
|
1862
|
+
{0, 0, 0, 0, 0}
|
|
1863
|
+
};
|
|
1864
|
+
|
|
1865
|
+
static PyGetSetDef __pyx_Coroutine_getsets[] = {
|
|
1866
|
+
{"__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name,
|
|
1867
|
+
PyDoc_STR("name of the coroutine"), 0},
|
|
1868
|
+
{"__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname,
|
|
1869
|
+
PyDoc_STR("qualified name of the coroutine"), 0},
|
|
1870
|
+
{"cr_frame", (getter)__Pyx_Coroutine_get_frame, NULL,
|
|
1871
|
+
PyDoc_STR("Frame of the coroutine"), 0},
|
|
1872
|
+
// getter rather than member for thread safety.
|
|
1873
|
+
{"cr_running", __Pyx_Coroutine_get_is_running_getter, NULL, NULL, NULL},
|
|
1874
|
+
{0, 0, 0, 0, 0}
|
|
1875
|
+
};
|
|
1876
|
+
|
|
1877
|
+
static PyType_Slot __pyx_CoroutineType_slots[] = {
|
|
1878
|
+
{Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc},
|
|
1879
|
+
{Py_am_await, (void *)&__Pyx_Coroutine_await},
|
|
1880
|
+
{Py_tp_traverse, (void *)__Pyx_Coroutine_traverse},
|
|
1881
|
+
{Py_tp_methods, (void *)__pyx_Coroutine_methods},
|
|
1882
|
+
{Py_tp_members, (void *)__pyx_Coroutine_memberlist},
|
|
1883
|
+
{Py_tp_getset, (void *)__pyx_Coroutine_getsets},
|
|
1884
|
+
{Py_tp_getattro, (void *) PyObject_GenericGetAttr},
|
|
1885
|
+
#if CYTHON_USE_TP_FINALIZE
|
|
1886
|
+
{Py_tp_finalize, (void *)__Pyx_Coroutine_del},
|
|
1887
|
+
#endif
|
|
1888
|
+
#if __PYX_HAS_PY_AM_SEND == 1
|
|
1889
|
+
{Py_am_send, (void *)__Pyx_Coroutine_AmSend},
|
|
1890
|
+
#endif
|
|
1891
|
+
{0, 0},
|
|
1892
|
+
};
|
|
1893
|
+
|
|
1894
|
+
static PyType_Spec __pyx_CoroutineType_spec = {
|
|
1895
|
+
__PYX_TYPE_MODULE_PREFIX "coroutine",
|
|
1896
|
+
sizeof(__pyx_CoroutineObject),
|
|
1897
|
+
0,
|
|
1898
|
+
#if PY_VERSION_HEX >= 0x030A0000
|
|
1899
|
+
Py_TPFLAGS_IMMUTABLETYPE |
|
|
1900
|
+
#endif
|
|
1901
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE | __Pyx_TPFLAGS_HAVE_AM_SEND, /*tp_flags*/
|
|
1902
|
+
__pyx_CoroutineType_slots
|
|
1903
|
+
};
|
|
1904
|
+
|
|
1905
|
+
#if __PYX_HAS_PY_AM_SEND == 2
|
|
1906
|
+
static __Pyx_PyAsyncMethodsStruct __pyx_Coroutine_as_async;
|
|
1907
|
+
#endif
|
|
1908
|
+
|
|
1909
|
+
static int __pyx_Coroutine_init(PyObject *module) {
|
|
1910
|
+
$modulestatetype_cname *mstate;
|
|
1911
|
+
CYTHON_MAYBE_UNUSED_VAR(module);
|
|
1912
|
+
// on Windows, C-API functions can't be used in slots statically
|
|
1913
|
+
mstate = __Pyx_PyModule_GetState(module);
|
|
1914
|
+
mstate->__pyx_CoroutineType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CoroutineType_spec, NULL);
|
|
1915
|
+
if (unlikely(!mstate->__pyx_CoroutineType))
|
|
1916
|
+
return -1;
|
|
1917
|
+
#if __PYX_HAS_PY_AM_SEND == 2
|
|
1918
|
+
__Pyx_SetBackportTypeAmSend(mstate->__pyx_CoroutineType, &__pyx_Coroutine_as_async, &__Pyx_Coroutine_AmSend);
|
|
1919
|
+
#endif
|
|
1920
|
+
|
|
1921
|
+
#ifdef __Pyx_IterableCoroutine_USED
|
|
1922
|
+
if (unlikely(__pyx_IterableCoroutine_init(module) == -1))
|
|
1923
|
+
return -1;
|
|
1924
|
+
#endif
|
|
1925
|
+
|
|
1926
|
+
mstate->__pyx_CoroutineAwaitType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CoroutineAwaitType_spec, NULL);
|
|
1927
|
+
if (unlikely(!mstate->__pyx_CoroutineAwaitType))
|
|
1928
|
+
return -1;
|
|
1929
|
+
#if __PYX_HAS_PY_AM_SEND == 2
|
|
1930
|
+
__Pyx_SetBackportTypeAmSend(mstate->__pyx_CoroutineAwaitType, &__pyx_CoroutineAwait_as_async, &__Pyx_CoroutineAwait_AmSend);
|
|
1931
|
+
#endif
|
|
1932
|
+
return 0;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
//////////////////// IterableCoroutine.proto ////////////////////
|
|
1937
|
+
|
|
1938
|
+
#define __Pyx_IterableCoroutine_USED
|
|
1939
|
+
|
|
1940
|
+
#undef __Pyx_Coroutine_Check
|
|
1941
|
+
#define __Pyx_Coroutine_Check(obj) (__Pyx_Coroutine_CheckExact(obj) || __Pyx_IS_TYPE(obj, CGLOBAL(__pyx_IterableCoroutineType)))
|
|
1942
|
+
|
|
1943
|
+
#define __Pyx_IterableCoroutine_New(body, code, closure, name, qualname, module_name) \
|
|
1944
|
+
__Pyx__Coroutine_New(CGLOBAL(__pyx_IterableCoroutineType), body, code, closure, name, qualname, module_name)
|
|
1945
|
+
|
|
1946
|
+
static int __pyx_IterableCoroutine_init(PyObject *module);/*proto*/
|
|
1947
|
+
|
|
1948
|
+
|
|
1949
|
+
//////////////////// IterableCoroutine ////////////////////
|
|
1950
|
+
//@requires: Coroutine
|
|
1951
|
+
//@requires: CommonStructures.c::FetchCommonType
|
|
1952
|
+
//@substitute: naming
|
|
1953
|
+
|
|
1954
|
+
static PyType_Slot __pyx_IterableCoroutineType_slots[] = {
|
|
1955
|
+
{Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc},
|
|
1956
|
+
{Py_am_await, (void *)&__Pyx_Coroutine_await},
|
|
1957
|
+
{Py_tp_traverse, (void *)__Pyx_Coroutine_traverse},
|
|
1958
|
+
{Py_tp_iter, (void *)__Pyx_Coroutine_await},
|
|
1959
|
+
{Py_tp_iternext, (void *)__Pyx_Generator_Next},
|
|
1960
|
+
{Py_tp_methods, (void *)__pyx_Coroutine_methods},
|
|
1961
|
+
{Py_tp_members, (void *)__pyx_Coroutine_memberlist},
|
|
1962
|
+
{Py_tp_getset, (void *)__pyx_Coroutine_getsets},
|
|
1963
|
+
{Py_tp_getattro, (void *) PyObject_GenericGetAttr},
|
|
1964
|
+
#if CYTHON_USE_TP_FINALIZE
|
|
1965
|
+
{Py_tp_finalize, (void *)__Pyx_Coroutine_del},
|
|
1966
|
+
#endif
|
|
1967
|
+
#if __PYX_HAS_PY_AM_SEND == 1
|
|
1968
|
+
{Py_am_send, (void *)__Pyx_Coroutine_AmSend},
|
|
1969
|
+
#endif
|
|
1970
|
+
{0, 0},
|
|
1971
|
+
};
|
|
1972
|
+
|
|
1973
|
+
static PyType_Spec __pyx_IterableCoroutineType_spec = {
|
|
1974
|
+
__PYX_TYPE_MODULE_PREFIX "iterable_coroutine",
|
|
1975
|
+
sizeof(__pyx_CoroutineObject),
|
|
1976
|
+
0,
|
|
1977
|
+
#if PY_VERSION_HEX >= 0x030A0000
|
|
1978
|
+
Py_TPFLAGS_IMMUTABLETYPE |
|
|
1979
|
+
#endif
|
|
1980
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE | __Pyx_TPFLAGS_HAVE_AM_SEND, /*tp_flags*/
|
|
1981
|
+
__pyx_IterableCoroutineType_slots
|
|
1982
|
+
};
|
|
1983
|
+
|
|
1984
|
+
|
|
1985
|
+
static int __pyx_IterableCoroutine_init(PyObject *module) {
|
|
1986
|
+
$modulestatetype_cname *mstate = __Pyx_PyModule_GetState(module);
|
|
1987
|
+
mstate->__pyx_IterableCoroutineType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_IterableCoroutineType_spec, NULL);
|
|
1988
|
+
if (unlikely(!mstate->__pyx_IterableCoroutineType))
|
|
1989
|
+
return -1;
|
|
1990
|
+
#if __PYX_HAS_PY_AM_SEND == 2
|
|
1991
|
+
__Pyx_SetBackportTypeAmSend(mstate->__pyx_IterableCoroutineType, &__pyx_Coroutine_as_async, &__Pyx_Coroutine_AmSend);
|
|
1992
|
+
#endif
|
|
1993
|
+
return 0;
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
//////////////////// Generator ////////////////////
|
|
1998
|
+
//@requires: CoroutineBase
|
|
1999
|
+
//@substitute: naming
|
|
2000
|
+
|
|
2001
|
+
static PyMethodDef __pyx_Generator_methods[] = {
|
|
2002
|
+
{"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O,
|
|
2003
|
+
PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")},
|
|
2004
|
+
{"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS,
|
|
2005
|
+
PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")},
|
|
2006
|
+
{"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS,
|
|
2007
|
+
PyDoc_STR("close() -> raise GeneratorExit inside generator.")},
|
|
2008
|
+
{0, 0, 0, 0}
|
|
2009
|
+
};
|
|
2010
|
+
|
|
2011
|
+
static PyMemberDef __pyx_Generator_memberlist[] = {
|
|
2012
|
+
{"gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
|
|
2013
|
+
PyDoc_STR("object being iterated by 'yield from', or None")},
|
|
2014
|
+
{"gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL},
|
|
2015
|
+
{"__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0},
|
|
2016
|
+
{"__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0},
|
|
2017
|
+
{0, 0, 0, 0, 0}
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
static PyGetSetDef __pyx_Generator_getsets[] = {
|
|
2021
|
+
{"__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name,
|
|
2022
|
+
PyDoc_STR("name of the generator"), 0},
|
|
2023
|
+
{"__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname,
|
|
2024
|
+
PyDoc_STR("qualified name of the generator"), 0},
|
|
2025
|
+
{"gi_frame", (getter)__Pyx_Coroutine_get_frame, NULL,
|
|
2026
|
+
PyDoc_STR("Frame of the generator"), 0},
|
|
2027
|
+
{"gi_running", __Pyx_Coroutine_get_is_running_getter, NULL, NULL, NULL},
|
|
2028
|
+
{0, 0, 0, 0, 0}
|
|
2029
|
+
};
|
|
2030
|
+
|
|
2031
|
+
static PyType_Slot __pyx_GeneratorType_slots[] = {
|
|
2032
|
+
{Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc},
|
|
2033
|
+
{Py_tp_traverse, (void *)__Pyx_Coroutine_traverse},
|
|
2034
|
+
{Py_tp_iter, (void *)PyObject_SelfIter},
|
|
2035
|
+
{Py_tp_iternext, (void *)__Pyx_Generator_Next},
|
|
2036
|
+
{Py_tp_methods, (void *)__pyx_Generator_methods},
|
|
2037
|
+
{Py_tp_members, (void *)__pyx_Generator_memberlist},
|
|
2038
|
+
{Py_tp_getset, (void *)__pyx_Generator_getsets},
|
|
2039
|
+
{Py_tp_getattro, (void *) PyObject_GenericGetAttr},
|
|
2040
|
+
#if CYTHON_USE_TP_FINALIZE
|
|
2041
|
+
{Py_tp_finalize, (void *)__Pyx_Coroutine_del},
|
|
2042
|
+
#endif
|
|
2043
|
+
#if __PYX_HAS_PY_AM_SEND == 1
|
|
2044
|
+
{Py_am_send, (void *)__Pyx_Coroutine_AmSend},
|
|
2045
|
+
#endif
|
|
2046
|
+
{0, 0},
|
|
2047
|
+
};
|
|
2048
|
+
|
|
2049
|
+
static PyType_Spec __pyx_GeneratorType_spec = {
|
|
2050
|
+
__PYX_TYPE_MODULE_PREFIX "generator",
|
|
2051
|
+
sizeof(__pyx_CoroutineObject),
|
|
2052
|
+
0,
|
|
2053
|
+
#if PY_VERSION_HEX >= 0x030A0000
|
|
2054
|
+
Py_TPFLAGS_IMMUTABLETYPE |
|
|
2055
|
+
#endif
|
|
2056
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE | __Pyx_TPFLAGS_HAVE_AM_SEND, /*tp_flags*/
|
|
2057
|
+
__pyx_GeneratorType_slots
|
|
2058
|
+
};
|
|
2059
|
+
|
|
2060
|
+
#if __PYX_HAS_PY_AM_SEND == 2
|
|
2061
|
+
static __Pyx_PyAsyncMethodsStruct __pyx_Generator_as_async;
|
|
2062
|
+
#endif
|
|
2063
|
+
|
|
2064
|
+
static int __pyx_Generator_init(PyObject *module) {
|
|
2065
|
+
$modulestatetype_cname *mstate = __Pyx_PyModule_GetState(module);
|
|
2066
|
+
mstate->__pyx_GeneratorType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_GeneratorType_spec, NULL);
|
|
2067
|
+
if (unlikely(!mstate->__pyx_GeneratorType)) {
|
|
2068
|
+
return -1;
|
|
2069
|
+
}
|
|
2070
|
+
#if __PYX_HAS_PY_AM_SEND == 2
|
|
2071
|
+
__Pyx_SetBackportTypeAmSend(mstate->__pyx_GeneratorType, &__pyx_Generator_as_async, &__Pyx_Coroutine_AmSend);
|
|
2072
|
+
#endif
|
|
2073
|
+
return 0;
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
static PyObject *__Pyx_Generator_GetInlinedResult(PyObject *self) {
|
|
2077
|
+
__pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
|
|
2078
|
+
PyObject *retval = NULL;
|
|
2079
|
+
if (unlikely(__Pyx_Coroutine_test_and_set_is_running(gen))) {
|
|
2080
|
+
return __Pyx_Coroutine_AlreadyRunningError(gen);
|
|
2081
|
+
}
|
|
2082
|
+
__Pyx_PySendResult result = __Pyx_Coroutine_SendEx(gen, Py_None, &retval, 0);
|
|
2083
|
+
__Pyx_Coroutine_unset_is_running(gen);
|
|
2084
|
+
(void) result;
|
|
2085
|
+
assert (result == PYGEN_RETURN || result == PYGEN_ERROR);
|
|
2086
|
+
assert ((result == PYGEN_RETURN && retval != NULL) || (result == PYGEN_ERROR && retval == NULL));
|
|
2087
|
+
return retval;
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
|
|
2091
|
+
/////////////// ReturnWithStopIteration.proto ///////////////
|
|
2092
|
+
|
|
2093
|
+
static CYTHON_INLINE void __Pyx_ReturnWithStopIteration(PyObject* value, int async, int iternext); /*proto*/
|
|
2094
|
+
|
|
2095
|
+
/////////////// ReturnWithStopIteration ///////////////
|
|
2096
|
+
//@requires: Exceptions.c::PyErrFetchRestore
|
|
2097
|
+
//@requires: Exceptions.c::PyThreadStateGet
|
|
2098
|
+
//@requires: ObjectHandling.c::PyObjectCallOneArg
|
|
2099
|
+
//@substitute: naming
|
|
2100
|
+
|
|
2101
|
+
// 1) Instantiating an exception just to pass back a value is costly.
|
|
2102
|
+
// 2) CPython 3.12 cannot separate exception type and value
|
|
2103
|
+
// 3) Passing a tuple as value into PyErr_SetObject() passes its items on as arguments.
|
|
2104
|
+
// 4) Passing an exception as value will interpret it as an exception on unpacking and raise it (or unpack its value).
|
|
2105
|
+
// 5) If there is currently an exception being handled, we need to chain it.
|
|
2106
|
+
// 6) CPython < 3.14a1 does not implement vectorcalls for exceptions.
|
|
2107
|
+
|
|
2108
|
+
static void __Pyx__ReturnWithStopIteration(PyObject* value, int async); /*proto*/
|
|
2109
|
+
|
|
2110
|
+
static CYTHON_INLINE void __Pyx_ReturnWithStopIteration(PyObject* value, int async, int iternext) {
|
|
2111
|
+
if (value == Py_None) {
|
|
2112
|
+
if (async || !iternext)
|
|
2113
|
+
PyErr_SetNone(async ? PyExc_StopAsyncIteration : PyExc_StopIteration);
|
|
2114
|
+
// for regular iternext, then we don't have to return StopIteration and can just return NULL
|
|
2115
|
+
return;
|
|
2116
|
+
}
|
|
2117
|
+
__Pyx__ReturnWithStopIteration(value, async);
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
static void __Pyx__ReturnWithStopIteration(PyObject* value, int async) {
|
|
2121
|
+
#if CYTHON_COMPILING_IN_CPYTHON
|
|
2122
|
+
__Pyx_PyThreadState_declare
|
|
2123
|
+
#endif
|
|
2124
|
+
PyObject *exc;
|
|
2125
|
+
PyObject *exc_type = async ? PyExc_StopAsyncIteration : PyExc_StopIteration;
|
|
2126
|
+
#if CYTHON_COMPILING_IN_CPYTHON
|
|
2127
|
+
if ((PY_VERSION_HEX >= 0x030C00A6) || unlikely(PyTuple_Check(value) || PyExceptionInstance_Check(value))) {
|
|
2128
|
+
if ((PY_VERSION_HEX >= 0x030e00A1)) {
|
|
2129
|
+
exc = __Pyx_PyObject_CallOneArg(exc_type, value);
|
|
2130
|
+
} else {
|
|
2131
|
+
// Before Py3.14a1, CPython doesn't implement vectorcall for exceptions.
|
|
2132
|
+
PyObject *args_tuple = PyTuple_New(1);
|
|
2133
|
+
if (unlikely(!args_tuple)) return;
|
|
2134
|
+
Py_INCREF(value);
|
|
2135
|
+
PyTuple_SET_ITEM(args_tuple, 0, value);
|
|
2136
|
+
exc = PyObject_Call(exc_type, args_tuple, NULL);
|
|
2137
|
+
Py_DECREF(args_tuple);
|
|
2138
|
+
}
|
|
2139
|
+
if (unlikely(!exc)) return;
|
|
2140
|
+
} else {
|
|
2141
|
+
// it's safe to avoid instantiating the exception
|
|
2142
|
+
Py_INCREF(value);
|
|
2143
|
+
exc = value;
|
|
2144
|
+
}
|
|
2145
|
+
#if CYTHON_FAST_THREAD_STATE
|
|
2146
|
+
__Pyx_PyThreadState_assign
|
|
2147
|
+
#if CYTHON_USE_EXC_INFO_STACK
|
|
2148
|
+
if (!$local_tstate_cname->exc_info->exc_value)
|
|
2149
|
+
#else
|
|
2150
|
+
if (!$local_tstate_cname->exc_type)
|
|
2151
|
+
#endif
|
|
2152
|
+
{
|
|
2153
|
+
// no chaining needed => avoid the overhead in PyErr_SetObject()
|
|
2154
|
+
Py_INCREF(exc_type);
|
|
2155
|
+
__Pyx_ErrRestore(exc_type, exc, NULL);
|
|
2156
|
+
return;
|
|
2157
|
+
}
|
|
2158
|
+
#endif
|
|
2159
|
+
#else
|
|
2160
|
+
exc = __Pyx_PyObject_CallOneArg(exc_type, value);
|
|
2161
|
+
if (unlikely(!exc)) return;
|
|
2162
|
+
#endif
|
|
2163
|
+
PyErr_SetObject(exc_type, exc);
|
|
2164
|
+
Py_DECREF(exc);
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
//////////////////// Coro_CheckExact.proto ////////////////
|
|
2168
|
+
|
|
2169
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
2170
|
+
static int __Pyx_PyCoro_CheckExact(PyObject *o); /* proto */
|
|
2171
|
+
#else
|
|
2172
|
+
#define __Pyx_PyCoro_CheckExact PyCoro_CheckExact
|
|
2173
|
+
#endif
|
|
2174
|
+
|
|
2175
|
+
/////////////////// Coro_CheckExact.module_state_decls //////////
|
|
2176
|
+
|
|
2177
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
2178
|
+
PyObject *__Pyx_CachedCoroType;
|
|
2179
|
+
#endif
|
|
2180
|
+
|
|
2181
|
+
////////////////// Coro_CheckExact.init ////////////////
|
|
2182
|
+
|
|
2183
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
2184
|
+
{
|
|
2185
|
+
PyObject *typesModule=NULL;
|
|
2186
|
+
typesModule = PyImport_ImportModule("types");
|
|
2187
|
+
if (typesModule) {
|
|
2188
|
+
CGLOBAL(__Pyx_CachedCoroType) = PyObject_GetAttrString(typesModule, "CoroutineType");
|
|
2189
|
+
Py_DECREF(typesModule);
|
|
2190
|
+
}
|
|
2191
|
+
} // error handling follows
|
|
2192
|
+
#endif
|
|
2193
|
+
|
|
2194
|
+
/////////////// Coro_CheckExact.cleanup ////////////////
|
|
2195
|
+
|
|
2196
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
2197
|
+
Py_CLEAR(CGLOBAL(__Pyx_CachedCoroType));
|
|
2198
|
+
#endif
|
|
2199
|
+
|
|
2200
|
+
/////////////////// Coro_CheckExact /////////////////////
|
|
2201
|
+
|
|
2202
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
2203
|
+
static int __Pyx_PyCoro_CheckExact(PyObject *o) {
|
|
2204
|
+
return (PyObject*)Py_TYPE(o) == CGLOBAL(__Pyx_CachedCoroType);
|
|
2205
|
+
}
|
|
2206
|
+
#endif
|