Cython 3.3.0__cp315-cp315-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Cython/Build/BuildExecutable.py +156 -0
- Cython/Build/Cache.py +199 -0
- Cython/Build/Cythonize.py +349 -0
- Cython/Build/Dependencies.py +1281 -0
- Cython/Build/Distutils.py +1 -0
- Cython/Build/Inline.py +467 -0
- Cython/Build/IpythonMagic.py +559 -0
- Cython/Build/SharedModule.py +165 -0
- Cython/Build/Tests/TestCyCache.py +195 -0
- Cython/Build/Tests/TestCythonizeArgsParser.py +480 -0
- Cython/Build/Tests/TestDependencies.py +133 -0
- Cython/Build/Tests/TestInline.py +177 -0
- Cython/Build/Tests/TestIpythonMagic.py +303 -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 +11 -0
- Cython/CodeWriter.py +825 -0
- Cython/Compiler/AnalysedTreeTransforms.py +97 -0
- Cython/Compiler/Annotate.py +328 -0
- Cython/Compiler/AutoDocTransforms.py +320 -0
- Cython/Compiler/Buffer.py +679 -0
- Cython/Compiler/Builtin.py +1102 -0
- Cython/Compiler/CmdLine.py +373 -0
- Cython/Compiler/Code.cp315-win_amd64.pyd +0 -0
- Cython/Compiler/Code.pxd +154 -0
- Cython/Compiler/Code.py +3760 -0
- Cython/Compiler/CodeGeneration.py +33 -0
- Cython/Compiler/CythonScope.py +208 -0
- Cython/Compiler/Dataclass.py +890 -0
- Cython/Compiler/DebugFlags.py +24 -0
- Cython/Compiler/Errors.py +310 -0
- Cython/Compiler/ExprNodes.py +16273 -0
- Cython/Compiler/FlowControl.cp315-win_amd64.pyd +0 -0
- Cython/Compiler/FlowControl.pxd +112 -0
- Cython/Compiler/FlowControl.py +1573 -0
- Cython/Compiler/FusedNode.cp315-win_amd64.pyd +0 -0
- Cython/Compiler/FusedNode.py +978 -0
- Cython/Compiler/Future.py +16 -0
- Cython/Compiler/Interpreter.py +57 -0
- Cython/Compiler/Lexicon.py +422 -0
- Cython/Compiler/LineTable.cp315-win_amd64.pyd +0 -0
- Cython/Compiler/LineTable.py +114 -0
- Cython/Compiler/Main.py +856 -0
- Cython/Compiler/MatchCaseNodes.py +2200 -0
- Cython/Compiler/MemoryView.py +930 -0
- Cython/Compiler/ModuleNode.py +4548 -0
- Cython/Compiler/Naming.py +370 -0
- Cython/Compiler/Nodes.py +11304 -0
- Cython/Compiler/Optimize.py +5564 -0
- Cython/Compiler/Options.py +840 -0
- Cython/Compiler/ParseTreeTransforms.pxd +80 -0
- Cython/Compiler/ParseTreeTransforms.py +4808 -0
- Cython/Compiler/Parsing.cp315-win_amd64.pyd +0 -0
- Cython/Compiler/Parsing.pxd +9 -0
- Cython/Compiler/Parsing.py +4809 -0
- Cython/Compiler/Pipeline.py +439 -0
- Cython/Compiler/PyrexTypes.py +6588 -0
- Cython/Compiler/Pythran.py +232 -0
- Cython/Compiler/Scanning.cp315-win_amd64.pyd +0 -0
- Cython/Compiler/Scanning.pxd +70 -0
- Cython/Compiler/Scanning.py +720 -0
- Cython/Compiler/StringEncoding.cp315-win_amd64.pyd +0 -0
- Cython/Compiler/StringEncoding.py +354 -0
- Cython/Compiler/Symtab.py +3121 -0
- Cython/Compiler/Tests/TestBuffer.py +105 -0
- Cython/Compiler/Tests/TestBuiltin.py +196 -0
- Cython/Compiler/Tests/TestCmdLine.py +652 -0
- Cython/Compiler/Tests/TestCode.py +145 -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 +132 -0
- Cython/Compiler/Tests/TestSignatureMatching.py +73 -0
- Cython/Compiler/Tests/TestStringEncoding.py +20 -0
- Cython/Compiler/Tests/TestTreeFragment.py +63 -0
- Cython/Compiler/Tests/TestTreePath.py +103 -0
- Cython/Compiler/Tests/TestTypes.py +119 -0
- Cython/Compiler/Tests/TestUtilityLoad.py +112 -0
- Cython/Compiler/Tests/TestVisitor.py +119 -0
- Cython/Compiler/Tests/Utils.py +36 -0
- Cython/Compiler/Tests/__init__.py +1 -0
- Cython/Compiler/TreeFragment.py +279 -0
- Cython/Compiler/TreePath.py +303 -0
- Cython/Compiler/TypeInference.py +611 -0
- Cython/Compiler/TypeSlots.py +1329 -0
- Cython/Compiler/UFuncs.py +317 -0
- Cython/Compiler/UtilNodes.py +389 -0
- Cython/Compiler/UtilityCode.py +354 -0
- Cython/Compiler/Version.py +8 -0
- Cython/Compiler/Visitor.cp315-win_amd64.pyd +0 -0
- Cython/Compiler/Visitor.pxd +52 -0
- Cython/Compiler/Visitor.py +914 -0
- Cython/Compiler/__init__.py +1 -0
- Cython/Coverage.py +448 -0
- Cython/Debugger/Cygdb.py +214 -0
- Cython/Debugger/DebugWriter.py +82 -0
- Cython/Debugger/Tests/TestLibCython.py +280 -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 +580 -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 +143 -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 +152 -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 +268 -0
- Cython/Includes/cpython/exc.pxd +263 -0
- Cython/Includes/cpython/fileobject.pxd +57 -0
- Cython/Includes/cpython/float.pxd +56 -0
- Cython/Includes/cpython/frozendict.pxd +37 -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 +144 -0
- Cython/Includes/cpython/long.pxd +180 -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 +430 -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 +141 -0
- Cython/Includes/cpython/sentinel.pxd +17 -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 +146 -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 +234 -0
- Cython/Includes/libc/time.pxd +52 -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/condition_variable.pxd +322 -0
- Cython/Includes/libcpp/deque.pxd +165 -0
- Cython/Includes/libcpp/exception.pxd +216 -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 +387 -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 +43 -0
- Cython/Includes/libcpp/set.pxd +228 -0
- Cython/Includes/libcpp/shared_mutex.pxd +96 -0
- Cython/Includes/libcpp/span.pxd +87 -0
- Cython/Includes/libcpp/stack.pxd +11 -0
- Cython/Includes/libcpp/stop_token.pxd +117 -0
- Cython/Includes/libcpp/string.pxd +355 -0
- Cython/Includes/libcpp/string_view.pxd +183 -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/numpy/math.pxd +150 -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/LZSS.cp315-win_amd64.pyd +0 -0
- Cython/LZSS.py +184 -0
- Cython/Plex/Actions.cp315-win_amd64.pyd +0 -0
- Cython/Plex/Actions.pxd +24 -0
- Cython/Plex/Actions.py +119 -0
- Cython/Plex/DFA.cp315-win_amd64.pyd +0 -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.cp315-win_amd64.pyd +0 -0
- Cython/Plex/Machines.pxd +36 -0
- Cython/Plex/Machines.py +238 -0
- Cython/Plex/Regexps.py +535 -0
- Cython/Plex/Scanners.cp315-win_amd64.pyd +0 -0
- Cython/Plex/Scanners.pxd +45 -0
- Cython/Plex/Scanners.py +328 -0
- Cython/Plex/Transitions.cp315-win_amd64.pyd +0 -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.cp315-win_amd64.pyd +0 -0
- Cython/Runtime/refnanny.pyx +237 -0
- Cython/Shadow.py +1174 -0
- Cython/StringIOTree.cp315-win_amd64.pyd +0 -0
- Cython/StringIOTree.py +169 -0
- Cython/Tempita/__init__.py +4 -0
- Cython/Tempita/_looper.py +154 -0
- Cython/Tempita/_tempita.cp315-win_amd64.pyd +0 -0
- Cython/Tempita/_tempita.py +1087 -0
- Cython/TestUtils.py +472 -0
- Cython/Tests/TestCodeWriter.py +128 -0
- Cython/Tests/TestCythonUtils.py +202 -0
- Cython/Tests/TestJediTyper.py +223 -0
- Cython/Tests/TestShadow.py +125 -0
- Cython/Tests/TestStringIOTree.py +68 -0
- Cython/Tests/TestTestUtils.py +89 -0
- Cython/Tests/__init__.py +1 -0
- Cython/Tests/xmlrunner.py +390 -0
- Cython/Utility/AsyncGen.c +1152 -0
- Cython/Utility/Buffer.c +866 -0
- Cython/Utility/BufferFormatFromTypeInfo.pxd +2 -0
- Cython/Utility/Builtins.c +1068 -0
- Cython/Utility/CConvert.pyx +153 -0
- Cython/Utility/CMath.c +104 -0
- Cython/Utility/CommonStructures.c +244 -0
- Cython/Utility/Complex.c +378 -0
- Cython/Utility/Coroutine.c +2344 -0
- Cython/Utility/CpdefEnums.pyx +119 -0
- Cython/Utility/CppConvert.pyx +282 -0
- Cython/Utility/CppSupport.cpp +151 -0
- Cython/Utility/CythonFunction.c +2185 -0
- Cython/Utility/Dataclasses.c +101 -0
- Cython/Utility/Embed.c +129 -0
- Cython/Utility/Exceptions.c +1331 -0
- Cython/Utility/Exceptions_Cy.pyx +109 -0
- Cython/Utility/ExtensionTypes.c +1199 -0
- Cython/Utility/FunctionArguments.c +1052 -0
- Cython/Utility/FusedFunction.pyx +44 -0
- Cython/Utility/ImportExport.c +972 -0
- Cython/Utility/MatchCase.c +981 -0
- Cython/Utility/MatchCase_Cy.pyx +12 -0
- Cython/Utility/MemoryView.pxd +108 -0
- Cython/Utility/MemoryView.pyx +1499 -0
- Cython/Utility/MemoryView_C.c +1056 -0
- Cython/Utility/ModuleSetupCode.c +3319 -0
- Cython/Utility/NumpyImportArray.c +46 -0
- Cython/Utility/ObjectHandling.c +3404 -0
- Cython/Utility/Optimize.c +2564 -0
- Cython/Utility/Overflow.c +378 -0
- Cython/Utility/Profile.c +736 -0
- Cython/Utility/StringTools.c +1534 -0
- Cython/Utility/Synchronization.c +438 -0
- Cython/Utility/TString.c +369 -0
- Cython/Utility/TestCyUtilityLoader.pyx +8 -0
- Cython/Utility/TestCythonScope.pyx +75 -0
- Cython/Utility/TestUtilityLoader.c +12 -0
- Cython/Utility/TypeConversion.c +1588 -0
- Cython/Utility/UFuncs.pyx +50 -0
- Cython/Utility/UFuncs_C.c +89 -0
- Cython/Utility/__init__.py +28 -0
- Cython/Utility/arrayarray.h +172 -0
- Cython/Utils.cp315-win_amd64.pyd +0 -0
- Cython/Utils.py +680 -0
- Cython/__init__.py +12 -0
- Cython/_shared.cp315-win_amd64.pyd +0 -0
- Cython/py.typed +0 -0
- cython-3.3.0.dist-info/METADATA +555 -0
- cython-3.3.0.dist-info/RECORD +339 -0
- cython-3.3.0.dist-info/WHEEL +5 -0
- cython-3.3.0.dist-info/entry_points.txt +4 -0
- cython-3.3.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,981 @@
|
|
|
1
|
+
///////////////////////////// ABCCheck //////////////////////////////
|
|
2
|
+
//@requires: Builtins.c::PyFrozenDict
|
|
3
|
+
|
|
4
|
+
#if PY_VERSION_HEX < 0x030A0000 || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY
|
|
5
|
+
static CYTHON_INLINE int __Pyx_MatchCase_IsExactSequence(PyObject *o) {
|
|
6
|
+
// Is one of the small list of builtin types known to be a sequence.
|
|
7
|
+
if (PyList_CheckExact(o) || PyTuple_CheckExact(o) ||
|
|
8
|
+
Py_IS_TYPE(o, &PyRange_Type) || Py_IS_TYPE(o, &PyMemoryView_Type)) {
|
|
9
|
+
// Use exact type match for these checks. In in the event of inheritance we need to make sure
|
|
10
|
+
// that it isn't a mapping too
|
|
11
|
+
return 1;
|
|
12
|
+
}
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static CYTHON_INLINE int __Pyx_MatchCase_IsExactMapping(PyObject *o) {
|
|
17
|
+
// dict and frozendict are the only regularly used mapping type.
|
|
18
|
+
// "types.MappingProxyType" also exists but is correctly covered by
|
|
19
|
+
// the isinstance(o, Mapping) check.
|
|
20
|
+
return __Pyx_PyAnyDict_CheckExact(o);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static int __Pyx_MatchCase_IsExactNeitherSequenceNorMapping(PyObject *o) {
|
|
24
|
+
if (PyByteArray_Check(o) || PyBytes_Check(o) || PyUnicode_Check(o)) {
|
|
25
|
+
// These types are deliberately excluded from the sequence test
|
|
26
|
+
// even though they look like sequences for most other purposes.
|
|
27
|
+
// Leaving them as inexact checks since they do pass
|
|
28
|
+
// "isinstance(o, collections.abc.Sequence)" so it's very hard to
|
|
29
|
+
// reason about their subclasses.
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
// No-exhaustive list of other common builtin types as an optimization.
|
|
33
|
+
if (o == Py_None || PyLong_CheckExact(o) || PyFloat_CheckExact(o) ||
|
|
34
|
+
Py_TYPE(o) == &PyBool_Type || Py_TYPE(o) == &PySlice_Type ||
|
|
35
|
+
PyAnySet_CheckExact(o) || PyComplex_CheckExact(o)) {
|
|
36
|
+
return 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// sequence_mapping_temp: For Python 3.10 testing sequences and mappings are
|
|
43
|
+
// really quick and this is ignored. For lower versions of Python they're
|
|
44
|
+
// slow, especially in the "fail" case.
|
|
45
|
+
// Therefore, we store an int temp to avoid duplicating tests.
|
|
46
|
+
// The bits of it in order are:
|
|
47
|
+
// 0. definitely a sequence
|
|
48
|
+
// 1. definitely a mapping
|
|
49
|
+
// - note that both of the above can be true when
|
|
50
|
+
// the type is registered with both abc types (not via inheritance)
|
|
51
|
+
// and in this case we return true for both IsSequence or IsMapping
|
|
52
|
+
// (which seems like the best handling of an ambiguous situation)
|
|
53
|
+
// 2. definitely not a sequence
|
|
54
|
+
// 3. definitely not a mapping
|
|
55
|
+
|
|
56
|
+
#define __PYX_DEFINITELY_SEQUENCE_FLAG 1U
|
|
57
|
+
#define __PYX_DEFINITELY_MAPPING_FLAG (1U<<1)
|
|
58
|
+
#define __PYX_DEFINITELY_NOT_SEQUENCE_FLAG (1U<<2)
|
|
59
|
+
#define __PYX_DEFINITELY_NOT_MAPPING_FLAG (1U<<3)
|
|
60
|
+
#define __PYX_SEQUENCE_MAPPING_ERROR (1U<<4) // only used by the ABCCheck function
|
|
61
|
+
|
|
62
|
+
static int __Pyx_MatchCase_InitAbcType(PyObject *abc_module, PyObject **abc_type, PyObject *name) {
|
|
63
|
+
if (*abc_type) return 0;
|
|
64
|
+
*abc_type = PyObject_GetAttr(abc_module, name);
|
|
65
|
+
return *abc_type ? 0 : -1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The result is defined using the specification for sequence_mapping_temp
|
|
69
|
+
// (detailed in "is_sequence").
|
|
70
|
+
static unsigned int __Pyx_MatchCase_ABCCheck(PyObject *o, int sequence_first, int definitely_not_sequence, int definitely_not_mapping) {
|
|
71
|
+
// In Python 3.10+, objects can have their sequence bit set or their mapping bit set
|
|
72
|
+
// but not both. Practically, this translates to "which type is registered first".
|
|
73
|
+
// In Python < 3.10 we can only determine this if they're direct bases (by looking
|
|
74
|
+
// at the MRO order). If they're registered manually then we can't tell.
|
|
75
|
+
|
|
76
|
+
PyObject *abc_module=NULL, *sequence_type=NULL, *mapping_type=NULL;
|
|
77
|
+
PyObject *mro;
|
|
78
|
+
int sequence_result=0, mapping_result=0;
|
|
79
|
+
unsigned int result = 0;
|
|
80
|
+
|
|
81
|
+
if (sequence_first && definitely_not_sequence) {
|
|
82
|
+
return __PYX_DEFINITELY_NOT_SEQUENCE_FLAG;
|
|
83
|
+
}
|
|
84
|
+
if (!sequence_first && definitely_not_mapping) {
|
|
85
|
+
return __PYX_DEFINITELY_NOT_MAPPING_FLAG;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
abc_module = PyImport_ImportModule("collections.abc");
|
|
89
|
+
if (!abc_module) {
|
|
90
|
+
return __PYX_SEQUENCE_MAPPING_ERROR;
|
|
91
|
+
}
|
|
92
|
+
if (sequence_first) {
|
|
93
|
+
if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &sequence_type, PYIDENT("Sequence")) == -1)) {
|
|
94
|
+
result = __PYX_SEQUENCE_MAPPING_ERROR;
|
|
95
|
+
goto end;
|
|
96
|
+
}
|
|
97
|
+
sequence_result = PyObject_IsInstance(o, sequence_type);
|
|
98
|
+
if (sequence_result <= 0) {
|
|
99
|
+
result = sequence_result < 0 ? __PYX_SEQUENCE_MAPPING_ERROR : __PYX_DEFINITELY_NOT_SEQUENCE_FLAG;
|
|
100
|
+
goto end;
|
|
101
|
+
}
|
|
102
|
+
// else sequence_result==1 but wait to see what mapping is
|
|
103
|
+
}
|
|
104
|
+
if (!definitely_not_mapping) {
|
|
105
|
+
if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &mapping_type, PYIDENT("Mapping")) == -1)) {
|
|
106
|
+
result = __PYX_SEQUENCE_MAPPING_ERROR;
|
|
107
|
+
goto end;
|
|
108
|
+
}
|
|
109
|
+
mapping_result = PyObject_IsInstance(o, mapping_type);
|
|
110
|
+
if (unlikely(mapping_result < 0)) {
|
|
111
|
+
result = __PYX_SEQUENCE_MAPPING_ERROR;
|
|
112
|
+
goto end;
|
|
113
|
+
} else if (mapping_result == 0 && !sequence_first) {
|
|
114
|
+
result = __PYX_DEFINITELY_NOT_MAPPING_FLAG;
|
|
115
|
+
goto end;
|
|
116
|
+
} // else mapping_result == 1
|
|
117
|
+
}
|
|
118
|
+
if (!sequence_first && !definitely_not_sequence) {
|
|
119
|
+
if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &sequence_type, PYIDENT("Sequence")) == -1)) {
|
|
120
|
+
result = __PYX_SEQUENCE_MAPPING_ERROR;
|
|
121
|
+
goto end;
|
|
122
|
+
}
|
|
123
|
+
sequence_result = PyObject_IsInstance(o, sequence_type);
|
|
124
|
+
if (unlikely(sequence_result < 0)) {
|
|
125
|
+
result = __PYX_SEQUENCE_MAPPING_ERROR;
|
|
126
|
+
goto end;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
result |= (sequence_result ? __PYX_DEFINITELY_SEQUENCE_FLAG : __PYX_DEFINITELY_NOT_SEQUENCE_FLAG);
|
|
130
|
+
result |= (mapping_result ? __PYX_DEFINITELY_MAPPING_FLAG : __PYX_DEFINITELY_NOT_MAPPING_FLAG);
|
|
131
|
+
if (result != (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_MAPPING_FLAG)) {
|
|
132
|
+
goto end;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// It's an instance of both types. Look up the MRO order.
|
|
136
|
+
// In event of failure treat it as "could be either"
|
|
137
|
+
mro = PyObject_GetAttrString((PyObject*)Py_TYPE(o), "__mro__");
|
|
138
|
+
Py_ssize_t i, mro_size;
|
|
139
|
+
if (!mro) {
|
|
140
|
+
PyErr_Clear();
|
|
141
|
+
goto end;
|
|
142
|
+
}
|
|
143
|
+
if (!PyTuple_Check(mro)) {
|
|
144
|
+
Py_DECREF(mro);
|
|
145
|
+
goto end;
|
|
146
|
+
}
|
|
147
|
+
mro_size = __Pyx_PyTuple_GET_SIZE(mro);
|
|
148
|
+
#if !CYTHON_ASSUME_SAFE_SIZE
|
|
149
|
+
if (unlikely(mro_size == -1)) {
|
|
150
|
+
goto loop_error;
|
|
151
|
+
}
|
|
152
|
+
#endif
|
|
153
|
+
for (i=1; i < mro_size; ++i) {
|
|
154
|
+
int is_subclass_sequence, is_subclass_mapping;
|
|
155
|
+
PyObject *mro_item = __Pyx_PyTuple_GET_ITEM(mro, i);
|
|
156
|
+
#if !CYTHON_ASSUME_SAFE_MACROS
|
|
157
|
+
if (unlikely(!mro_item)) goto loop_error;
|
|
158
|
+
#endif
|
|
159
|
+
is_subclass_sequence = PyObject_IsSubclass(mro_item, sequence_type);
|
|
160
|
+
if (is_subclass_sequence < 0) goto loop_error;
|
|
161
|
+
is_subclass_mapping = PyObject_IsSubclass(mro_item, mapping_type);
|
|
162
|
+
if (is_subclass_mapping < 0) goto loop_error;
|
|
163
|
+
if (is_subclass_sequence && !is_subclass_mapping) {
|
|
164
|
+
result = (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
|
|
165
|
+
break;
|
|
166
|
+
} else if (is_subclass_mapping && !is_subclass_sequence) {
|
|
167
|
+
result = (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_MAPPING_FLAG);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// If we get to the end of the loop without breaking then neither type is in
|
|
172
|
+
// the MRO, so they've both been registered manually. We don't know which was
|
|
173
|
+
// registered first so accept the object as either as a compromise.
|
|
174
|
+
loop_error_recovery:
|
|
175
|
+
Py_DECREF(mro);
|
|
176
|
+
|
|
177
|
+
end:
|
|
178
|
+
Py_XDECREF(abc_module);
|
|
179
|
+
Py_XDECREF(sequence_type);
|
|
180
|
+
Py_XDECREF(mapping_type);
|
|
181
|
+
return result;
|
|
182
|
+
|
|
183
|
+
loop_error:
|
|
184
|
+
PyErr_Clear();
|
|
185
|
+
goto loop_error_recovery;
|
|
186
|
+
}
|
|
187
|
+
#endif
|
|
188
|
+
|
|
189
|
+
///////////////////////////// IsSequence.proto //////////////////////
|
|
190
|
+
|
|
191
|
+
static int __Pyx_MatchCase_IsSequence(PyObject *o, unsigned int *sequence_mapping_temp); /* proto */
|
|
192
|
+
|
|
193
|
+
//////////////////////////// IsSequence /////////////////////////
|
|
194
|
+
//@requires: ABCCheck
|
|
195
|
+
|
|
196
|
+
static int __Pyx_MatchCase_IsSequence(PyObject *o, unsigned int *sequence_mapping_temp) {
|
|
197
|
+
#if PY_VERSION_HEX >= 0x030A0000 && !(CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY)
|
|
198
|
+
CYTHON_UNUSED_VAR(sequence_mapping_temp);
|
|
199
|
+
return __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_SEQUENCE);
|
|
200
|
+
#else
|
|
201
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
202
|
+
// In the Limited API we have runtime access to Py_TPFLAGS_SEQUENCE
|
|
203
|
+
// by looking it up on module init so it's still worth attempting
|
|
204
|
+
// the fast path.
|
|
205
|
+
if (__Pyx_Runtime_TPFLAGS_SEQUENCE) {
|
|
206
|
+
return __Pyx_PyType_HasFeature(Py_TYPE(o), __Pyx_Runtime_TPFLAGS_SEQUENCE);
|
|
207
|
+
}
|
|
208
|
+
#elif defined(Py_TPFLAGS_SEQUENCE)
|
|
209
|
+
// Elsewhere *we* define Py_TPFLAGS_SEQUENCE but that doesn't necessarily
|
|
210
|
+
// mean other types use it, so only success is meaningful.
|
|
211
|
+
if (__Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_SEQUENCE)) {
|
|
212
|
+
return 1;
|
|
213
|
+
}
|
|
214
|
+
#endif
|
|
215
|
+
// Py_TPFLAGS_SEQUENCE doesn't exit.
|
|
216
|
+
PyObject *o_module_name;
|
|
217
|
+
unsigned int abc_result, dummy=0;
|
|
218
|
+
|
|
219
|
+
if (sequence_mapping_temp) {
|
|
220
|
+
// maybe we already know the answer
|
|
221
|
+
if (*sequence_mapping_temp & __PYX_DEFINITELY_SEQUENCE_FLAG) {
|
|
222
|
+
return 1;
|
|
223
|
+
}
|
|
224
|
+
if (*sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG) {
|
|
225
|
+
return 0;
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
// Probably quicker to just assign it and not check from here.
|
|
229
|
+
sequence_mapping_temp = &dummy;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Start by checking a known list of types.
|
|
233
|
+
if (__Pyx_MatchCase_IsExactSequence(o)) {
|
|
234
|
+
*sequence_mapping_temp |= (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
|
|
235
|
+
return 1;
|
|
236
|
+
}
|
|
237
|
+
if (__Pyx_MatchCase_IsExactMapping(o)) {
|
|
238
|
+
*sequence_mapping_temp |= (__PYX_DEFINITELY_MAPPING_FLAG | __PYX_DEFINITELY_NOT_SEQUENCE_FLAG);
|
|
239
|
+
return 0;
|
|
240
|
+
}
|
|
241
|
+
if (__Pyx_MatchCase_IsExactNeitherSequenceNorMapping(o)) {
|
|
242
|
+
*sequence_mapping_temp |= (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
|
|
243
|
+
return 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
abc_result = __Pyx_MatchCase_ABCCheck(
|
|
247
|
+
o, 1,
|
|
248
|
+
*sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG,
|
|
249
|
+
*sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG
|
|
250
|
+
);
|
|
251
|
+
if (abc_result & __PYX_SEQUENCE_MAPPING_ERROR) {
|
|
252
|
+
return -1;
|
|
253
|
+
}
|
|
254
|
+
*sequence_mapping_temp = abc_result;
|
|
255
|
+
if (*sequence_mapping_temp & __PYX_DEFINITELY_SEQUENCE_FLAG) {
|
|
256
|
+
return 1;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// array.array is a more complicated check (and unfortunately isn't covered by
|
|
260
|
+
// collections.abc.Sequence on Python <3.10).
|
|
261
|
+
// Do the test by checking the module name, and then importing/testing the class.
|
|
262
|
+
// It also doesn't give perfect results for classes that inherit from both array.array
|
|
263
|
+
// and a mapping.
|
|
264
|
+
#if !CYTHON_COMPILING_IN_LIMITED_API || __PYX_LIMITED_VERSION_HEX < 0x030A0000
|
|
265
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
266
|
+
if (__Pyx_get_runtime_version() < 0x030A0000)
|
|
267
|
+
#endif
|
|
268
|
+
{
|
|
269
|
+
o_module_name = PyObject_GetAttrString((PyObject*)Py_TYPE(o), "__module__");
|
|
270
|
+
if (!o_module_name) {
|
|
271
|
+
return -1;
|
|
272
|
+
}
|
|
273
|
+
if (PyUnicode_Check(o_module_name) && PyUnicode_CompareWithASCIIString(o_module_name, "array") == 0)
|
|
274
|
+
{
|
|
275
|
+
int is_array;
|
|
276
|
+
PyObject *array_module, *array_object;
|
|
277
|
+
Py_DECREF(o_module_name);
|
|
278
|
+
array_module = PyImport_ImportModule("array");
|
|
279
|
+
if (!array_module) {
|
|
280
|
+
PyErr_Clear();
|
|
281
|
+
return 0; // treat these tests as "soft" and don't cause an exception
|
|
282
|
+
}
|
|
283
|
+
array_object = PyObject_GetAttrString(array_module, "array");
|
|
284
|
+
Py_DECREF(array_module);
|
|
285
|
+
if (!array_object) {
|
|
286
|
+
PyErr_Clear();
|
|
287
|
+
return 0;
|
|
288
|
+
}
|
|
289
|
+
is_array = PyObject_IsInstance(o, array_object);
|
|
290
|
+
Py_DECREF(array_object);
|
|
291
|
+
if (is_array) {
|
|
292
|
+
*sequence_mapping_temp |= __PYX_DEFINITELY_SEQUENCE_FLAG;
|
|
293
|
+
return 1;
|
|
294
|
+
}
|
|
295
|
+
PyErr_Clear();
|
|
296
|
+
} else {
|
|
297
|
+
Py_DECREF(o_module_name);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
#else
|
|
301
|
+
CYTHON_UNUSED_VAR(o_module_name);
|
|
302
|
+
#endif
|
|
303
|
+
*sequence_mapping_temp |= __PYX_DEFINITELY_NOT_SEQUENCE_FLAG;
|
|
304
|
+
return 0;
|
|
305
|
+
#endif
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
////////////////////// OtherSequenceSliceToList.proto //////////////////////
|
|
309
|
+
|
|
310
|
+
static PyObject *__Pyx_MatchCase_OtherSequenceSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end); /* proto */
|
|
311
|
+
|
|
312
|
+
////////////////////// OtherSequenceSliceToList //////////////////////////
|
|
313
|
+
|
|
314
|
+
// This is substantially based off ceval unpack_iterable.
|
|
315
|
+
// It's also pretty similar to itertools.islice.
|
|
316
|
+
// Indices must be positive - there's no wraparound or boundschecking.
|
|
317
|
+
|
|
318
|
+
static PyObject *__Pyx_MatchCase_OtherSequenceSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end) {
|
|
319
|
+
Py_ssize_t total = end-start;
|
|
320
|
+
Py_ssize_t i;
|
|
321
|
+
PyObject *list;
|
|
322
|
+
ssizeargfunc slot;
|
|
323
|
+
|
|
324
|
+
list = PyList_New(total);
|
|
325
|
+
if (!list) {
|
|
326
|
+
return NULL;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
slot = __Pyx_PyObject_TryGetSubSlot(x, tp_as_sequence, sq_item, ssizeargfunc);
|
|
330
|
+
if (!slot) {
|
|
331
|
+
#if !CYTHON_COMPILING_IN_LIMITED_API && !defined(PySequence_ITEM)
|
|
332
|
+
// PyPy (and maybe others?) implements PySequence_ITEM as a function. In this case.
|
|
333
|
+
// it's slightly more efficient than using PySequence_GetItem since it skips negative indices.
|
|
334
|
+
slot = PySequence_ITEM;
|
|
335
|
+
#else
|
|
336
|
+
slot = PySequence_GetItem;
|
|
337
|
+
#endif
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
for (i=start; i<end; ++i) {
|
|
341
|
+
PyObject *obj = slot(x, i);
|
|
342
|
+
if (unlikely(!obj) || unlikely(__Pyx_PyList_SET_ITEM(list, i-start, obj) == -1)) {
|
|
343
|
+
Py_DECREF(list);
|
|
344
|
+
return NULL;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return list;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
////////////////////// TupleSliceToList.proto //////////////////////
|
|
351
|
+
|
|
352
|
+
static PyObject *__Pyx_MatchCase_TupleSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end); /* proto */
|
|
353
|
+
|
|
354
|
+
////////////////////// TupleSliceToList //////////////////////////
|
|
355
|
+
//@requires: OtherSequenceSliceToList
|
|
356
|
+
//@requires: ObjectHandling.c::ListFromArray
|
|
357
|
+
|
|
358
|
+
// Indices must be positive - there's no wraparound or boundschecking.
|
|
359
|
+
|
|
360
|
+
static PyObject *__Pyx_MatchCase_TupleSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end) {
|
|
361
|
+
#if !CYTHON_COMPILING_IN_CPYTHON
|
|
362
|
+
return __Pyx_MatchCase_OtherSequenceSliceToList(x, start, end);
|
|
363
|
+
#else
|
|
364
|
+
PyObject **array;
|
|
365
|
+
|
|
366
|
+
(void)__Pyx_MatchCase_OtherSequenceSliceToList; // clear unused warning
|
|
367
|
+
|
|
368
|
+
array = &PyTuple_GET_ITEM(x, 0);
|
|
369
|
+
return __Pyx_PyList_FromArray(array+start, end-start);
|
|
370
|
+
#endif
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
////////////////////////// UnknownTypeSliceToList.proto //////////////////////
|
|
374
|
+
|
|
375
|
+
static PyObject *__Pyx_MatchCase_UnknownTypeSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end); /* proto */
|
|
376
|
+
|
|
377
|
+
////////////////////////// UnknownTypeSliceToList.proto //////////////////////
|
|
378
|
+
//@requires: TupleSliceToList
|
|
379
|
+
//@requires: OtherSequenceSliceToList
|
|
380
|
+
|
|
381
|
+
static PyObject *__Pyx_MatchCase_UnknownTypeSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end) {
|
|
382
|
+
if (PyList_CheckExact(x)) {
|
|
383
|
+
return PyList_GetSlice(x, start, end);
|
|
384
|
+
}
|
|
385
|
+
#if !CYTHON_COMPILING_IN_CPYTHON
|
|
386
|
+
// since __Pyx_MatchCase_TupleToList only does anything special in CPython, skip the check otherwise
|
|
387
|
+
if (PyTuple_CheckExact(x)) {
|
|
388
|
+
return __Pyx_MatchCase_TupleSliceToList(x, start, end);
|
|
389
|
+
}
|
|
390
|
+
#else
|
|
391
|
+
(void)__Pyx_MatchCase_TupleSliceToList;
|
|
392
|
+
#endif
|
|
393
|
+
return __Pyx_MatchCase_OtherSequenceSliceToList(x, start, end);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
///////////////////////////// IsMapping.proto //////////////////////
|
|
397
|
+
|
|
398
|
+
static int __Pyx_MatchCase_IsMapping(PyObject *o, unsigned int *sequence_mapping_temp); /* proto */
|
|
399
|
+
|
|
400
|
+
//////////////////////////// IsMapping /////////////////////////
|
|
401
|
+
//@requires: ABCCheck
|
|
402
|
+
|
|
403
|
+
static int __Pyx_MatchCase_IsMapping(PyObject *o, unsigned int *sequence_mapping_temp) {
|
|
404
|
+
#if PY_VERSION_HEX >= 0x030A0000 && !(CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY)
|
|
405
|
+
CYTHON_UNUSED_VAR(sequence_mapping_temp);
|
|
406
|
+
return __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_MAPPING);
|
|
407
|
+
#else
|
|
408
|
+
#if CYTHON_COMPILING_IN_LIMITED_API
|
|
409
|
+
// In the Limited API we have runtime access to Py_TPFLAGS_MAPPING
|
|
410
|
+
// by looking it up on module init so it's still worth attempting
|
|
411
|
+
// the fast path.
|
|
412
|
+
if (__Pyx_Runtime_TPFLAGS_MAPPING) {
|
|
413
|
+
return __Pyx_PyType_HasFeature(Py_TYPE(o), __Pyx_Runtime_TPFLAGS_MAPPING);
|
|
414
|
+
}
|
|
415
|
+
#elif defined(Py_TPFLAGS_MAPPING)
|
|
416
|
+
// Elsewhere *we* define Py_TPFLAGS_SEQUENCE but that doesn't necessarily
|
|
417
|
+
// mean other types use it, so only success is meaningful.
|
|
418
|
+
if (__Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_MAPPING)) {
|
|
419
|
+
return 1;
|
|
420
|
+
}
|
|
421
|
+
#endif
|
|
422
|
+
unsigned int abc_result, dummy=0;
|
|
423
|
+
if (sequence_mapping_temp) {
|
|
424
|
+
// do we already know the answer?
|
|
425
|
+
if (*sequence_mapping_temp & __PYX_DEFINITELY_MAPPING_FLAG) {
|
|
426
|
+
return 1;
|
|
427
|
+
} else if (*sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG) {
|
|
428
|
+
return 0;
|
|
429
|
+
}
|
|
430
|
+
} else {
|
|
431
|
+
sequence_mapping_temp = &dummy; // just so we can assign freely without checking
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (__Pyx_MatchCase_IsExactMapping(o)) {
|
|
435
|
+
*sequence_mapping_temp |= (__PYX_DEFINITELY_MAPPING_FLAG | __PYX_DEFINITELY_NOT_SEQUENCE_FLAG);
|
|
436
|
+
return 1;
|
|
437
|
+
}
|
|
438
|
+
if (__Pyx_MatchCase_IsExactSequence(o)) {
|
|
439
|
+
*sequence_mapping_temp |= (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
|
|
440
|
+
return 0;
|
|
441
|
+
}
|
|
442
|
+
if (__Pyx_MatchCase_IsExactNeitherSequenceNorMapping(o)) {
|
|
443
|
+
*sequence_mapping_temp |= (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG);
|
|
444
|
+
return 0;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// otherwise check against collections.abc.Mapping
|
|
448
|
+
abc_result = __Pyx_MatchCase_ABCCheck(
|
|
449
|
+
o, 0,
|
|
450
|
+
*sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG,
|
|
451
|
+
*sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG
|
|
452
|
+
);
|
|
453
|
+
if (abc_result & __PYX_SEQUENCE_MAPPING_ERROR) {
|
|
454
|
+
return -1;
|
|
455
|
+
}
|
|
456
|
+
*sequence_mapping_temp = abc_result;
|
|
457
|
+
return *sequence_mapping_temp & __PYX_DEFINITELY_MAPPING_FLAG;
|
|
458
|
+
#endif
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
//////////////////////// MappingKeyCheck.proto /////////////////////////
|
|
462
|
+
|
|
463
|
+
static int __Pyx_MatchCase_CheckMappingDuplicateKeys(PyObject *keys[], Py_ssize_t nFixedKeys, Py_ssize_t nKeys);
|
|
464
|
+
|
|
465
|
+
//////////////////////// MappingKeyCheck ///////////////////////////////
|
|
466
|
+
|
|
467
|
+
static int __Pyx_MatchCase_CheckMappingDuplicateKeys(PyObject *keys[], Py_ssize_t nFixedKeys, Py_ssize_t nKeys) {
|
|
468
|
+
// Inputs are arrays, and typically fairly small. It may be more efficient to
|
|
469
|
+
// loop over the array than create a set.
|
|
470
|
+
|
|
471
|
+
// The CPython implementation (match_keys in ceval.c) does this concurrently with
|
|
472
|
+
// taking the keys out of the dictionary. I'm choosing to do it separately since the
|
|
473
|
+
// majority of the time the keys will be known at compile-time so Cython can skip
|
|
474
|
+
// this step completely.
|
|
475
|
+
// The step is also skipped when there's only a single key.
|
|
476
|
+
|
|
477
|
+
PyObject *var_keys_set;
|
|
478
|
+
PyObject *key;
|
|
479
|
+
Py_ssize_t n;
|
|
480
|
+
int contains;
|
|
481
|
+
|
|
482
|
+
var_keys_set = PySet_New(NULL);
|
|
483
|
+
if (!var_keys_set) return -1;
|
|
484
|
+
|
|
485
|
+
for (n=nFixedKeys; n < nKeys; ++n) {
|
|
486
|
+
key = keys[n];
|
|
487
|
+
contains = PySet_Contains(var_keys_set, key);
|
|
488
|
+
if (contains < 0) {
|
|
489
|
+
goto bad;
|
|
490
|
+
} else if (contains == 1) {
|
|
491
|
+
goto raise_error;
|
|
492
|
+
} else {
|
|
493
|
+
if (PySet_Add(var_keys_set, key)) {
|
|
494
|
+
goto bad;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
for (n=0; n < nFixedKeys; ++n) {
|
|
499
|
+
key = keys[n];
|
|
500
|
+
contains = PySet_Contains(var_keys_set, key);
|
|
501
|
+
if (contains < 0) {
|
|
502
|
+
goto bad;
|
|
503
|
+
} else if (contains == 1) {
|
|
504
|
+
goto raise_error;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
Py_DECREF(var_keys_set);
|
|
508
|
+
return 0;
|
|
509
|
+
|
|
510
|
+
raise_error:
|
|
511
|
+
PyErr_Format(PyExc_ValueError,
|
|
512
|
+
"mapping pattern checks duplicate key (%R)", key);
|
|
513
|
+
bad:
|
|
514
|
+
Py_DECREF(var_keys_set);
|
|
515
|
+
return -1;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/////////////////////////// ExtractExactDict.proto ////////////////
|
|
519
|
+
|
|
520
|
+
// The subjects array is a list of PyObject** to subjects to be filled. They may be NULL
|
|
521
|
+
// in which case they're ignored.
|
|
522
|
+
//
|
|
523
|
+
// This is a specialized version for when we have an exact (frozen)dict (which is likely to be pretty common)
|
|
524
|
+
|
|
525
|
+
#if CYTHON_REFNANNY
|
|
526
|
+
#define __Pyx_MatchCase_Mapping_ExtractDict(...) __Pyx__MatchCase_Mapping_ExtractDict(__pyx_refnanny, __VA_ARGS__)
|
|
527
|
+
#else
|
|
528
|
+
#define __Pyx_MatchCase_Mapping_ExtractDict(...) __Pyx__MatchCase_Mapping_ExtractDict(NULL, __VA_ARGS__)
|
|
529
|
+
#endif
|
|
530
|
+
static CYTHON_INLINE int __Pyx__MatchCase_Mapping_ExtractDict(void *__pyx_refnanny, PyObject *dict, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]); /* proto */
|
|
531
|
+
|
|
532
|
+
/////////////////////////// ExtractExactDict ////////////////
|
|
533
|
+
|
|
534
|
+
static CYTHON_INLINE int __Pyx__MatchCase_Mapping_ExtractDict(void *__pyx_refnanny, PyObject *dict, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]) {
|
|
535
|
+
#if !CYTHON_REFNANNY
|
|
536
|
+
CYTHON_UNUSED_VAR(__pyx_refnanny);
|
|
537
|
+
#endif
|
|
538
|
+
|
|
539
|
+
Py_ssize_t i;
|
|
540
|
+
Py_ssize_t size;
|
|
541
|
+
size = PyDict_Size(dict);
|
|
542
|
+
if (size < nKeys) {
|
|
543
|
+
return size == -1 ? -1: 0;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
for (i=0; i<nKeys; ++i) {
|
|
547
|
+
PyObject *key = keys[i];
|
|
548
|
+
PyObject **subject = subjects[i];
|
|
549
|
+
if (!subject) {
|
|
550
|
+
int contains = PyDict_Contains(dict, key);
|
|
551
|
+
if (contains <= 0) {
|
|
552
|
+
return contains; // any subjects that were already set will be cleaned up externally
|
|
553
|
+
}
|
|
554
|
+
} else {
|
|
555
|
+
PyObject *value;
|
|
556
|
+
int getref_result = __Pyx_PyDict_GetItemRef(dict, key, &value);
|
|
557
|
+
if (getref_result != 1) {
|
|
558
|
+
return getref_result; // any subjects that were already set will be cleaned up externally
|
|
559
|
+
}
|
|
560
|
+
__Pyx_GOTREF(value);
|
|
561
|
+
__Pyx_XDECREF_SET(*subject, value);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return 1; // success
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
///////////////////////// ExtractNonDict.proto ////////////////////////////////
|
|
568
|
+
|
|
569
|
+
// The subjects array is a list of PyObject** to subjects to be filled. They may be NULL
|
|
570
|
+
// in which case they're ignored.
|
|
571
|
+
//
|
|
572
|
+
// This is a specialized version for the rarer case when the type isn't an exact dict.
|
|
573
|
+
|
|
574
|
+
#if CYTHON_REFNANNY
|
|
575
|
+
#define __Pyx_MatchCase_Mapping_ExtractNonDict(...) __Pyx__MatchCase_Mapping_ExtractNonDict(__pyx_refnanny, __VA_ARGS__)
|
|
576
|
+
#else
|
|
577
|
+
#define __Pyx_MatchCase_Mapping_ExtractNonDict(...) __Pyx__MatchCase_Mapping_ExtractNonDict(NULL, __VA_ARGS__)
|
|
578
|
+
#endif
|
|
579
|
+
static CYTHON_INLINE int __Pyx__MatchCase_Mapping_ExtractNonDict(void *__pyx_refnanny, PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]); /* proto */
|
|
580
|
+
|
|
581
|
+
///////////////////////// ExtractNonDict //////////////////////////////////////
|
|
582
|
+
//@requires: ObjectHandling.c::PyObjectCall2Args
|
|
583
|
+
|
|
584
|
+
// largely adapted from match_keys in CPython ceval.c
|
|
585
|
+
|
|
586
|
+
static int __Pyx__MatchCase_Mapping_ExtractNonDict(void *__pyx_refnanny, PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]) {
|
|
587
|
+
PyObject *dummy=NULL, *get=NULL;
|
|
588
|
+
Py_ssize_t i, size;
|
|
589
|
+
int result = 0;
|
|
590
|
+
#if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL
|
|
591
|
+
PyObject *get_method = NULL, *get_self = NULL;
|
|
592
|
+
#endif
|
|
593
|
+
|
|
594
|
+
#if !CYTHON_REFNANNY
|
|
595
|
+
CYTHON_UNUSED_VAR(__pyx_refnanny);
|
|
596
|
+
#endif
|
|
597
|
+
|
|
598
|
+
// Length check is undocumented but does take place in CPython and is probably worthwhile.
|
|
599
|
+
size = PyObject_Length(mapping);
|
|
600
|
+
if (size < nKeys) {
|
|
601
|
+
return size == -1 ? -1: 0;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
dummy = PyObject_CallObject((PyObject *)&PyBaseObject_Type, NULL);
|
|
605
|
+
if (!dummy) {
|
|
606
|
+
return -1;
|
|
607
|
+
}
|
|
608
|
+
get = PyObject_GetAttr(mapping, PYIDENT("get"));
|
|
609
|
+
if (!get) {
|
|
610
|
+
result = -1;
|
|
611
|
+
goto end;
|
|
612
|
+
}
|
|
613
|
+
#if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL
|
|
614
|
+
if (likely(PyMethod_Check(get))) {
|
|
615
|
+
// both of these are borrowed
|
|
616
|
+
get_method = PyMethod_GET_FUNCTION(get);
|
|
617
|
+
get_self = PyMethod_GET_SELF(get);
|
|
618
|
+
}
|
|
619
|
+
#endif
|
|
620
|
+
|
|
621
|
+
for (i=0; i<nKeys; ++i) {
|
|
622
|
+
PyObject **subject;
|
|
623
|
+
PyObject *value = NULL;
|
|
624
|
+
PyObject *key = keys[i];
|
|
625
|
+
|
|
626
|
+
// TODO - there's an optimization here (although it deviates from the strict definition of pattern matching).
|
|
627
|
+
// If we don't need the values then we can call PyObject_Contains instead of "get". If we don't need *any*
|
|
628
|
+
// of the values then we can skip initialization "get" and "dummy"
|
|
629
|
+
#if CYTHON_UNPACK_METHODS && CYTHON_VECTORCALL
|
|
630
|
+
if (likely(get_method)) {
|
|
631
|
+
PyObject *args[] = { get_self, key, dummy };
|
|
632
|
+
value = PyObject_Vectorcall(get_method, args, 3, NULL);
|
|
633
|
+
}
|
|
634
|
+
else
|
|
635
|
+
#endif
|
|
636
|
+
{
|
|
637
|
+
value = __Pyx_PyObject_Call2Args(get, key, dummy);
|
|
638
|
+
}
|
|
639
|
+
if (!value) {
|
|
640
|
+
result = -1;
|
|
641
|
+
goto end;
|
|
642
|
+
} else if (value == dummy) {
|
|
643
|
+
Py_DECREF(value);
|
|
644
|
+
goto end; // failed to match.
|
|
645
|
+
} else {
|
|
646
|
+
subject = subjects[i];
|
|
647
|
+
if (subject) {
|
|
648
|
+
__Pyx_XDECREF_SET(*subject, value);
|
|
649
|
+
__Pyx_GOTREF(*subject);
|
|
650
|
+
} else {
|
|
651
|
+
Py_DECREF(value);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
result = 1;
|
|
656
|
+
|
|
657
|
+
end:
|
|
658
|
+
Py_XDECREF(dummy);
|
|
659
|
+
Py_XDECREF(get);
|
|
660
|
+
return result;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
///////////////////////// ExtractGeneric.proto ////////////////////////////////
|
|
664
|
+
|
|
665
|
+
#if CYTHON_REFNANNY
|
|
666
|
+
#define __Pyx_MatchCase_Mapping_Extract(...) __Pyx__MatchCase_Mapping_Extract(__pyx_refnanny, __VA_ARGS__)
|
|
667
|
+
#else
|
|
668
|
+
#define __Pyx_MatchCase_Mapping_Extract(...) __Pyx__MatchCase_Mapping_Extract(NULL, __VA_ARGS__)
|
|
669
|
+
#endif
|
|
670
|
+
static CYTHON_INLINE int __Pyx__MatchCase_Mapping_Extract(void *__pyx_refnanny, PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]); /* proto */
|
|
671
|
+
|
|
672
|
+
////////////////////// ExtractGeneric //////////////////////////////////////
|
|
673
|
+
//@requires: ExtractExactDict
|
|
674
|
+
//@requires: ExtractNonDict
|
|
675
|
+
//@requires: Builtins.c::PyFrozenDict
|
|
676
|
+
|
|
677
|
+
static CYTHON_INLINE int __Pyx__MatchCase_Mapping_Extract(void *__pyx_refnanny, PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]) {
|
|
678
|
+
if (__Pyx_PyAnyDict_CheckExact(mapping)) {
|
|
679
|
+
return __Pyx__MatchCase_Mapping_ExtractDict(__pyx_refnanny, mapping, keys, nKeys, subjects);
|
|
680
|
+
} else {
|
|
681
|
+
return __Pyx__MatchCase_Mapping_ExtractNonDict(__pyx_refnanny, mapping, keys, nKeys, subjects);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
///////////////////////////// DoubleStarCapture.proto //////////////////////
|
|
686
|
+
|
|
687
|
+
static PyObject* __Pyx_MatchCase_DoubleStarCapture{{tag}}(PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys); /* proto */
|
|
688
|
+
|
|
689
|
+
//////////////////////////// DoubleStarCapture //////////////////////////////
|
|
690
|
+
//@requires: Builtins.c::PyFrozenDict
|
|
691
|
+
|
|
692
|
+
// The implementation is largely copied from the original COPY_DICT_WITHOUT_KEYS opcode
|
|
693
|
+
// implementation of CPython
|
|
694
|
+
// https://github.com/python/cpython/blob/145bf269df3530176f6ebeab1324890ef7070bf8/Python/ceval.c#L3977
|
|
695
|
+
// (now removed in favour of building the same thing from a combination of opcodes)
|
|
696
|
+
// The differences are:
|
|
697
|
+
// 1. We use an array of keys rather than a tuple of keys
|
|
698
|
+
// 2. We add a shortcut for when there will be no left over keys (because I guess it's pretty common)
|
|
699
|
+
//
|
|
700
|
+
// Tempita variable 'tag' can be "NonDict", "ExactDict", "ExactFrozenDict" or empty
|
|
701
|
+
|
|
702
|
+
static PyObject* __Pyx_MatchCase_DoubleStarCapture{{tag}}(PyObject *mapping, PyObject *keys[], Py_ssize_t nKeys) {
|
|
703
|
+
PyObject *dict_out;
|
|
704
|
+
Py_ssize_t i, size;
|
|
705
|
+
|
|
706
|
+
// shortcut for when there are no left-over keys
|
|
707
|
+
{{if tag=="ExactDict" or tag=="ExactFrozenDict"}}
|
|
708
|
+
if ((1))
|
|
709
|
+
{{else}}
|
|
710
|
+
if (__Pyx_PyAnyDict_CheckExact(mapping))
|
|
711
|
+
{{endif}}
|
|
712
|
+
{
|
|
713
|
+
size = PyDict_Size(mapping);
|
|
714
|
+
} else {
|
|
715
|
+
size = PyObject_Length(mapping);
|
|
716
|
+
}
|
|
717
|
+
if (unlikely(size == -1)) return NULL;
|
|
718
|
+
if (size == nKeys) {
|
|
719
|
+
return PyDict_New();
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
{{if tag=="ExactDict"}}
|
|
723
|
+
dict_out = PyDict_Copy(mapping);
|
|
724
|
+
{{else}}
|
|
725
|
+
dict_out = PyDict_New();
|
|
726
|
+
{{endif}}
|
|
727
|
+
if (!dict_out) {
|
|
728
|
+
return NULL;
|
|
729
|
+
}
|
|
730
|
+
{{if tag!="ExactDict"}}
|
|
731
|
+
if (PyDict_Update(dict_out, mapping)) {
|
|
732
|
+
Py_DECREF(dict_out);
|
|
733
|
+
return NULL;
|
|
734
|
+
}
|
|
735
|
+
{{endif}}
|
|
736
|
+
|
|
737
|
+
for (i=0; i<nKeys; ++i) {
|
|
738
|
+
if (PyDict_DelItem(dict_out, keys[i])) {
|
|
739
|
+
Py_DECREF(dict_out);
|
|
740
|
+
return NULL;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return dict_out;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
////////////////////////////// ClassPositionalPatterns.proto ////////////////////////
|
|
747
|
+
|
|
748
|
+
#if CYTHON_REFNANNY
|
|
749
|
+
#define __Pyx_MatchCase_ClassPositional(...) __Pyx__MatchCase_ClassPositional(__pyx_refnanny, __VA_ARGS__)
|
|
750
|
+
#else
|
|
751
|
+
#define __Pyx_MatchCase_ClassPositional(...) __Pyx__MatchCase_ClassPositional(NULL, __VA_ARGS__)
|
|
752
|
+
#endif
|
|
753
|
+
static int __Pyx__MatchCase_ClassPositional(void *__pyx_refnanny, PyObject *subject, PyObject *type, PyObject *fixed_names[], Py_ssize_t n_fixed, int match_self, PyObject **subjects[], Py_ssize_t n_subjects); /* proto */
|
|
754
|
+
|
|
755
|
+
/////////////////////////// ClassPositionalPatterns //////////////////////////////
|
|
756
|
+
//@requires: ObjectHandling.c::RaiseErrorWithObjectTypes
|
|
757
|
+
//@requires: ObjectHandling.c::RaiseErrorWithObjectType
|
|
758
|
+
//@requires: ObjectHandling.c::RaiseErrorWithTypeAndVarargs
|
|
759
|
+
//@requires: Builtins.c::PyFrozenDict
|
|
760
|
+
|
|
761
|
+
static int __Pyx_MatchCase_ClassCheckDuplicateAttrs(PyTypeObject *type, PyObject *fixed_names[], Py_ssize_t n_fixed, PyObject *match_args, Py_ssize_t num_args) {
|
|
762
|
+
// a lot of the basic logic of this is shared with __Pyx_MatchCase_CheckMappingDuplicateKeys
|
|
763
|
+
// but they take different input types so it isn't easy to actually share the code.
|
|
764
|
+
|
|
765
|
+
// Inputs are tuples, and typically fairly small. It may be more efficient to
|
|
766
|
+
// loop over the tuple than create a set.
|
|
767
|
+
|
|
768
|
+
PyObject *attrs_set;
|
|
769
|
+
PyObject *attr = NULL;
|
|
770
|
+
Py_ssize_t n, match_args_size;
|
|
771
|
+
int contains;
|
|
772
|
+
|
|
773
|
+
match_args_size = __Pyx_PyTuple_GET_SIZE(match_args);
|
|
774
|
+
if (n_fixed == 0 && match_args_size == 1) {
|
|
775
|
+
// Trivial cases where there can be no duplicates.
|
|
776
|
+
// (In the match_args_size == 0 trivial case, this function is never called).
|
|
777
|
+
return 0;
|
|
778
|
+
}
|
|
779
|
+
#if !CYTHON_ASSUME_SAFE_SIZE
|
|
780
|
+
if (unlikely(match_args_size < 0)) return -1;
|
|
781
|
+
#endif
|
|
782
|
+
|
|
783
|
+
attrs_set = PySet_New(NULL);
|
|
784
|
+
if (unlikely(!attrs_set)) return -1;
|
|
785
|
+
|
|
786
|
+
num_args = match_args_size < num_args ? match_args_size : num_args;
|
|
787
|
+
for (n=0; n < num_args; ++n) {
|
|
788
|
+
attr = __Pyx_PyTuple_GET_ITEM(match_args, n);
|
|
789
|
+
#if !CYTHON_ASSUME_SAFE_MACROS
|
|
790
|
+
if (unlikely(!attr)) goto bad;
|
|
791
|
+
#endif
|
|
792
|
+
contains = PySet_Contains(attrs_set, attr);
|
|
793
|
+
if (contains < 0) {
|
|
794
|
+
goto bad;
|
|
795
|
+
} else if (contains == 1) {
|
|
796
|
+
goto raise_error;
|
|
797
|
+
} else {
|
|
798
|
+
if (PySet_Add(attrs_set, attr)) {
|
|
799
|
+
goto bad;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
for (n=0; n < n_fixed; ++n) {
|
|
804
|
+
attr = fixed_names[n];
|
|
805
|
+
contains = PySet_Contains(attrs_set, attr);
|
|
806
|
+
if (contains < 0) {
|
|
807
|
+
goto bad;
|
|
808
|
+
} else if (contains == 1) {
|
|
809
|
+
goto raise_error;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
Py_DECREF(attrs_set);
|
|
813
|
+
return 0;
|
|
814
|
+
|
|
815
|
+
raise_error:
|
|
816
|
+
__Pyx_RaiseErrorWithTypeAndVarargs(
|
|
817
|
+
PyExc_TypeError,
|
|
818
|
+
__Pyx_FMT_TYPENAME "() got multiple sub-patterns for attribute %R",
|
|
819
|
+
type, attr
|
|
820
|
+
);
|
|
821
|
+
bad:
|
|
822
|
+
Py_DECREF(attrs_set);
|
|
823
|
+
return -1;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// Adapted from ceval.c "match_class" in CPython
|
|
827
|
+
//
|
|
828
|
+
// The argument match_self can equal 1 for "known to be true"
|
|
829
|
+
// 0 for "known to be false"
|
|
830
|
+
// -1 for "unknown", runtime test
|
|
831
|
+
// n_subjects is >= 0 otherwise this function will be skipped
|
|
832
|
+
static int __Pyx__MatchCase_ClassPositional(void *__pyx_refnanny, PyObject *subject, PyObject *type_o, PyObject *fixed_names[], Py_ssize_t n_fixed, int match_self, PyObject **subjects[], Py_ssize_t n_subjects)
|
|
833
|
+
{
|
|
834
|
+
PyObject *match_args = NULL;
|
|
835
|
+
Py_ssize_t allowed, i;
|
|
836
|
+
int result;
|
|
837
|
+
|
|
838
|
+
assert(PyType_Check(type_o));
|
|
839
|
+
|
|
840
|
+
PyTypeObject *type = (PyTypeObject*)type_o;
|
|
841
|
+
|
|
842
|
+
#if !CYTHON_REFNANNY
|
|
843
|
+
CYTHON_UNUSED_VAR(__pyx_refnanny);
|
|
844
|
+
#endif
|
|
845
|
+
|
|
846
|
+
if (match_self != 1) {
|
|
847
|
+
#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000
|
|
848
|
+
if (PyObject_GetOptionalAttr(type_o, PYIDENT("__match_args__"), &match_args) == -1) {
|
|
849
|
+
return -1;
|
|
850
|
+
}
|
|
851
|
+
#else
|
|
852
|
+
match_args = PyObject_GetAttr(type_o, PYIDENT("__match_args__"));
|
|
853
|
+
if (!match_args) {
|
|
854
|
+
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
|
855
|
+
PyErr_Clear();
|
|
856
|
+
} else {
|
|
857
|
+
return -1;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
#endif
|
|
861
|
+
}
|
|
862
|
+
if (match_args) {
|
|
863
|
+
match_self = 0;
|
|
864
|
+
if (!PyTuple_CheckExact(match_args)) {
|
|
865
|
+
__Pyx_RaiseTypeErrorWithTypes(
|
|
866
|
+
__Pyx_FMT_TYPENAME ".__match_args__ must be a tuple (got " __Pyx_FMT_TYPENAME ")",
|
|
867
|
+
type, Py_TYPE(match_args));
|
|
868
|
+
Py_DECREF(match_args);
|
|
869
|
+
return -1;
|
|
870
|
+
}
|
|
871
|
+
} else if (!match_args && match_self == -1) {
|
|
872
|
+
// Mysteriously, this private flag seems to have ended up defined in the Limited API
|
|
873
|
+
#if defined(_Py_TPFLAGS_MATCH_SELF) && !CYTHON_COMPILING_IN_PYPY && !(CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000)
|
|
874
|
+
match_self = PyType_HasFeature(type, _Py_TPFLAGS_MATCH_SELF);
|
|
875
|
+
#else
|
|
876
|
+
// probably an earlier version of Python. Go off the known list in the specification
|
|
877
|
+
match_self = ((PyType_GetFlags(type) &
|
|
878
|
+
// long should capture bool too
|
|
879
|
+
(Py_TPFLAGS_LONG_SUBCLASS | Py_TPFLAGS_LIST_SUBCLASS | Py_TPFLAGS_TUPLE_SUBCLASS |
|
|
880
|
+
Py_TPFLAGS_BYTES_SUBCLASS | Py_TPFLAGS_UNICODE_SUBCLASS | Py_TPFLAGS_DICT_SUBCLASS
|
|
881
|
+
)) ||
|
|
882
|
+
PyType_IsSubtype(type, &PyByteArray_Type) ||
|
|
883
|
+
PyType_IsSubtype(type, &PyFloat_Type) ||
|
|
884
|
+
PyType_IsSubtype(type, &PyFrozenSet_Type)
|
|
885
|
+
#if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030F0000
|
|
886
|
+
|| PyType_IsSubtype(type, __Pyx_PyFrozenDict_TypePtr)
|
|
887
|
+
#endif
|
|
888
|
+
);
|
|
889
|
+
#endif
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
if (match_self) {
|
|
893
|
+
allowed = 1;
|
|
894
|
+
} else if (match_args) {
|
|
895
|
+
allowed = __Pyx_PyTuple_GET_SIZE(match_args);
|
|
896
|
+
#if !CYTHON_ASSUME_SAFE_SIZE
|
|
897
|
+
if (unlikely(allowed < 0)) goto end;
|
|
898
|
+
#endif
|
|
899
|
+
} else {
|
|
900
|
+
allowed = 0;
|
|
901
|
+
}
|
|
902
|
+
if (unlikely(allowed < n_subjects)) {
|
|
903
|
+
const char *plural = (allowed == 1) ? "" : "s";
|
|
904
|
+
__Pyx_RaiseErrorWithTypeAndVarargs(
|
|
905
|
+
PyExc_TypeError,
|
|
906
|
+
__Pyx_FMT_TYPENAME "() accepts %d positional sub-pattern%s (%d given)",
|
|
907
|
+
type, allowed, plural, n_subjects
|
|
908
|
+
);
|
|
909
|
+
Py_XDECREF(match_args);
|
|
910
|
+
return -1;
|
|
911
|
+
}
|
|
912
|
+
if (match_self) {
|
|
913
|
+
PyObject **self_subject = subjects[0];
|
|
914
|
+
if (self_subject) {
|
|
915
|
+
// Easy. Copy the subject itself, and move on to kwargs.
|
|
916
|
+
__Pyx_XDECREF_SET(*self_subject, subject);
|
|
917
|
+
__Pyx_INCREF(*self_subject);
|
|
918
|
+
}
|
|
919
|
+
result = 1;
|
|
920
|
+
goto end_match_self;
|
|
921
|
+
}
|
|
922
|
+
// next stage is to check for duplicate attributes.
|
|
923
|
+
if (__Pyx_MatchCase_ClassCheckDuplicateAttrs(type, fixed_names, n_fixed, match_args, n_subjects)) {
|
|
924
|
+
result = -1;
|
|
925
|
+
goto end;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
for (i = 0; i < n_subjects; i++) {
|
|
929
|
+
PyObject *attr;
|
|
930
|
+
PyObject **subject_i;
|
|
931
|
+
PyObject *name = __Pyx_PyTuple_GET_ITEM(match_args, i);
|
|
932
|
+
#if !CYTHON_ASSUME_SAFE_MACROS
|
|
933
|
+
if (unlikely(!name)) {
|
|
934
|
+
result = -1;
|
|
935
|
+
goto end;
|
|
936
|
+
}
|
|
937
|
+
#endif
|
|
938
|
+
if (!PyUnicode_CheckExact(name)) {
|
|
939
|
+
__Pyx_RaiseTypeErrorWithObjectType(
|
|
940
|
+
"__match_args__ elements must be strings (got " __Pyx_FMT_TYPENAME ")",
|
|
941
|
+
name);
|
|
942
|
+
result = -1;
|
|
943
|
+
goto end;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
attr = PyObject_GetAttr(subject, name);
|
|
947
|
+
if (attr == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
|
948
|
+
PyErr_Clear();
|
|
949
|
+
result = 0;
|
|
950
|
+
goto end;
|
|
951
|
+
}
|
|
952
|
+
subject_i = subjects[i];
|
|
953
|
+
if (subject_i) {
|
|
954
|
+
__Pyx_XDECREF_SET(*subject_i, attr);
|
|
955
|
+
__Pyx_GOTREF(attr);
|
|
956
|
+
} else {
|
|
957
|
+
Py_DECREF(attr);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
result = 1;
|
|
961
|
+
|
|
962
|
+
end:
|
|
963
|
+
Py_DECREF(match_args);
|
|
964
|
+
end_match_self: // because match_args isn't set
|
|
965
|
+
return result;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
//////////////////////// MatchClassTypeGuard.proto /////////////////////////////
|
|
969
|
+
|
|
970
|
+
static PyObject* __Pyx_MatchCase_TypeGuard(PyObject* type); /* proto */
|
|
971
|
+
|
|
972
|
+
//////////////////////// MatchClassTypeGuard /////////////////////////////
|
|
973
|
+
|
|
974
|
+
static PyObject* __Pyx_MatchCase_TypeGuard(PyObject* type) {
|
|
975
|
+
if (!PyType_Check(type)) {
|
|
976
|
+
PyErr_Format(PyExc_TypeError, "called match pattern must be a type");
|
|
977
|
+
return NULL;
|
|
978
|
+
}
|
|
979
|
+
Py_INCREF(type);
|
|
980
|
+
return type;
|
|
981
|
+
}
|