6#include "nuitka/prelude.h"
10bool Nuitka_Type_IsSubtype(PyTypeObject *a, PyTypeObject *b) {
14#if PYTHON_VERSION < 0x300
15 if (!(a->tp_flags & Py_TPFLAGS_HAVE_CLASS)) {
16 return b == a || b == &PyBaseObject_Type;
20 PyObject *mro = a->tp_mro;
23 if (likely(mro != NULL)) {
24 assert(PyTuple_Check(mro));
26 Py_ssize_t n = PyTuple_GET_SIZE(mro);
28 for (Py_ssize_t i = 0; i < n; i++) {
29 if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) {
44 return (b == &PyBaseObject_Type);
56int Nuitka_Object_IsSubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls)
59 if (PyType_CheckExact(cls)) {
66 return PyObject_IsSubclass(derived, cls);
70 if (PyTuple_Check(cls)) {
71 if (Py_EnterRecursiveCall(
" in __subclasscheck__")) {
75 Py_ssize_t n = PyTuple_GET_SIZE(cls);
78 for (Py_ssize_t i = 0; i < n; ++i) {
79 PyObject *item = PyTuple_GET_ITEM(cls, i);
81 r = Nuitka_Object_IsSubclass(tstate, derived, item);
88 Py_LeaveRecursiveCall();
94 PyObject *checker = Nuitka_TypeLookup((PyTypeObject *)cls, const_str_plain___subclasscheck__);
96 if (checker != NULL) {
97 descrgetfunc f = Py_TYPE(checker)->tp_descr_get;
102 checker = f(checker, cls, (PyObject *)(Py_TYPE(cls)));
106 if (checker != NULL) {
109 if (Py_EnterRecursiveCall(
" in __subclasscheck__")) {
114 PyObject *res = CALL_FUNCTION_WITH_SINGLE_ARG(checker, derived);
116 Py_LeaveRecursiveCall();
121 ok = CHECK_IF_TRUE(res);
125 }
else if (HAS_ERROR_OCCURRED(tstate)) {
130 return PyObject_IsSubclass(derived, cls);
134getattrofunc PyObject_GenericGetAttr_resolved;
135setattrofunc PyObject_GenericSetAttr_resolved;
139void Nuitka_PyType_Ready(PyTypeObject *type, PyTypeObject *base,
bool generic_get_attr,
bool generic_set_attr,
140 bool self_iter,
bool await_self_iter,
bool await_self_aiter) {
141 assert(type->tp_base == NULL);
143 PyObject_GenericGetAttr_resolved = PyBaseObject_Type.tp_getattro;
144 PyObject_GenericSetAttr_resolved = PyBaseObject_Type.tp_setattro;
146 type->tp_base = base;
148#if PYTHON_VERSION >= 0x3d0
152 assert(_PyType_PreHeaderSize(type) == _PyType_PreHeaderSize(base));
156 if (generic_get_attr) {
157 assert(type->tp_getattro == NULL);
158 type->tp_getattro = PyObject_GenericGetAttr_resolved;
161 if (generic_set_attr) {
162 assert(type->tp_setattro == NULL);
163 type->tp_setattro = PyObject_GenericSetAttr_resolved;
167 assert(type->tp_iter == NULL);
168 type->tp_iter = PyObject_SelfIter;
171#if PYTHON_VERSION >= 0x350
172 if (await_self_iter) {
173 assert(type->tp_as_async->am_await == NULL);
174 type->tp_as_async->am_await = PyObject_SelfIter;
177 if (await_self_aiter) {
178 assert(type->tp_as_async->am_aiter == NULL);
179 type->tp_as_async->am_aiter = PyObject_SelfIter;
182 assert(!await_self_iter);
183 assert(!await_self_aiter);
186#if PYTHON_VERSION >= 0x3a0
187 type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
190 NUITKA_MAY_BE_UNUSED
int res = PyType_Ready(type);
194#if PYTHON_VERSION >= 0x3c0
197 PyObject_HEAD PyObject *name;
198 PyObject *type_params;
199 PyObject *compute_value;
204static PyTypeObject *getTypeAliasType(
void) {
205 static PyTypeObject *type_alias_type = NULL;
207 if (type_alias_type == NULL) {
209 PyObject *typing_module = PyImport_ImportModule(
"_typing");
210 CHECK_OBJECT(typing_module);
212 type_alias_type = (PyTypeObject *)PyObject_GetAttrString(typing_module,
"TypeAliasType");
213 CHECK_OBJECT(type_alias_type);
216 return type_alias_type;
219PyObject *MAKE_TYPE_ALIAS(PyObject *name, PyObject *type_params, PyObject *compute_value, PyObject *module_name) {
222 typealiasobject *ta = Nuitka_GC_New(getTypeAliasType());
226 ta->name = Py_NewRef(name);
227 ta->type_params = Py_IsNone(type_params) ? NULL : Py_XNewRef(type_params);
228 ta->compute_value = Py_NewRef(compute_value);
230 ta->module = Py_NewRef(module_name);
234 return (PyObject *)ta;
238 PyObject_HEAD PyObject *name;
240 PyObject *evaluate_bound;
241 PyObject *constraints;
242 PyObject *evaluate_constraints;
243#if PYTHON_VERSION >= 0x3d0
244 PyObject *default_value;
245 PyObject *evaluate_default;
253 PyObject_HEAD PyObject *name;
254#if PYTHON_VERSION >= 0x3d0
255 PyObject *default_value;
256 PyObject *evaluate_default;
261 PyObject_HEAD PyObject *name;
263#if PYTHON_VERSION >= 0x3d0
264 PyObject *default_value;
265 PyObject *evaluate_default;
272static typevarobject *_Nuitka_typevar_alloc(PyThreadState *tstate, PyObject *name, PyObject *bound,
273 PyObject *evaluate_bound, PyObject *constraints,
274 PyObject *evaluate_constraints,
bool covariant,
bool contravariant,
275 bool infer_variance, PyObject *module) {
276 PyTypeObject *tp = _Py_INTERP_CACHED_OBJECT(tstate->interp, typevar_type);
277 typevarobject *result = Nuitka_GC_New(tp);
279 result->name = Py_NewRef(name);
281 result->bound = Py_XNewRef(bound);
282 result->evaluate_bound = Py_XNewRef(evaluate_bound);
283 result->constraints = Py_XNewRef(constraints);
284 result->evaluate_constraints = Py_XNewRef(evaluate_constraints);
285#if PYTHON_VERSION >= 0x3d0
286 result->default_value = NULL;
287 result->evaluate_default = NULL;
290 result->covariant = covariant;
291 result->contravariant = contravariant;
292 result->infer_variance = infer_variance;
294 Nuitka_GC_Track(result);
297 if (unlikely(module != NULL)) {
298 if (PyObject_SetAttrString((PyObject *)result,
"__module__", module) < 0) {
307static typevartupleobject *_Nuitka_typevartuple_alloc(PyThreadState *tstate, PyObject *name, PyObject *module,
308 PyObject *default_value) {
309 PyTypeObject *tp = _Py_INTERP_CACHED_OBJECT(tstate->interp, typevartuple_type);
310 typevartupleobject *tvt = Nuitka_GC_New(tp);
314 tvt->name = Py_NewRef(name);
315#if PYTHON_VERSION >= 0x3d0
316 tvt->default_value = Py_XNewRef(default_value);
317 tvt->evaluate_default = NULL;
319 Nuitka_GC_Track(tvt);
320 if (module != NULL) {
321 if (PyObject_SetAttrString((PyObject *)tvt,
"__module__", module) < 0) {
329static paramspecobject *_Nuitka_paramspec_alloc(PyThreadState *tstate, PyObject *name, PyObject *bound,
330 PyObject *default_value,
bool covariant,
bool contravariant,
331 bool infer_variance, PyObject *module) {
332 PyTypeObject *tp = _Py_INTERP_CACHED_OBJECT(tstate->interp, paramspec_type);
333 paramspecobject *ps = Nuitka_GC_New(tp);
337 ps->name = Py_NewRef(name);
338 ps->bound = Py_XNewRef(bound);
339 ps->covariant = covariant;
340 ps->contravariant = contravariant;
341 ps->infer_variance = infer_variance;
342#if PYTHON_VERSION >= 0x3d0
343 ps->default_value = Py_XNewRef(default_value);
344 ps->evaluate_default = NULL;
347 if (module != NULL) {
348 if (PyObject_SetAttrString((PyObject *)ps,
"__module__", module) < 0) {
356PyObject *MAKE_TYPE_VAR(PyThreadState *tstate, PyObject *name) {
360 return (PyObject *)_Nuitka_typevar_alloc(tstate, name, NULL, NULL, NULL, NULL,
false,
false,
true, NULL);
363PyObject *MAKE_TYPE_VAR_TUPLE(PyThreadState *tstate, PyObject *name) {
364 return (PyObject *)_Nuitka_typevartuple_alloc(tstate, name, NULL, NULL);
367PyObject *MAKE_PARAM_SPEC(PyThreadState *tstate, PyObject *name) {
368 return (PyObject *)_Nuitka_paramspec_alloc(tstate, name, NULL, NULL,
false,
false,
true, NULL);
371static PyTypeObject *_getTypeGenericAliasType(
void) {
372 static PyTypeObject *type_generic_alias_type = NULL;
374 if (type_generic_alias_type == NULL) {
376 PyObject *typing_module = IMPORT_HARD_TYPING();
378 type_generic_alias_type = (PyTypeObject *)PyObject_GetAttrString(typing_module,
"_GenericAlias");
379 CHECK_OBJECT(type_generic_alias_type);
382 return type_generic_alias_type;
385static int _Nuitka_contains_typevartuple(PyTupleObject *params) {
386 Py_ssize_t n = PyTuple_GET_SIZE(params);
387 PyTypeObject *tp = _Py_INTERP_CACHED_OBJECT(PyInterpreterState_Get(), typevartuple_type);
388 for (Py_ssize_t i = 0; i < n; i++) {
389 PyObject *param = PyTuple_GET_ITEM(params, i);
390 if (Py_IS_TYPE(param, tp)) {
397static PyObject *_Nuitka_unpack_param(PyThreadState *tstate, PyObject *self) {
398 static PyObject *typing_unpack = NULL;
400 if (typing_unpack == NULL) {
401 typing_unpack = LOOKUP_ATTRIBUTE(tstate, IMPORT_HARD_TYPING(), const_str_plain_Unpack);
402 CHECK_OBJECT(typing_unpack);
405 return LOOKUP_SUBSCRIPT(tstate, typing_unpack, self);
409static PyObject *_Nuitka_unpack_typevartuples(PyThreadState *tstate, PyObject *params) {
410 assert(PyTuple_Check(params));
412 if (_Nuitka_contains_typevartuple((PyTupleObject *)params)) {
413 Py_ssize_t n = PyTuple_GET_SIZE(params);
414 PyObject *new_params = MAKE_TUPLE_EMPTY(tstate, n);
415 CHECK_OBJECT(new_params);
417 PyTypeObject *tp = _Py_INTERP_CACHED_OBJECT(tstate->interp, typevartuple_type);
418 for (Py_ssize_t i = 0; i < n; i++) {
419 PyObject *param = PyTuple_GET_ITEM(params, i);
420 if (Py_IS_TYPE(param, tp)) {
421 PyObject *unpacked = _Nuitka_unpack_param(tstate, param);
422 if (unpacked == NULL) {
423 Py_DECREF(new_params);
426 PyTuple_SET_ITEM(new_params, i, unpacked);
428 PyTuple_SET_ITEM(new_params, i, Py_NewRef(param));
433 return Py_NewRef(params);
437PyObject *MAKE_TYPE_GENERIC(PyThreadState *tstate, PyObject *params) {
438 CHECK_OBJECT(params);
439 PyObject *unpacked_params = _Nuitka_unpack_typevartuples(tstate, params);
440 CHECK_OBJECT(unpacked_params);
441 assert(PyTuple_CheckExact(unpacked_params));
443 PyObject *args[2] = {(PyObject *)_Py_INTERP_CACHED_OBJECT(tstate->interp, generic_type), unpacked_params};
445 PyObject *called = (PyObject *)_getTypeGenericAliasType();
447 PyObject *result = CALL_FUNCTION_WITH_ARGS2(tstate, called, args);
448 Py_DECREF(unpacked_params);
450 return MAKE_TUPLE1_0(tstate, result);