Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersClasses.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
10// This file is included from another C file, help IDEs to still parse it on
11// its own.
12#ifdef __IDE_ONLY__
13#include "nuitka/prelude.h"
14#endif
15
16#if PYTHON_VERSION >= 0x300
17PyObject *SELECT_METACLASS(PyThreadState *tstate, PyObject *metaclass, PyObject *bases) {
18 CHECK_OBJECT(metaclass);
19 CHECK_OBJECT(bases);
20
21 if (likely(PyType_Check(metaclass))) {
22 // Determine the proper metaclass type
23 Py_ssize_t nbases = PyTuple_GET_SIZE(bases);
24 PyTypeObject *winner = (PyTypeObject *)metaclass;
25
26#if _DEBUG_CLASSES
27 PRINT_STRING("Bases:");
28 PRINT_ITEM((PyObject *)bases);
29 PRINT_NEW_LINE();
30#endif
31
32 for (int i = 0; i < nbases; i++) {
33 PyObject *base = PyTuple_GET_ITEM(bases, i);
34
35 PyTypeObject *base_type = Py_TYPE(base);
36
37 if (Nuitka_Type_IsSubtype(winner, base_type)) {
38 // Ignore if current winner is already a subtype.
39 continue;
40 } else if (Nuitka_Type_IsSubtype(base_type, winner)) {
41 // Use if, if it's a subtype of the current winner.
42 winner = base_type;
43 continue;
44 } else {
45 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
46 "metaclass conflict: the metaclass of a derived class must be a "
47 "(non-strict) subclass of the metaclasses of all its bases");
48
49 return NULL;
50 }
51 }
52
53 if (unlikely(winner == NULL)) {
54 return NULL;
55 }
56
57#if _DEBUG_CLASSES
58 PRINT_STRING("Metaclass winner:");
59 PRINT_ITEM((PyObject *)winner);
60 PRINT_NEW_LINE();
61#endif
62
63 Py_INCREF(winner);
64 return (PyObject *)winner;
65 } else {
66#if _DEBUG_CLASSES
67 PRINT_STRING("Metaclass not a type is used:");
68 PRINT_ITEM((PyObject *)metaclass);
69 PRINT_NEW_LINE();
70#endif
71
72 Py_INCREF(metaclass);
73 return metaclass;
74 }
75}
76#endif
77
78// Part of "Nuitka", an optimizing Python compiler that is compatible and
79// integrates with CPython, but also works on its own.
80//
81// Licensed under the Apache License, Version 2.0 (the "License");
82// you may not use this file except in compliance with the License.
83// You may obtain a copy of the License at
84//
85// http://www.apache.org/licenses/LICENSE-2.0
86//
87// Unless required by applicable law or agreed to in writing, software
88// distributed under the License is distributed on an "AS IS" BASIS,
89// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
90// See the License for the specific language governing permissions and
91// limitations under the License.