///////////////////////////// ABCCheck ////////////////////////////// //@requires: Builtins.c::PyFrozenDict #if PY_VERSION_HEX < 0x030A0000 || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY static CYTHON_INLINE int __Pyx_MatchCase_IsExactSequence(PyObject *o) { // Is one of the small list of builtin types known to be a sequence. if (PyList_CheckExact(o) || PyTuple_CheckExact(o) || Py_IS_TYPE(o, &PyRange_Type) || Py_IS_TYPE(o, &PyMemoryView_Type)) { // Use exact type match for these checks. In in the event of inheritance we need to make sure // that it isn't a mapping too return 1; } return 0; } static CYTHON_INLINE int __Pyx_MatchCase_IsExactMapping(PyObject *o) { // dict and frozendict are the only regularly used mapping type. // "types.MappingProxyType" also exists but is correctly covered by // the isinstance(o, Mapping) check. return __Pyx_PyAnyDict_CheckExact(o); } static int __Pyx_MatchCase_IsExactNeitherSequenceNorMapping(PyObject *o) { if (PyByteArray_Check(o) || PyBytes_Check(o) || PyUnicode_Check(o)) { // These types are deliberately excluded from the sequence test // even though they look like sequences for most other purposes. // Leaving them as inexact checks since they do pass // "isinstance(o, collections.abc.Sequence)" so it's very hard to // reason about their subclasses. return 1; } // No-exhaustive list of other common builtin types as an optimization. if (o == Py_None || PyLong_CheckExact(o) || PyFloat_CheckExact(o) || Py_TYPE(o) == &PyBool_Type || Py_TYPE(o) == &PySlice_Type || PyAnySet_CheckExact(o) || PyComplex_CheckExact(o)) { return 1; } return 0; } // sequence_mapping_temp: For Python 3.10 testing sequences and mappings are // really quick and this is ignored. For lower versions of Python they're // slow, especially in the "fail" case. // Therefore, we store an int temp to avoid duplicating tests. // The bits of it in order are: // 0. definitely a sequence // 1. definitely a mapping // - note that both of the above can be true when // the type is registered with both abc types (not via inheritance) // and in this case we return true for both IsSequence or IsMapping // (which seems like the best handling of an ambiguous situation) // 2. definitely not a sequence // 3. definitely not a mapping #define __PYX_DEFINITELY_SEQUENCE_FLAG 1U #define __PYX_DEFINITELY_MAPPING_FLAG (1U<<1) #define __PYX_DEFINITELY_NOT_SEQUENCE_FLAG (1U<<2) #define __PYX_DEFINITELY_NOT_MAPPING_FLAG (1U<<3) #define __PYX_SEQUENCE_MAPPING_ERROR (1U<<4) // only used by the ABCCheck function static int __Pyx_MatchCase_InitAbcType(PyObject *abc_module, PyObject **abc_type, PyObject *name) { if (*abc_type) return 0; *abc_type = PyObject_GetAttr(abc_module, name); return *abc_type ? 0 : -1; } // The result is defined using the specification for sequence_mapping_temp // (detailed in "is_sequence"). static unsigned int __Pyx_MatchCase_ABCCheck(PyObject *o, int sequence_first, int definitely_not_sequence, int definitely_not_mapping) { // In Python 3.10+, objects can have their sequence bit set or their mapping bit set // but not both. Practically, this translates to "which type is registered first". // In Python < 3.10 we can only determine this if they're direct bases (by looking // at the MRO order). If they're registered manually then we can't tell. PyObject *abc_module=NULL, *sequence_type=NULL, *mapping_type=NULL; PyObject *mro; int sequence_result=0, mapping_result=0; unsigned int result = 0; if (sequence_first && definitely_not_sequence) { return __PYX_DEFINITELY_NOT_SEQUENCE_FLAG; } if (!sequence_first && definitely_not_mapping) { return __PYX_DEFINITELY_NOT_MAPPING_FLAG; } abc_module = PyImport_ImportModule("collections.abc"); if (!abc_module) { return __PYX_SEQUENCE_MAPPING_ERROR; } if (sequence_first) { if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &sequence_type, PYIDENT("Sequence")) == -1)) { result = __PYX_SEQUENCE_MAPPING_ERROR; goto end; } sequence_result = PyObject_IsInstance(o, sequence_type); if (sequence_result <= 0) { result = sequence_result < 0 ? __PYX_SEQUENCE_MAPPING_ERROR : __PYX_DEFINITELY_NOT_SEQUENCE_FLAG; goto end; } // else sequence_result==1 but wait to see what mapping is } if (!definitely_not_mapping) { if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &mapping_type, PYIDENT("Mapping")) == -1)) { result = __PYX_SEQUENCE_MAPPING_ERROR; goto end; } mapping_result = PyObject_IsInstance(o, mapping_type); if (unlikely(mapping_result < 0)) { result = __PYX_SEQUENCE_MAPPING_ERROR; goto end; } else if (mapping_result == 0 && !sequence_first) { result = __PYX_DEFINITELY_NOT_MAPPING_FLAG; goto end; } // else mapping_result == 1 } if (!sequence_first && !definitely_not_sequence) { if (unlikely(__Pyx_MatchCase_InitAbcType(abc_module, &sequence_type, PYIDENT("Sequence")) == -1)) { result = __PYX_SEQUENCE_MAPPING_ERROR; goto end; } sequence_result = PyObject_IsInstance(o, sequence_type); if (unlikely(sequence_result < 0)) { result = __PYX_SEQUENCE_MAPPING_ERROR; goto end; } } result |= (sequence_result ? __PYX_DEFINITELY_SEQUENCE_FLAG : __PYX_DEFINITELY_NOT_SEQUENCE_FLAG); result |= (mapping_result ? __PYX_DEFINITELY_MAPPING_FLAG : __PYX_DEFINITELY_NOT_MAPPING_FLAG); if (result != (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_MAPPING_FLAG)) { goto end; } // It's an instance of both types. Look up the MRO order. // In event of failure treat it as "could be either" mro = PyObject_GetAttrString((PyObject*)Py_TYPE(o), "__mro__"); Py_ssize_t i, mro_size; if (!mro) { PyErr_Clear(); goto end; } if (!PyTuple_Check(mro)) { Py_DECREF(mro); goto end; } mro_size = __Pyx_PyTuple_GET_SIZE(mro); #if !CYTHON_ASSUME_SAFE_SIZE if (unlikely(mro_size == -1)) { goto loop_error; } #endif for (i=1; i < mro_size; ++i) { int is_subclass_sequence, is_subclass_mapping; PyObject *mro_item = __Pyx_PyTuple_GET_ITEM(mro, i); #if !CYTHON_ASSUME_SAFE_MACROS if (unlikely(!mro_item)) goto loop_error; #endif is_subclass_sequence = PyObject_IsSubclass(mro_item, sequence_type); if (is_subclass_sequence < 0) goto loop_error; is_subclass_mapping = PyObject_IsSubclass(mro_item, mapping_type); if (is_subclass_mapping < 0) goto loop_error; if (is_subclass_sequence && !is_subclass_mapping) { result = (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG); break; } else if (is_subclass_mapping && !is_subclass_sequence) { result = (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_MAPPING_FLAG); break; } } // If we get to the end of the loop without breaking then neither type is in // the MRO, so they've both been registered manually. We don't know which was // registered first so accept the object as either as a compromise. loop_error_recovery: Py_DECREF(mro); end: Py_XDECREF(abc_module); Py_XDECREF(sequence_type); Py_XDECREF(mapping_type); return result; loop_error: PyErr_Clear(); goto loop_error_recovery; } #endif ///////////////////////////// IsSequence.proto ////////////////////// static int __Pyx_MatchCase_IsSequence(PyObject *o, unsigned int *sequence_mapping_temp); /* proto */ //////////////////////////// IsSequence ///////////////////////// //@requires: ABCCheck static int __Pyx_MatchCase_IsSequence(PyObject *o, unsigned int *sequence_mapping_temp) { #if PY_VERSION_HEX >= 0x030A0000 && !(CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY) CYTHON_UNUSED_VAR(sequence_mapping_temp); return __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_SEQUENCE); #else #if CYTHON_COMPILING_IN_LIMITED_API // In the Limited API we have runtime access to Py_TPFLAGS_SEQUENCE // by looking it up on module init so it's still worth attempting // the fast path. if (__Pyx_Runtime_TPFLAGS_SEQUENCE) { return __Pyx_PyType_HasFeature(Py_TYPE(o), __Pyx_Runtime_TPFLAGS_SEQUENCE); } #elif defined(Py_TPFLAGS_SEQUENCE) // Elsewhere *we* define Py_TPFLAGS_SEQUENCE but that doesn't necessarily // mean other types use it, so only success is meaningful. if (__Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_SEQUENCE)) { return 1; } #endif // Py_TPFLAGS_SEQUENCE doesn't exit. PyObject *o_module_name; unsigned int abc_result, dummy=0; if (sequence_mapping_temp) { // maybe we already know the answer if (*sequence_mapping_temp & __PYX_DEFINITELY_SEQUENCE_FLAG) { return 1; } if (*sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG) { return 0; } } else { // Probably quicker to just assign it and not check from here. sequence_mapping_temp = &dummy; } // Start by checking a known list of types. if (__Pyx_MatchCase_IsExactSequence(o)) { *sequence_mapping_temp |= (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG); return 1; } if (__Pyx_MatchCase_IsExactMapping(o)) { *sequence_mapping_temp |= (__PYX_DEFINITELY_MAPPING_FLAG | __PYX_DEFINITELY_NOT_SEQUENCE_FLAG); return 0; } if (__Pyx_MatchCase_IsExactNeitherSequenceNorMapping(o)) { *sequence_mapping_temp |= (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG); return 0; } abc_result = __Pyx_MatchCase_ABCCheck( o, 1, *sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG, *sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG ); if (abc_result & __PYX_SEQUENCE_MAPPING_ERROR) { return -1; } *sequence_mapping_temp = abc_result; if (*sequence_mapping_temp & __PYX_DEFINITELY_SEQUENCE_FLAG) { return 1; } // array.array is a more complicated check (and unfortunately isn't covered by // collections.abc.Sequence on Python <3.10). // Do the test by checking the module name, and then importing/testing the class. // It also doesn't give perfect results for classes that inherit from both array.array // and a mapping. #if !CYTHON_COMPILING_IN_LIMITED_API || __PYX_LIMITED_VERSION_HEX < 0x030A0000 #if CYTHON_COMPILING_IN_LIMITED_API if (__Pyx_get_runtime_version() < 0x030A0000) #endif { o_module_name = PyObject_GetAttrString((PyObject*)Py_TYPE(o), "__module__"); if (!o_module_name) { return -1; } if (PyUnicode_Check(o_module_name) && PyUnicode_CompareWithASCIIString(o_module_name, "array") == 0) { int is_array; PyObject *array_module, *array_object; Py_DECREF(o_module_name); array_module = PyImport_ImportModule("array"); if (!array_module) { PyErr_Clear(); return 0; // treat these tests as "soft" and don't cause an exception } array_object = PyObject_GetAttrString(array_module, "array"); Py_DECREF(array_module); if (!array_object) { PyErr_Clear(); return 0; } is_array = PyObject_IsInstance(o, array_object); Py_DECREF(array_object); if (is_array) { *sequence_mapping_temp |= __PYX_DEFINITELY_SEQUENCE_FLAG; return 1; } PyErr_Clear(); } else { Py_DECREF(o_module_name); } } #else CYTHON_UNUSED_VAR(o_module_name); #endif *sequence_mapping_temp |= __PYX_DEFINITELY_NOT_SEQUENCE_FLAG; return 0; #endif } ////////////////////// OtherSequenceSliceToList.proto ////////////////////// static PyObject *__Pyx_MatchCase_OtherSequenceSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end); /* proto */ ////////////////////// OtherSequenceSliceToList ////////////////////////// // This is substantially based off ceval unpack_iterable. // It's also pretty similar to itertools.islice. // Indices must be positive - there's no wraparound or boundschecking. static PyObject *__Pyx_MatchCase_OtherSequenceSliceToList(PyObject *x, Py_ssize_t start, Py_ssize_t end) { Py_ssize_t total = end-start; Py_ssize_t i; PyObject *list; ssizeargfunc slot; list = PyList_New(total); if (!list) { return NULL; } slot = __Pyx_PyObject_TryGetSubSlot(x, tp_as_sequence, sq_item, ssizeargfunc); if (!slot) { #if !CYTHON_COMPILING_IN_LIMITED_API && !defined(PySequence_ITEM) // PyPy (and maybe others?) implements PySequence_ITEM as a function. In this case. // it's slightly more efficient than using PySequence_GetItem since it skips negative indices. slot = PySequence_ITEM; #else slot = PySequence_GetItem; #endif } for (i=start; i= 0x030A0000 && !(CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY) CYTHON_UNUSED_VAR(sequence_mapping_temp); return __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_MAPPING); #else #if CYTHON_COMPILING_IN_LIMITED_API // In the Limited API we have runtime access to Py_TPFLAGS_MAPPING // by looking it up on module init so it's still worth attempting // the fast path. if (__Pyx_Runtime_TPFLAGS_MAPPING) { return __Pyx_PyType_HasFeature(Py_TYPE(o), __Pyx_Runtime_TPFLAGS_MAPPING); } #elif defined(Py_TPFLAGS_MAPPING) // Elsewhere *we* define Py_TPFLAGS_SEQUENCE but that doesn't necessarily // mean other types use it, so only success is meaningful. if (__Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_MAPPING)) { return 1; } #endif unsigned int abc_result, dummy=0; if (sequence_mapping_temp) { // do we already know the answer? if (*sequence_mapping_temp & __PYX_DEFINITELY_MAPPING_FLAG) { return 1; } else if (*sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG) { return 0; } } else { sequence_mapping_temp = &dummy; // just so we can assign freely without checking } if (__Pyx_MatchCase_IsExactMapping(o)) { *sequence_mapping_temp |= (__PYX_DEFINITELY_MAPPING_FLAG | __PYX_DEFINITELY_NOT_SEQUENCE_FLAG); return 1; } if (__Pyx_MatchCase_IsExactSequence(o)) { *sequence_mapping_temp |= (__PYX_DEFINITELY_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG); return 0; } if (__Pyx_MatchCase_IsExactNeitherSequenceNorMapping(o)) { *sequence_mapping_temp |= (__PYX_DEFINITELY_NOT_SEQUENCE_FLAG | __PYX_DEFINITELY_NOT_MAPPING_FLAG); return 0; } // otherwise check against collections.abc.Mapping abc_result = __Pyx_MatchCase_ABCCheck( o, 0, *sequence_mapping_temp & __PYX_DEFINITELY_NOT_SEQUENCE_FLAG, *sequence_mapping_temp & __PYX_DEFINITELY_NOT_MAPPING_FLAG ); if (abc_result & __PYX_SEQUENCE_MAPPING_ERROR) { return -1; } *sequence_mapping_temp = abc_result; return *sequence_mapping_temp & __PYX_DEFINITELY_MAPPING_FLAG; #endif } //////////////////////// MappingKeyCheck.proto ///////////////////////// static int __Pyx_MatchCase_CheckMappingDuplicateKeys(PyObject *keys[], Py_ssize_t nFixedKeys, Py_ssize_t nKeys); //////////////////////// MappingKeyCheck /////////////////////////////// static int __Pyx_MatchCase_CheckMappingDuplicateKeys(PyObject *keys[], Py_ssize_t nFixedKeys, Py_ssize_t nKeys) { // Inputs are arrays, and typically fairly small. It may be more efficient to // loop over the array than create a set. // The CPython implementation (match_keys in ceval.c) does this concurrently with // taking the keys out of the dictionary. I'm choosing to do it separately since the // majority of the time the keys will be known at compile-time so Cython can skip // this step completely. // The step is also skipped when there's only a single key. PyObject *var_keys_set; PyObject *key; Py_ssize_t n; int contains; var_keys_set = PySet_New(NULL); if (!var_keys_set) return -1; for (n=nFixedKeys; n < nKeys; ++n) { key = keys[n]; contains = PySet_Contains(var_keys_set, key); if (contains < 0) { goto bad; } else if (contains == 1) { goto raise_error; } else { if (PySet_Add(var_keys_set, key)) { goto bad; } } } for (n=0; n < nFixedKeys; ++n) { key = keys[n]; contains = PySet_Contains(var_keys_set, key); if (contains < 0) { goto bad; } else if (contains == 1) { goto raise_error; } } Py_DECREF(var_keys_set); return 0; raise_error: PyErr_Format(PyExc_ValueError, "mapping pattern checks duplicate key (%R)", key); bad: Py_DECREF(var_keys_set); return -1; } /////////////////////////// ExtractExactDict.proto //////////////// // The subjects array is a list of PyObject** to subjects to be filled. They may be NULL // in which case they're ignored. // // This is a specialized version for when we have an exact (frozen)dict (which is likely to be pretty common) #if CYTHON_REFNANNY #define __Pyx_MatchCase_Mapping_ExtractDict(...) __Pyx__MatchCase_Mapping_ExtractDict(__pyx_refnanny, __VA_ARGS__) #else #define __Pyx_MatchCase_Mapping_ExtractDict(...) __Pyx__MatchCase_Mapping_ExtractDict(NULL, __VA_ARGS__) #endif static CYTHON_INLINE int __Pyx__MatchCase_Mapping_ExtractDict(void *__pyx_refnanny, PyObject *dict, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]); /* proto */ /////////////////////////// ExtractExactDict //////////////// static CYTHON_INLINE int __Pyx__MatchCase_Mapping_ExtractDict(void *__pyx_refnanny, PyObject *dict, PyObject *keys[], Py_ssize_t nKeys, PyObject **subjects[]) { #if !CYTHON_REFNANNY CYTHON_UNUSED_VAR(__pyx_refnanny); #endif Py_ssize_t i; Py_ssize_t size; size = PyDict_Size(dict); if (size < nKeys) { return size == -1 ? -1: 0; } for (i=0; i= 0 otherwise this function will be skipped 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) { PyObject *match_args = NULL; Py_ssize_t allowed, i; int result; assert(PyType_Check(type_o)); PyTypeObject *type = (PyTypeObject*)type_o; #if !CYTHON_REFNANNY CYTHON_UNUSED_VAR(__pyx_refnanny); #endif if (match_self != 1) { #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 if (PyObject_GetOptionalAttr(type_o, PYIDENT("__match_args__"), &match_args) == -1) { return -1; } #else match_args = PyObject_GetAttr(type_o, PYIDENT("__match_args__")); if (!match_args) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); } else { return -1; } } #endif } if (match_args) { match_self = 0; if (!PyTuple_CheckExact(match_args)) { __Pyx_RaiseTypeErrorWithTypes( __Pyx_FMT_TYPENAME ".__match_args__ must be a tuple (got " __Pyx_FMT_TYPENAME ")", type, Py_TYPE(match_args)); Py_DECREF(match_args); return -1; } } else if (!match_args && match_self == -1) { // Mysteriously, this private flag seems to have ended up defined in the Limited API #if defined(_Py_TPFLAGS_MATCH_SELF) && !CYTHON_COMPILING_IN_PYPY && !(CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000) match_self = PyType_HasFeature(type, _Py_TPFLAGS_MATCH_SELF); #else // probably an earlier version of Python. Go off the known list in the specification match_self = ((PyType_GetFlags(type) & // long should capture bool too (Py_TPFLAGS_LONG_SUBCLASS | Py_TPFLAGS_LIST_SUBCLASS | Py_TPFLAGS_TUPLE_SUBCLASS | Py_TPFLAGS_BYTES_SUBCLASS | Py_TPFLAGS_UNICODE_SUBCLASS | Py_TPFLAGS_DICT_SUBCLASS )) || PyType_IsSubtype(type, &PyByteArray_Type) || PyType_IsSubtype(type, &PyFloat_Type) || PyType_IsSubtype(type, &PyFrozenSet_Type) #if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030F0000 || PyType_IsSubtype(type, __Pyx_PyFrozenDict_TypePtr) #endif ); #endif } if (match_self) { allowed = 1; } else if (match_args) { allowed = __Pyx_PyTuple_GET_SIZE(match_args); #if !CYTHON_ASSUME_SAFE_SIZE if (unlikely(allowed < 0)) goto end; #endif } else { allowed = 0; } if (unlikely(allowed < n_subjects)) { const char *plural = (allowed == 1) ? "" : "s"; __Pyx_RaiseErrorWithTypeAndVarargs( PyExc_TypeError, __Pyx_FMT_TYPENAME "() accepts %d positional sub-pattern%s (%d given)", type, allowed, plural, n_subjects ); Py_XDECREF(match_args); return -1; } if (match_self) { PyObject **self_subject = subjects[0]; if (self_subject) { // Easy. Copy the subject itself, and move on to kwargs. __Pyx_XDECREF_SET(*self_subject, subject); __Pyx_INCREF(*self_subject); } result = 1; goto end_match_self; } // next stage is to check for duplicate attributes. if (__Pyx_MatchCase_ClassCheckDuplicateAttrs(type, fixed_names, n_fixed, match_args, n_subjects)) { result = -1; goto end; } for (i = 0; i < n_subjects; i++) { PyObject *attr; PyObject **subject_i; PyObject *name = __Pyx_PyTuple_GET_ITEM(match_args, i); #if !CYTHON_ASSUME_SAFE_MACROS if (unlikely(!name)) { result = -1; goto end; } #endif if (!PyUnicode_CheckExact(name)) { __Pyx_RaiseTypeErrorWithObjectType( "__match_args__ elements must be strings (got " __Pyx_FMT_TYPENAME ")", name); result = -1; goto end; } attr = PyObject_GetAttr(subject, name); if (attr == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); result = 0; goto end; } subject_i = subjects[i]; if (subject_i) { __Pyx_XDECREF_SET(*subject_i, attr); __Pyx_GOTREF(attr); } else { Py_DECREF(attr); } } result = 1; end: Py_DECREF(match_args); end_match_self: // because match_args isn't set return result; } //////////////////////// MatchClassTypeGuard.proto ///////////////////////////// static PyObject* __Pyx_MatchCase_TypeGuard(PyObject* type); /* proto */ //////////////////////// MatchClassTypeGuard ///////////////////////////// static PyObject* __Pyx_MatchCase_TypeGuard(PyObject* type) { if (!PyType_Check(type)) { PyErr_Format(PyExc_TypeError, "called match pattern must be a type"); return NULL; } Py_INCREF(type); return type; }