Nuitka
The Python compiler
Loading...
Searching...
No Matches
prelude.h
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3#ifndef __NUITKA_PRELUDE_H__
4#define __NUITKA_PRELUDE_H__
5
6#ifdef __NUITKA_NO_ASSERT__
7#undef NDEBUG
8#define NDEBUG
9#endif
10
11#include "nuitka/debug_settings.h"
12
13#if defined(_WIN32)
14// Note: Keep this separate line, must be included before other Windows headers.
15#include <windows.h>
16#endif
17
18/* Include the CPython version numbers, and define our own take of what version
19 * numbers should be.
20 */
21#include <patchlevel.h>
22
23/* Use a hex version of our own to compare for versions. We do not care about pre-releases */
24#if PY_MICRO_VERSION < 16
25#define PYTHON_VERSION (PY_MAJOR_VERSION * 256 + PY_MINOR_VERSION * 16 + PY_MICRO_VERSION)
26#else
27#define PYTHON_VERSION (PY_MAJOR_VERSION * 256 + PY_MINOR_VERSION * 16 + 15)
28#endif
29
30/* This is needed or else we can't create modules name "proc" or "func". For
31 * Python3, the name collision can't happen, so we can limit it to Python2.
32 spell-checker: ignore initproc,initfunc
33 */
34#define initproc python_init_proc
35#define initfunc python_init_func
36#define initstate python_initstate
37
38// Python 3.11 headers give these warnings
39#if defined(_MSC_VER)
40#pragma warning(push)
41#pragma warning(disable : 4200)
42#pragma warning(disable : 4244)
43#endif
44
45/* Include the relevant Python C-API header files. */
46#include <Python.h>
47#include <frameobject.h>
48#include <marshal.h>
49#include <methodobject.h>
50#include <osdefs.h>
51#include <structseq.h>
52
53#if PYTHON_VERSION < 0x3a0
54#include <pydebug.h>
55#endif
56
57/* A way to not give warnings about things that are declared, but might not
58 * be used like in-line helper functions in headers or static per module
59 * variables from headers.
60 */
61#ifdef __GNUC__
62#define NUITKA_MAY_BE_UNUSED __attribute__((__unused__))
63#else
64#define NUITKA_MAY_BE_UNUSED
65#endif
66
67// We are not following the 3.10 change to an inline function. At least
68// not immediately.
69#if PYTHON_VERSION >= 0x3a0 && PYTHON_VERSION < 0x3c0
70#undef Py_REFCNT
71#define Py_REFCNT(ob) (_PyObject_CAST(ob)->ob_refcnt)
72#endif
73
74// We are using this new macro on old code too.
75#ifndef Py_SET_REFCNT
76#define Py_SET_REFCNT(ob, refcnt) Py_REFCNT(ob) = refcnt
77#endif
78
79#if defined(_WIN32)
80// Windows is too difficult for API redefines.
81#define MIN_PYCORE_PYTHON_VERSION 0x380
82#else
83#define MIN_PYCORE_PYTHON_VERSION 0x371
84#endif
85
86#if PYTHON_VERSION >= MIN_PYCORE_PYTHON_VERSION
87#define NUITKA_USE_PYCORE_THREAD_STATE
88#endif
89
90#ifdef NUITKA_USE_PYCORE_THREAD_STATE
91#undef Py_BUILD_CORE
92#define Py_BUILD_CORE
93#undef _PyGC_FINALIZED
94
95#if PYTHON_VERSION < 0x380
96#undef Py_ATOMIC_H
97#include <pyatomic.h>
98#undef Py_INTERNAL_PYSTATE_H
99#include <internal/pystate.h>
100#undef Py_STATE_H
101#include <pystate.h>
102
103extern _PyRuntimeState _PyRuntime;
104#else
105
106#if PYTHON_VERSION >= 0x3c0
107#include <internal/pycore_runtime.h>
108#include <internal/pycore_typevarobject.h>
109
110static inline size_t Nuitka_static_builtin_index_get(PyTypeObject *self) { return (size_t)self->tp_subclasses - 1; }
111
112// Changed internal type access for Python3.13
113#if PYTHON_VERSION < 0x3d0
114#define managed_static_type_state static_builtin_state
115
116static inline managed_static_type_state *Nuitka_static_builtin_state_get(PyInterpreterState *interp,
117 PyTypeObject *self) {
118 return &(interp->types.builtins[Nuitka_static_builtin_index_get(self)]);
119}
120#else
121static inline managed_static_type_state *Nuitka_static_builtin_state_get(PyInterpreterState *interp,
122 PyTypeObject *self) {
123 return &(interp->types.builtins.initialized[Nuitka_static_builtin_index_get(self)]);
124}
125#endif
126
127NUITKA_MAY_BE_UNUSED static inline managed_static_type_state *Nuitka_PyStaticType_GetState(PyInterpreterState *interp,
128 PyTypeObject *self) {
129 assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
130 return Nuitka_static_builtin_state_get(interp, self);
131}
132
133#define _PyStaticType_GetState(interp, self) Nuitka_PyStaticType_GetState(interp, self)
134#endif
135
136#include <internal/pycore_pystate.h>
137#endif
138
139#if PYTHON_VERSION >= 0x390
140#include <internal/pycore_ceval.h>
141#include <internal/pycore_interp.h>
142#include <internal/pycore_runtime.h>
143#endif
144
145#if PYTHON_VERSION >= 0x380
146#include <cpython/initconfig.h>
147#include <internal/pycore_initconfig.h>
148#include <internal/pycore_pathconfig.h>
149#include <internal/pycore_pyerrors.h>
150#endif
151
152#if PYTHON_VERSION >= 0x3a0
153#include <internal/pycore_long.h>
154#include <internal/pycore_unionobject.h>
155#endif
156
157#if PYTHON_VERSION >= 0x3b0
158#include <internal/pycore_dict.h>
159#include <internal/pycore_frame.h>
160#include <internal/pycore_gc.h>
161#endif
162
163// Uncompiled generator integration requires these.
164#if PYTHON_VERSION >= 0x3b0
165#if PYTHON_VERSION >= 0x3d0
166#include <internal/pycore_opcode_utils.h>
167#include <opcode_ids.h>
168#else
169#include <internal/pycore_opcode.h>
170#endif
171// Clashes with our helper names.
172#undef CALL_FUNCTION
173#endif
174
175#if PYTHON_VERSION >= 0x3c0
176#include <cpython/code.h>
177#endif
178
179#if PYTHON_VERSION < 0x3c0
180// Make sure we go the really fast variant, spell-checker: ignore gilstate
181#undef PyThreadState_GET
182#define _PyThreadState_Current _PyRuntime.gilstate.tstate_current
183#define PyThreadState_GET() ((PyThreadState *)_Py_atomic_load_relaxed(&_PyThreadState_Current))
184#endif
185
186#if PYTHON_VERSION >= 0x380
187#undef _PyObject_LookupSpecial
188#include <internal/pycore_object.h>
189#else
190#include <objimpl.h>
191#endif
192
193#if PYTHON_VERSION >= 0x3d0
194#include <internal/pycore_critical_section.h>
195#include <internal/pycore_freelist.h>
196#include <internal/pycore_intrinsics.h>
197#include <internal/pycore_modsupport.h>
198#include <internal/pycore_parking_lot.h>
199#include <internal/pycore_pyatomic_ft_wrappers.h>
200#include <internal/pycore_setobject.h>
201#include <internal/pycore_time.h>
202#endif
203
204#undef Py_BUILD_CORE
205
206#endif
207
208#if defined(_MSC_VER)
209#pragma warning(pop)
210#endif
211
212/* See above. */
213#if PYTHON_VERSION < 0x300
214#undef initproc
215#undef initfunc
216#undef initstate
217#endif
218
219/* Type bool */
220#ifndef __cplusplus
221#include <stdbool.h>
222#endif
223
224/* Include the C header files most often used. */
225#include <stdio.h>
226
227#include "hedley.h"
228
229/* Use annotations for branch prediction. They still make sense as the L1
230 * cache space is saved.
231 */
232
233#define likely(x) HEDLEY_LIKELY(x)
234#define unlikely(x) HEDLEY_UNLIKELY(x)
235
236/* A way to indicate that a specific function won't return, so the C compiler
237 * can create better code.
238 */
239
240#define NUITKA_NO_RETURN HEDLEY_NO_RETURN
241
242/* This is used to indicate code control flows we know cannot happen. */
243#ifndef __NUITKA_NO_ASSERT__
244#define NUITKA_CANNOT_GET_HERE(NAME) \
245 PRINT_FORMAT("%s : %s\n", __FUNCTION__, #NAME); \
246 abort();
247#else
248#define NUITKA_CANNOT_GET_HERE(NAME) abort();
249#endif
250
251#define NUITKA_ERROR_EXIT(NAME) \
252 PRINT_FORMAT("%s : %s\n", __FUNCTION__, #NAME); \
253 abort();
254
255#if defined(_MSC_VER)
256/* Using "_alloca" extension due to MSVC restrictions for array variables
257 * on the local stack.
258 */
259#include <malloc.h>
260#define NUITKA_DYNAMIC_ARRAY_DECL(VARIABLE_NAME, ELEMENT_TYPE, COUNT) \
261 ELEMENT_TYPE *VARIABLE_NAME = (ELEMENT_TYPE *)_alloca(sizeof(ELEMENT_TYPE) * (COUNT));
262#else
263#define NUITKA_DYNAMIC_ARRAY_DECL(VARIABLE_NAME, ELEMENT_TYPE, COUNT) ELEMENT_TYPE VARIABLE_NAME[COUNT];
264#endif
265
266/* Python3 removed PyInt instead of renaming PyLong, and PyObject_Str instead
267 * of renaming PyObject_Unicode. Define this to be easily portable.
268 */
269#if PYTHON_VERSION >= 0x300
270#define PyInt_AsLong PyLong_AsLong
271#define PyInt_FromSsize_t PyLong_FromSsize_t
272
273#define PyNumber_Int PyNumber_Long
274
275#define PyObject_Unicode PyObject_Str
276
277#endif
278
279/* String handling that uses the proper version of strings for Python3 or not,
280 * which makes it easier to write portable code.
281 */
282#if PYTHON_VERSION < 0x300
283#define PyUnicode_GET_LENGTH(x) (PyUnicode_GET_SIZE(x))
284#define Nuitka_String_AsString PyString_AsString
285#define Nuitka_String_AsString_Unchecked PyString_AS_STRING
286#define Nuitka_String_Check PyString_Check
287#define Nuitka_String_CheckExact PyString_CheckExact
288NUITKA_MAY_BE_UNUSED static inline bool Nuitka_StringOrUnicode_CheckExact(PyObject *value) {
289 return PyString_CheckExact(value) || PyUnicode_CheckExact(value);
290}
291#define Nuitka_StringObject PyStringObject
292#define Nuitka_String_FromString PyString_FromString
293#define Nuitka_String_FromStringAndSize PyString_FromStringAndSize
294#define Nuitka_String_FromFormat PyString_FromFormat
295#define PyUnicode_CHECK_INTERNED (0)
296NUITKA_MAY_BE_UNUSED static Py_UNICODE *Nuitka_UnicodeAsWideString(PyObject *str, Py_ssize_t *size) {
297 PyObject *unicode;
298
299 if (!PyUnicode_Check(str)) {
300 // Leaking memory, but for usages its acceptable to
301 // achieve that the pointer remains valid.
302 unicode = PyObject_Unicode(str);
303 } else {
304 unicode = str;
305 }
306
307 if (size != NULL) {
308 *size = (Py_ssize_t)PyUnicode_GET_LENGTH(unicode);
309 }
310
311 return PyUnicode_AsUnicode(unicode);
312}
313#else
314#define Nuitka_String_AsString _PyUnicode_AsString
315
316// Note: This private stuff from file "Objects/unicodeobject.c"
317// spell-checker: ignore unicodeobject
318#define _PyUnicode_UTF8(op) (((PyCompactUnicodeObject *)(op))->utf8)
319#define PyUnicode_UTF8(op) \
320 (assert(PyUnicode_IS_READY(op)), \
321 PyUnicode_IS_COMPACT_ASCII(op) ? ((char *)((PyASCIIObject *)(op) + 1)) : _PyUnicode_UTF8(op))
322#ifdef __NUITKA_NO_ASSERT__
323#define Nuitka_String_AsString_Unchecked PyUnicode_UTF8
324#else
325NUITKA_MAY_BE_UNUSED static char const *Nuitka_String_AsString_Unchecked(PyObject *object) {
326 char const *result = PyUnicode_UTF8(object);
327 assert(result != NULL);
328 return result;
329}
330#endif
331#define Nuitka_String_Check PyUnicode_Check
332#define Nuitka_String_CheckExact PyUnicode_CheckExact
333#define Nuitka_StringOrUnicode_CheckExact PyUnicode_CheckExact
334#define Nuitka_StringObject PyUnicodeObject
335#define Nuitka_String_FromString PyUnicode_FromString
336#define Nuitka_String_FromStringAndSize PyUnicode_FromStringAndSize
337#define Nuitka_String_FromFormat PyUnicode_FromFormat
338#define Nuitka_UnicodeAsWideString PyUnicode_AsWideCharString
339#endif
340
341// Wrap the type lookup for debug mode, to identify errors, and potentially
342// to make our own enhancement later on. For now only verify it is not being
343// called with an error set, which 3.9 asserts against in core code.
344#ifdef __NUITKA_NO_ASSERT__
345#define Nuitka_TypeLookup(x, y) _PyType_Lookup(x, y)
346#else
347NUITKA_MAY_BE_UNUSED static PyObject *Nuitka_TypeLookup(PyTypeObject *type, PyObject *name) {
348 return _PyType_Lookup(type, name);
349}
350
351#endif
352
353/* With the idea to reduce the amount of exported symbols in the DLLs, make it
354 * clear that the module "init" function should of course be exported, but not
355 * for executable, where we call it ourselves from the main code.
356 */
357
358#if PYTHON_VERSION < 0x300
359#define NUITKA_MODULE_ENTRY_FUNCTION void
360#else
361#define NUITKA_MODULE_ENTRY_FUNCTION PyObject *
362#endif
363
364#if PYTHON_VERSION < 0x300
365typedef long Py_hash_t;
366#endif
367
368/* These two express if a directly called function should be exported (C level)
369 * or if it can be local to the file.
370 */
371#define NUITKA_CROSS_MODULE
372#define NUITKA_LOCAL_MODULE static
373
374/* Due to ABI issues, it seems that on Windows the symbols used by
375 * "_PyObject_GC_TRACK" were not exported before 3.8 and we need to use a
376 * function that does it instead.
377 *
378 * The Python 3.7.0 release on at Linux doesn't work this way either, was
379 * a bad CPython release apparently and between 3.7.3 and 3.7.4 these have
380 * become runtime incompatible.
381 */
382#if (defined(_WIN32) || defined(__MSYS__)) && PYTHON_VERSION < 0x380
383#define Nuitka_GC_Track PyObject_GC_Track
384#define Nuitka_GC_UnTrack PyObject_GC_UnTrack
385#undef _PyObject_GC_TRACK
386#undef _PyObject_GC_UNTRACK
387#elif PYTHON_VERSION == 0x370
388#define Nuitka_GC_Track PyObject_GC_Track
389#define Nuitka_GC_UnTrack PyObject_GC_UnTrack
390#undef _PyObject_GC_TRACK
391#undef _PyObject_GC_UNTRACK
392#elif _NUITKA_MODULE_MODE && PYTHON_VERSION >= 0x370 && PYTHON_VERSION < 0x380
393#define Nuitka_GC_Track PyObject_GC_Track
394#define Nuitka_GC_UnTrack PyObject_GC_UnTrack
395#undef _PyObject_GC_TRACK
396#undef _PyObject_GC_UNTRACK
397#undef PyThreadState_GET
398#define PyThreadState_GET PyThreadState_Get
399#else
400#define Nuitka_GC_Track _PyObject_GC_TRACK
401#define Nuitka_GC_UnTrack _PyObject_GC_UNTRACK
402#endif
403
404#if _NUITKA_EXPERIMENTAL_FAST_THREAD_GET && PYTHON_VERSION >= 0x300 && PYTHON_VERSION < 0x370
405// We are careful, access without locking under the assumption that we hold
406// the GIL over uses of this or the same thread continues to execute code of
407// ours.
408#undef PyThreadState_GET
409extern PyThreadState *_PyThreadState_Current;
410#define PyThreadState_GET() (_PyThreadState_Current)
411#endif
412
413#ifndef _NUITKA_FULL_COMPAT
414// Remove useless recursion control guards, except for testing mode, we do not
415// want them and we have no need for them as we are achieving deeper recursion
416// anyway.
417#undef Py_EnterRecursiveCall
418#define Py_EnterRecursiveCall(arg) (0)
419#undef Py_LeaveRecursiveCall
420#define Py_LeaveRecursiveCall()
421#endif
422
423#if PYTHON_VERSION < 0x300
424#define TP_RICHCOMPARE(t) (PyType_HasFeature((t), Py_TPFLAGS_HAVE_RICHCOMPARE) ? (t)->tp_richcompare : NULL)
425#else
426#define TP_RICHCOMPARE(t) ((t)->tp_richcompare)
427#endif
428
429// For older Python we need to define this ourselves.
430#ifndef Py_ABS
431#define Py_ABS(x) ((x) < 0 ? -(x) : (x))
432#endif
433
434#ifndef Py_MIN
435#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))
436#endif
437
438#ifndef Py_MAX
439#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y))
440#endif
441
442#ifndef Py_SET_SIZE
443#define Py_SET_SIZE(op, size) ((PyVarObject *)(op))->ob_size = size
444#endif
445
446#ifndef PyFloat_SET_DOUBLE
447#define PyFloat_SET_DOUBLE(op, value) ((PyFloatObject *)(op))->ob_fval = value
448#endif
449
450#ifndef Py_NewRef
451static inline PyObject *_Py_NewRef(PyObject *obj) {
452 Py_INCREF(obj);
453 return obj;
454}
455
456static inline PyObject *_Py_XNewRef(PyObject *obj) {
457 Py_XINCREF(obj);
458 return obj;
459}
460
461#define Py_NewRef(obj) _Py_NewRef((PyObject *)(obj))
462#define Py_XNewRef(obj) _Py_XNewRef((PyObject *)(obj))
463#endif
464
465// For older Python, we don't have a feature "CLASS" anymore, that's implied now.
466#if PYTHON_VERSION < 0x300
467#define NuitkaType_HasFeatureClass(descr) (PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))
468#else
469#define NuitkaType_HasFeatureClass(descr) (1)
470#endif
471
472// For pre-3.13, lets allow ourselves to use them as well, these do play
473// nice with no-GIL Python.
474#if PYTHON_VERSION < 0x3d0
475#define FT_ATOMIC_LOAD_PTR(value) value
476#define FT_ATOMIC_STORE_PTR(value, new_value) value = new_value
477#define FT_ATOMIC_LOAD_SSIZE(value) value
478#define FT_ATOMIC_LOAD_SSIZE_ACQUIRE(value) value
479#define FT_ATOMIC_LOAD_SSIZE_RELAXED(value) value
480#define FT_ATOMIC_STORE_PTR(value, new_value) value = new_value
481#define FT_ATOMIC_LOAD_PTR_ACQUIRE(value) value
482#define FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(value) value
483#define FT_ATOMIC_LOAD_PTR_RELAXED(value) value
484#define FT_ATOMIC_LOAD_UINT8(value) value
485#define FT_ATOMIC_STORE_UINT8(value, new_value) value = new_value
486#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) value
487#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) value
488#define FT_ATOMIC_LOAD_UINT32_RELAXED(value) value
489#define FT_ATOMIC_LOAD_ULONG_RELAXED(value) value
490#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value
491#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) value = new_value
492#define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) value = new_value
493#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value
494#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) value = new_value
495#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) value = new_value
496#define FT_ATOMIC_STORE_UINT32_RELAXED(value, new_value) value = new_value
497
498#define Py_BEGIN_CRITICAL_SECTION(mut) {
499#define Py_BEGIN_CRITICAL_SECTION2(m1, m2) {
500#define Py_BEGIN_CRITICAL_SECTION_MUT(mut) {
501#define Py_BEGIN_CRITICAL_SECTION2_MUT(m1, m2) {
502#define Py_END_CRITICAL_SECTION() }
503
504#define Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(original) {
505#define Py_END_CRITICAL_SECTION_SEQUENCE_FAST() }
506#define _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(mutex)
507#define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op)
508
509#endif
510
511// Our replacement for "PyType_IsSubtype"
512extern bool Nuitka_Type_IsSubtype(PyTypeObject *a, PyTypeObject *b);
513
514#include "nuitka/allocator.h"
515#include "nuitka/exceptions.h"
516
517// The digit types
518#if PYTHON_VERSION < 0x300
519#include <longintrepr.h>
520
521#if PYTHON_VERSION < 0x270
522// Not present in Python2.6 yet, spell-checker: ignore sdigit
523typedef signed int sdigit;
524#endif
525#endif
526
527// A long value that represents a signed digit on the helper interface.
528typedef long nuitka_digit;
529
530#include "nuitka/helpers.h"
531
532#include "nuitka/compiled_frame.h"
533
534#include "nuitka/compiled_cell.h"
535
536#include "nuitka/compiled_function.h"
537
538/* Sentinel PyObject to be used for all our call iterator endings. */
539extern PyObject *Nuitka_sentinel_value;
540
541/* Value to use for __compiled__ value of all modules. */
542extern PyObject *Nuitka_dunder_compiled_value;
543
544#include "nuitka/compiled_generator.h"
545
546#include "nuitka/compiled_method.h"
547
548#if PYTHON_VERSION >= 0x350
549#include "nuitka/compiled_coroutine.h"
550#endif
551
552#if PYTHON_VERSION >= 0x360
553#include "nuitka/compiled_asyncgen.h"
554#endif
555
556#include "nuitka/filesystem_paths.h"
557#include "nuitka/safe_string_ops.h"
558
559#include "nuitka/jit_sources.h"
560
561#if _NUITKA_EXPERIMENTAL_WRITEABLE_CONSTANTS
562#include "nuitka_data_decoder.h"
563#else
564#define DECODE(x) assert(x)
565#define UN_TRANSLATE(x) (x)
566#endif
567
568#if _NUITKA_EXPERIMENTAL_FILE_TRACING
569#include "nuitka_file_tracer.h"
570#else
571#if PYTHON_VERSION < 0x300
572#define TRACE_FILE_OPEN(tstate, x, y, z, r) (false)
573#else
574#define TRACE_FILE_OPEN(tstate, x, y, z, a, b, c, d, e, r) (false)
575#endif
576#define TRACE_FILE_READ(tstate, x, y) (false)
577
578#define TRACE_FILE_EXISTS(tstate, x, y) (false)
579#define TRACE_FILE_ISFILE(tstate, x, y) (false)
580#define TRACE_FILE_ISDIR(tstate, x, y) (false)
581
582#define TRACE_FILE_LISTDIR(tstate, x, y) (false)
583
584#define TRACE_FILE_STAT(tstate, x, y, z, r) (false)
585
586#endif
587
588#if _NUITKA_EXPERIMENTAL_INIT_PROGRAM
589#include "nuitka_init_program.h"
590#else
591#define NUITKA_INIT_PROGRAM_EARLY(argc, argv)
592#define NUITKA_INIT_PROGRAM_LATE(module_name)
593#endif
594
595#if _NUITKA_EXPERIMENTAL_EXIT_PROGRAM
596#include "nuitka_exit_program.h"
597#else
598#define NUITKA_FINALIZE_PROGRAM(tstate)
599#endif
600
601// Only Python3.9+ has a more precise check, while making the old one slow.
602#ifndef PyCFunction_CheckExact
603#define PyCFunction_CheckExact PyCFunction_Check
604#endif
605
606#ifdef _NUITKA_EXPERIMENTAL_DUMP_C_TRACEBACKS
607extern void INIT_C_BACKTRACES(void);
608extern void DUMP_C_BACKTRACE(void);
609#endif
610
611#endif
612
613// Part of "Nuitka", an optimizing Python compiler that is compatible and
614// integrates with CPython, but also works on its own.
615//
616// Licensed under the Apache License, Version 2.0 (the "License");
617// you may not use this file except in compliance with the License.
618// You may obtain a copy of the License at
619//
620// http://www.apache.org/licenses/LICENSE-2.0
621//
622// Unless required by applicable law or agreed to in writing, software
623// distributed under the License is distributed on an "AS IS" BASIS,
624// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
625// See the License for the specific language governing permissions and
626// limitations under the License.