Python.h now also includes <string.h> in the limited C API version 3.11
and newer to fix the Py_CLEAR() macro which uses memcpy().
Add a Py_CLEAR() test in test_cext.
Modify also _Py_TYPEOF to use C23 typeof() if available.
Remove spurious Py_DECREF on borrowed ref in LOAD_GLOBAL specialization
_PyDict_LookupIndexAndValue() returns a borrowed reference via
_Py_dict_lookup(), but specialize_load_global_lock_held() called
Py_DECREF(value) on it when bailing out for lazy imports. Each time
the adaptive counter fired while a lazy import was still in globals,
this stole one reference from the dict's object. With 8+ threads
racing through LOAD_GLOBAL during concurrent lazy import resolution,
enough triggers accumulated to drive the refcount to zero while the
dict and other threads still referenced the object, causing
use-after-free.
Don't test internal header files including mimalloc on macOS since
mimalloc emits compiler warnings:
In file included from extension.cpp:21:
In file included from Include/internal/pycore_backoff.h:15:
In file included from Include/internal/pycore_interp_structs.h:15:
In file included from Include/internal/pycore_tstate.h:14:
In file included from Include/internal/pycore_mimalloc.h:43:
Include/internal/mimalloc/mimalloc.h:464:85: error: defaulted
function definitions are a C++11 extension
[-Werror,-Wc++11-extensions]
mi_stl_allocator() mi_attr_noexcept = default;
^
Include/internal/mimalloc/mimalloc.h:465:85: error: defaulted
function definitions are a C++11 extension
[-Werror,-Wc++11-extensions]
mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept = default;
Log also CXX and CXXFLAGS env vars in test_cppext. Log also CPPFLAGS
in test_cext.
Fix a race condition where a thread could receive a partially-initialized
module when another thread's import fails. The race occurs when:
1. Thread 1 starts importing, adds module to sys.modules
2. Thread 2 sees the module in sys.modules via the fast path
3. Thread 1's import fails, removes module from sys.modules
4. Thread 2 returns a stale module reference not in sys.modules
The fix adds verification after the "skip lock" optimization in both Python
and C code paths to check if the module is still in sys.modules. If the
module was removed (due to import failure), we retry the import so the
caller receives the actual exception from the import failure rather than
a stale module reference.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add an example showing how to use str.translate() with a dictionary
mapping directly, demonstrating character replacement and deletion.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
When _ctypes is imported, it may call dlopen on the libpython shared
library, causing the dynamic linker to load a second mapping of the
library into the process address space. The remote debugging code
iterates memory regions from low addresses upward and returns the first
mapping whose filename matches libpython. After _ctypes is imported, it
finds the dlopen'd copy first, but that copy's PyRuntime section was
never initialized, so reading debug offsets from it fails.
Fix this by validating each candidate PyRuntime address before accepting
it. The validation reads the first 8 bytes and checks for the "xdebugpy"
cookie that is only present in an initialized PyRuntime. Uninitialized
duplicate mappings will fail this check and be skipped, allowing the
search to continue to the real, initialized PyRuntime.
Changing the values requires forking and patching, which is intentional. Simply rebuilding from source does not change the implementation enough to justify changing these values - they would still be `cpython` and compatible with existing `.pyc` files. But people who maintain forks are better served by being able to easily override these values in a place that can be forward-ported reliably.