* Fix ambiguous `str(handle)` constructor for object-derived types
Templatize `str(handle h)` with SFINAE to exclude types derived from
`object`, resolving ambiguity with `str(const object&)` when calling
`py::str()` on types like `kwargs`, `dict`, etc.
The template now only accepts `handle` or `PyObject*`, while all
`object`-derived types use the `str(const object&)` overload.
* fix(tests): CIBW test fixes from b-pass→vectorcall branch
- Install multiple-interpreter test modules into wheel (CMakeLists.txt)
The mod_per_interpreter_gil, mod_shared_interpreter_gil, and
mod_per_interpreter_gil_with_singleton modules were being built
but not installed into the wheel when using scikit-build-core.
- Pin numpy 2.4.0 for Python 3.14 CI tests (requirements.txt)
NumPy 2.4.0 is the first version with official Python 3.14 wheels.
- Add IOS platform constant to tests/env.py
- Skip subinterpreter tests on iOS (test_multiple_interpreters.py)
Subinterpreters are not supported in the iOS simulator environment.
- Enable pytest timeout of 120s for CIBW tests (pyproject.toml)
Provides a safety net to catch hanging tests before CI job timeout.
- Disable pytest-timeout for Pyodide (no signal.setitimer)
Pyodide runs in WebAssembly without POSIX signals.
- Add -v flag for verbose pytest output in CIBW tests
* Add per-interpreter storage for `gil_safe_call_once_and_store`
* Disable thread local cache for `internals_pp_manager`
* Disable thread local cache for `internals_pp_manager` for multi-interpreter only
* Use anonymous namespace to separate these type_ids from other tests with the same class names.
* style: pre-commit fixes
* Revert internals_pp_manager changes
* This is the crux of fix for the subinterpreter_before_main failure.
The pre_init needs to check if it is in a subinterpreter or not. But in 3.13+ this static initializer runs in the main interpreter. So we need to check this later, during the exec phase.
* Continue to do the ensure in both places, there might be a reason it was where it was...
Should not hurt anything to do it extra times here.
* Change get_num_interpreters_seen to a boolean flag instead.
The count was not used, it was just checked for > 1, we now accomplish this by setting the flag.
* Spelling typo
* Work around older python versions, only need this check for newish versions
* Add more comments for test case
* Add more comments for test case
* Stop traceback propagation
* Re-enable subinterpreter support on ubuntu 3.14 builds
Was disabled in e4873e8
* As suggested, don't use an anonymous namespace.
* Typo in test assert format string
* Use a more appropriate function name
* Fix mod_per_interpreter_gil* output directory on Windows/MSVC
On Windows with MSVC (multi-configuration generators), CMake uses
config-specific properties like LIBRARY_OUTPUT_DIRECTORY_DEBUG when
set, otherwise falls back to LIBRARY_OUTPUT_DIRECTORY/<Config>/.
The main test modules (pybind11_tests, etc.) correctly set both
LIBRARY_OUTPUT_DIRECTORY and the config-specific variants (lines
517-528), so they output directly to tests/.
However, the mod_per_interpreter_gil* modules only copied the base
LIBRARY_OUTPUT_DIRECTORY property, causing them to be placed in
tests/Debug/ instead of tests/.
This mismatch caused test_import_in_subinterpreter_concurrently and
related tests to fail with ModuleNotFoundError on Windows Python 3.14,
because the test code sets sys.path based on pybind11_tests.__file__
(which is in tests/) but tries to import mod_per_interpreter_gil_with_singleton
(which ended up in tests/Debug/).
This bug was previously masked by @pytest.mark.xfail decorators on
these tests. Now that the underlying "Duplicate C++ type registration"
issue is fixed and the xfails are removed, this path issue surfaced.
The fix mirrors the same pattern used for main test targets: also set
LIBRARY_OUTPUT_DIRECTORY_<CONFIG> for each configuration type.
* Remove unneeded `pytest.importorskip`
* Remove comment
---------
Co-authored-by: b-pass <b-pass@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
* Add new argument to `gil_safe_call_once_and_store::call_once_and_store_result`
* Add per-interpreter storage for `gil_safe_call_once_and_store`
* Make `~gil_safe_call_once_and_store` a no-op
* Fix C++11 compatibility
* Improve thread-safety and add default finalizer
* Try fix thread-safety
* Try fix thread-safety
* Add a warning comment
* Simplify `PYBIND11_INTERNALS_VERSION >= 12`
* Try fix thread-safety
* Try fix thread-safety
* Revert get_pp()
* Update comments
* Move call-once storage out of internals
* Revert internal version bump
* Cleanup outdated comments
* Move atomic_bool alias into pybind11::detail namespace
The `using atomic_bool = ...` declaration was at global scope,
polluting the global namespace. Move it into pybind11::detail
to avoid potential conflicts with user code.
* Add explicit #include <unordered_map> for subinterpreter support
The subinterpreter branch uses std::unordered_map but relied on
transitive includes. Add an explicit include for robustness.
* Remove extraneous semicolon after destructor definition
Style fix: remove trailing semicolon after ~call_once_storage()
destructor body.
* Add comment explaining unused finalize parameter
Clarify why the finalize callback parameter is intentionally ignored
when subinterpreter support is disabled: the storage is process-global
and leaked to avoid destructor calls after interpreter finalization.
* Add comment explaining error_scope usage
Clarify why error_scope is used: to preserve any existing Python
error state that might be cleared or modified by dict_getitemstringref.
* Improve exception safety in get_or_create_call_once_storage_map()
Use std::unique_ptr to hold the newly allocated storage map until
the capsule is successfully created. This prevents a memory leak
if capsule creation throws an exception.
* Add timeout-minutes: 3 to cpptest workflow steps
Add a 3-minute timeout to all C++ test (cpptest) steps across all
platforms to detect hangs early. This uses GitHub Actions' built-in
timeout-minutes property which works on Linux, macOS, and Windows.
* Add progress reporter for test_with_catch Catch2 runner
Add a custom Catch2 streaming reporter that prints one line per test
case as it starts and ends, with immediate flushing to keep CI logs
current. This makes it easy to see where the embedded/interpreter
tests are spending time and to pinpoint which test case is stuck
when builds hang (e.g., free-threading issues).
The reporter:
- Prints "[ RUN ]" when each test starts
- Prints "[ OK ]" or "[ FAILED ]" when each test ends
- Prints the Python version once at the start via Py_GetVersion()
- Uses StreamingReporterBase for immediate output (not buffered)
- Is set as the default reporter via CATCH_CONFIG_DEFAULT_REPORTER
This approach gives visibility into all tests without changing their
behavior, turning otherwise opaque 90-minute CI timeouts into
locatable issues in the Catch output.
* clang-format auto-fix (overlooked before)
* Disable "Move Subinterpreter" test on free-threaded Python 3.14+
This test hangs in Py_EndInterpreter() when the subinterpreter is
destroyed from a different thread than it was created on.
The hang was observed:
- Intermittently on macOS with Python 3.14.0t
- Predictably on macOS, Ubuntu, and Windows with Python 3.14.1t and 3.14.2t
Root cause analysis points to an interaction between pybind11's
subinterpreter creation code and CPython's free-threaded runtime,
specifically around PyThreadState_Swap() after PyThreadState_DeleteCurrent().
See detailed analysis: https://github.com/pybind/pybind11/pull/5933
* style: pre-commit fixes
* Add test for gil_safe_call_once_and_store per-interpreter isolation
This test verifies that gil_safe_call_once_and_store provides separate
storage for each interpreter when subinterpreter support is enabled.
The test caches the interpreter ID in the main interpreter, then creates
a subinterpreter and verifies it gets its own cached value (not the main
interpreter's). Without per-interpreter storage, the subinterpreter would
incorrectly see the main interpreter's cached object.
* Add STARTING/DONE timestamps to test_with_catch output
Print UTC timestamps at the beginning and end of the test run to make
it immediately clear when tests started and whether they ran to
completion. The DONE message includes the Catch session result value.
Example output:
[ STARTING ] 2025-12-21 03:23:20.497Z
[ PYTHON ] 3.14.2 ...
[ RUN ] Threads
[ OK ] Threads
[ DONE ] 2025-12-21 03:23:20.512Z (result 0)
* Disable stdout buffering in test_with_catch
Ensure test output appears immediately in CI logs by disabling stdout
buffering. Without this, output may be lost if the process is killed
by a timeout, making it difficult to diagnose which test was hanging.
* EXPERIMENT: Re-enable hanging test to verify CI log buffering fix
This is a temporary commit to verify that the unbuffered stdout fix
makes the hanging test visible in CI logs. REVERT THIS COMMIT after
confirming the output appears.
* Revert "Disable stdout buffering in test_with_catch"
This reverts commit 0f8f32a92a.
* Use USES_TERMINAL for cpptest to show output immediately
Ninja buffers subprocess output until completion. When a test hangs,
the output is never shown, making it impossible to diagnose which test
is hanging. USES_TERMINAL gives the command direct terminal access,
bypassing ninja's buffering.
This explains why Windows CI showed test progress but Linux/macOS did
not - Windows uses MSBuild which doesn't buffer the same way.
* Fix clang-tidy performance-avoid-endl warning
Use '\n' instead of std::endl since USES_TERMINAL now handles
output buffering at the CMake level.
* Add SIGTERM handler to show when test is killed by timeout
When a test hangs and is killed by `timeout`, Catch2 marks it as failed
but the process exits before printing [ DONE ]. This made it unclear
whether the test failed normally or was terminated.
The signal handler prints a clear message when SIGTERM is received,
making timeout-related failures obvious in CI logs.
* Fix typo: atleast -> at_least
* Fix GCC warn_unused_result error for write() in signal handler
Assign the return value to a variable to satisfy GCC's warn_unused_result
attribute, then cast to void to suppress unused variable warning.
* Add USES_TERMINAL to other C++ test targets
Apply the same ninja output buffering fix to test_cross_module_rtti
and test_pure_cpp targets. Also add explanatory comments to all
USES_TERMINAL usages.
* Revert "EXPERIMENT: Re-enable hanging test to verify CI log buffering fix"
This reverts commit a3abdeea89.
* Update comment to reference PR #5940 for Move Subinterpreter fix
* Add alias `interpid_t = std::int64_t`
* Add isolation and gc test for `gil_safe_call_once_and_store`
* Add thread local cache for gil_safe_call_once_and_store
* Revert "Add thread local cache for gil_safe_call_once_and_store"
This reverts commit 5d6681956d2d326fe74c7bf80e845c8e8ddb2a7c.
* Revert changes according to code review
* Relocate multiple-interpreters tests
* Add more tests for multiple interpreters
* Remove copy constructor
* Apply suggestions from code review
* Refactor to use per-storage capsule instead
* Update comments
* Update singleton tests
* Use interpreter id type for `get_num_interpreters_seen()`
* Suppress unused variable warning
* HACKING
* Revert "HACKING"
This reverts commit 534235ea55.
* Try fix concurrency
* Test even harder
* Reorg code to avoid duplicates
* Fix unique_ptr::reset -> unique_ptr::release
* Extract reusable functions
* Fix indentation
* Appease warnings for MSVC
* Appease warnings for MSVC
* Appease warnings for MSVC
* Try fix concurrency by not using `get_num_interpreters_seen() > 1`
* Try fix tests
* Make Python path handling more robust
* Update comments and assertion messages
* Revert changes according to code review
* Disable flaky tests
* Use `@pytest.mark.xfail` rather than `pytest.skip`
* Retrigger CI
* Retrigger CI
* Revert file moves
* Refactor atomic_get_or_create_in_state_dict: improve API and fix on_fetch_ bug
Three improvements to atomic_get_or_create_in_state_dict:
1. Return std::pair<Payload*, bool> instead of just Payload*
- The bool indicates whether storage was newly created (true) or
already existed (false), following std::map::insert convention.
- This fixes a bug where on_fetch_ was called even for newly created
internals, when it should only run for fetched (existing) ones.
(Identified by @b-pass in code review)
2. Change LeakOnInterpreterShutdown from template param to runtime arg
- Renamed to `clear_destructor` to describe what it does locally,
rather than embedding assumptions about why it's used.
- Reduces template instantiations (header-only library benefits).
- The check is in the slow path (create) anyway, so negligible cost.
3. Remove unnecessary braces around the fast-path lookup
- The braces created a nested scope but declared no local variables
that would benefit from scoping.
* Remove unused PYBIND11_MULTIPLE_INTERPRETERS_TEST_FILES variable
This variable was defined but never used.
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Remove skip for Move Subinterpreter test on free-threaded Python 3.14+
* Fix deadlock by detaching from the main interpreter before joining the thread.
* style: pre-commit fixes
---------
Co-authored-by: b-pass <b-pass@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Improve C++ test infrastructure and disable hanging test
This commit improves the C++ test infrastructure to ensure test output
is visible in CI logs, and disables a test that hangs on free-threaded
Python 3.14+.
Changes:
## CI/test infrastructure improvements
- .github/workflows: Added `timeout-minutes: 3` to all C++ test steps
to prevent indefinite hangs.
- tests/**/CMakeLists.txt: Added `USES_TERMINAL` to C++ test targets
(cpptest, test_cross_module_rtti, test_pure_cpp) to ensure output is
shown immediately rather than buffered and possibly lost on crash/timeout.
- tests/test_with_catch/catch.cpp: Added a custom Catch2 progress reporter
with timestamps, Python version info, and a SIGTERM handler to make test
execution and failures clearly visible in CI logs.
## Disabled hanging test
- The "Move Subinterpreter" test is disabled on free-threaded Python 3.14+
due to a hang in Py_EndInterpreter() when the subinterpreter is destroyed
from a different thread than it was created on. Work on fixing the
underlying issue will continue under PR #5940.
Context: We were in the dark for months (since we started testing with
Python 3.14t) because CI logs gave no clue about the root cause of hangs.
This led to ignoring intermittent hangs (mostly on macOS). Our hand was
forced only with the Python 3.14.1 release, when hangs became predictable
on all platforms.
For the full development history of these changes, see PR #5933.
* Add test summary to progress reporter
Print the total number of test cases and assertions at the end of the
test run, making it easy to spot if tests are disabled or added.
Example output:
[ PASSED ] 20 test cases, 1589 assertions.
* Add PYBIND11_CATCH2_SKIP_IF macro to skip tests at runtime
Catch2 v2 doesn't have native skip support (v3 does with SKIP()).
This macro allows tests to be skipped with a visible message while
still appearing in the test list.
Use this for the Move Subinterpreter test on free-threaded Python 3.14+
so it shows as skipped rather than being conditionally compiled out.
Example output:
[ RUN ] Move Subinterpreter
[ SKIPPED ] Skipped on free-threaded Python 3.14+ (see PR #5940)
[ OK ] Move Subinterpreter
* Fix clang-tidy bugprone-macro-parentheses warning in PYBIND11_CATCH2_SKIP_IF
* Limit busy-wait loops in per-subinterpreter GIL test
Add explicit timeouts to the busy-wait coordination loops in the
Per-Subinterpreter GIL test in tests/test_with_catch/test_subinterpreter.cpp.
Previously those loops spun indefinitely waiting for shared atomics like
`started` and `sync` to change, which is fine when CPython's free-threading
and per-interpreter GIL behavior matches the test's expectations but becomes
pathologically bad when that behavior regresses: the `test_with_catch`
executable can then hang forever, causing our 3.14t CI jobs to time out
after 90 minutes.
This change keeps the structure and intent of the test but adds a
std::chrono::steady_clock deadline to each of the coordination loops,
using a conservative 10 second bound. Worker threads record a failure and
return if they hit the timeout, while the main thread fails the test via
Catch2 instead of hanging. That way, if future CPython free-threading
patches change the semantics again, the test will fail quickly and
produced a diagnosable error instead of wedging the CI job.
* Revert "Limit busy-wait loops in per-subinterpreter GIL test"
This reverts commit 7847adacda.
* Add progress reporter for test_with_catch Catch runner
Introduce a custom Catch2 reporter for tests/test_with_catch that prints a
simple one-line status for each test case as it starts and ends, and wire the
cpptest CMake target to invoke test_with_catch with -r progress. This makes
it much easier to see where the embedded/interpreter test binary is spending
its time in CI logs, and in particular to pinpoint which test case is stuck
when the free-threading builds hang.
Compared to adding ad hoc timeouts around potentially infinite busy-wait
loops in individual tests, a progress reporter is a more general and robust
approach: it gives visibility into all tests (including future ones) without
changing their behavior, and turns otherwise opaque 90-minute timeouts into
locatable issues in the Catch output.
* Temporarily limit CI to Python 3.14t free-threading jobs
* Temporarily remove non-CI GitHub workflow files
* Temporarily disable AppVeyor builds via skip_commits
* Add DEBUG_LOOK in TEST_CASE("Move Subinterpreter")
* Add Python version banner to Catch progress reporter
Print the CPython version once at the start of the Catch-based
interpreter tests using Py_GetVersion(). This makes it trivial to
confirm which free-threaded build a failing run is using when
inspecting CI or local logs.
* Revert "Add DEBUG_LOOK in TEST_CASE("Move Subinterpreter")"
This reverts commit ad3e1c34ce.
* Pin CI free-threaded runs to CPython 3.14.0t
Update the standard-small and standard-large GitHub Actions jobs to
request python-version 3.14.0t instead of 3.14t. This forces setup-python
to use the last-known-good 3.14.0 free-threaded build rather than the
newer 3.14.1+ builds where subinterpreter finalization regressed.
* Revert "Pin CI free-threaded runs to CPython 3.14.0t"
This reverts commit 5281e1c20c.
* Revert "Temporarily disable AppVeyor builds via skip_commits"
This reverts commit ed11292636.
* Revert "Temporarily remove non-CI GitHub workflow files"
This reverts commit 0fe6a42a04.
* Revert "Temporarily limit CI to Python 3.14t free-threading jobs"
This reverts commit 60ae0e8f74.
* Pin CI free-threaded runs to CPython 3.14.0t
Update the standard-small and standard-large GitHub Actions jobs to
request python-version 3.14.0t instead of 3.14t. This forces setup-python
to use the last-known-good 3.14.0 free-threaded build rather than the
newer 3.14.1+ builds where subinterpreter finalization regressed.
* Switch NVHPC job to ubuntu-24.04 and disable AppVeyor
* Temporarily trim workflows to focus on NVHPC job
* First restore ci.yml from test-with-catch-timeouts branch, then delete all jobs except ubuntu-nvhpc7
* Change runner to ubuntu-24.04
* Use nvhpc-25-11
* Undo ALL changes relative to master (i.e. this branch is now an exact copy of master)
* Change runner to ubuntu-24.04
* Use nvhpc-25-11
* Remove misleading 7 from job name (i.e. ubuntu-nvhpc7 → ubuntu-nvhpc)
* Fix PyObject_HasAttrString return value
Signed-off-by: cyy <cyyever@outlook.com>
* Tidy unchecked files
Signed-off-by: cyy <cyyever@outlook.com>
* [skip ci] Handle PyObject_HasAttrString error when probing __notes__
PyObject_HasAttrString may return -1 to signal an error and set a
Python exception. The previous logic only checked for "!= 0", which
meant that the error path was treated the same as "attribute exists",
causing two problems: misreporting the presence of __notes__ and
leaving a spurious exception pending.
The earlier PR tightened the condition to "== 1" so that only a
successful lookup marks the error string as [WITH __notes__], but it
still left the -1 case unhandled. In the context of
error_fetch_and_normalize, we are already dealing with an active
exception and only want to best-effort detect whether normalization
attached any __notes__. If the attribute probe itself fails, we do not
want that secondary failure to affect later C-API calls or the error
we ultimately report.
This change stores the PyObject_HasAttrString return value, treats
"== 1" as "has __notes__", and explicitly calls PyErr_Clear() when
it returns -1. That way, we avoid leaking a secondary error while
still preserving the original exception information and hinting
[WITH __notes__] only when we can determine it reliably.
* Run clang-tidy with -DPYBIND11_HAS_SUBINTERPRETER_SUPPORT
* [skip ci] Revert "Run clang-tidy with -DPYBIND11_HAS_SUBINTERPRETER_SUPPORT"
This reverts commit bb6e751de4.
---------
Signed-off-by: cyy <cyyever@outlook.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
* adding windows arm test
- excluding numpy 2.2.0 for arm64 builds
* adding windows arm msys2 test
* testing mingw python
* unnamed namespace test on windows arm with clang and mingw
* Revert "unnamed namespace test on windows arm with clang and mingw"
This reverts commit 08abf889ae.
* bumping c++ version
* commenting out other tests
* Ignore unnmaed namespace on arm windows with mingw
- Updatig XFAIL condition to expect a failure on windows arm with
mingw and clang
- setting python home and path variables in c++ tests
* Revert "commenting out other tests"
This reverts commit dc75243963.
* removing windows-11-arm from big test, push
* removing redundant shell
* removing trailing whitespace
* Clarify Windows ARM clang job naming
Rename the Windows ARM clang jobs to windows_arm_clang_msvc and windows_arm_clang_msys2 and adjust their display names to clang-msvc / clang-msys2. The first runs clang against the MSVC/Windows SDK toolchain and python.org CPython for Windows ARM, while the second runs clang inside the MSYS2/MinGW-w64 CLANGARM64 environment with MSYS2 Python.
Using clearly distinguished job names makes it easier to discuss failures and behavior in each environment without ambiguity, both in logs and in PR review discussions.
* Reduce Windows ARM clang matrix size
Limit the windows_arm_clang_msvc job to Python 3.13 and the windows_arm_clang_msys2 job to Python 3.12 to stay within our constrained GitHub Actions resources. Keep both jobs using a matrix over os and python so their structure stays aligned and it remains easy to expand coverage when needed.
* Remove matrix.python from windows_arm_clang_msys2 job: the Python version is determined by the msys2/setup-msys2 action and cannot be changed
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
* Apply ruff/flake8-implicit-str-concat rule ISC003
ISC003 Explicitly concatenated string should be implicitly concatenated
* Enforce ruff/flake8-implicit-str-concat rules (ISC)
* Apply ruff/Perflint rule PERF102
PERF102 When using only the values of a dict use the `values()` method
* Apply ruff/Perflint rule PERF401
PERF401 Use a list comprehension to create a transformed list
* Enforce ruff/Perflint rules (PERF)
* [skip ci] Point main README.rst to CI for supported platforms and compilers
- **Replace** the hard-coded “Supported compilers” and “Supported platforms” lists in `README.rst`.
- **Point** readers to the current GitHub Actions matrix as the source of truth for tested platforms, compilers, and Python/C++ versions.
- **Clarify** that the matrix evolves over time and that configurations users care about can be kept working via contributions.
- **Avoid stale documentation**: Enumerating specific compiler and platform versions in the README is both burdensome and error-prone, and tends to drift out of sync with reality.
- **Align “supported” with “tested”**: In practice, the CI configuration is the only place where we can say with confidence which combinations are exercised. Nearby versions (e.g., adjacent compiler minor releases) will often work, but we cannot test every variant.
- **Reflect actual maintenance capacity**: pybind11 is maintained by a small, volunteer-based community, so support is necessarily best-effort. Pointing to CI and inviting contributions better matches how support is provided in practice.
- **No behavior change**: This PR updates documentation only.
- **Living source of truth**: As CI jobs are added or removed, the linked Actions view will automatically reflect the set of configurations we actively test. Keeping a configuration in CI is the best way to keep it “supported”.
* [skip ci] Slight rewording: point out GitHub's limits on concurrent jobs under the free tier (rather than free minutes).
* Remove enum from bold in doc
* [skip ci] Remove bold formatting around (see #5528)
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
* Don't allow keep_alive or call_guard on properties
The def_property family blindly ignore the keep_alive and call_guard arguments passed to them making them confusing to use.
This adds a static_assert if either is passed to make it clear it doesn't work.
I would prefer this to be a compiler warning but I can't find a way to do that. Is that even possible?
* style: pre-commit fixes
* Re-run tests
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Type hint make_tuple / fix *args/**kwargs return type
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* add back commented out panic
* ignore return std move clang
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* fix for mingmw
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* added missing case
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
---------
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
Since we already require pytest>=6 (see tests/requirements.txt), the
old compatibility function is obsolete and pytest.deprecated_call() can
be used directly.
Extracted from PR #5879
Co-authored-by: Michael Carlstrom <rmc@carlstrom.com>
Co-authored-by: gentlegiantJGC <gentlegiantJGC@users.noreply.github.com>
* Enhance: edit doc py::native_enum feature in upgrade.rst
Added information about the inclusion requirement for py::native_enum feature.
* [skip ci] Polish wording
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
* Add typing.SupportsIndex to int/float/complex type hints
This corrects a mistake where these types were supported but the type
hint was not updated to reflect that SupportsIndex objects are accepted.
To track the resulting test failures:
The output of
"$(cat PYROOT)"/bin/python3 $HOME/clone/pybind11_scons/run_tests.py $HOME/forked/pybind11 -v
is in
~/logs/pybind11_pr5879_scons_run_tests_v_log_2025-11-10+122217.txt
* Cursor auto-fixes (partial) plus pre-commit cleanup. 7 test failures left to do.
* Fix remaining test failures, partially done by cursor, partially manually.
* Cursor-generated commit: Added the Index() tests from PR 5879.
Summary:
Changes Made
1. **C++ Bindings** (`tests/test_builtin_casters.cpp`)
• Added complex_convert and complex_noconvert functions needed for the tests
2. **Python Tests** (`tests/test_builtin_casters.py`)
`test_float_convert`:
• Added Index class with __index__ returning -7
• Added Int class with __int__ returning -5
• Added test showing Index() works with convert mode: assert pytest.approx(convert(Index())) == -7.0
• Added test showing Index() doesn't work with noconvert mode: requires_conversion(Index())
• Added additional assertions for int literals and Int() class
`test_complex_cast`:
• Expanded the test to include convert and noconvert functionality
• Added Index, Complex, Float, and Int classes
• Added test showing Index() works with convert mode: assert convert(Index()) == 1 and assert isinstance(convert(Index()), complex)
• Added test showing Index() doesn't work with noconvert mode: requires_conversion(Index())
• Added type hint assertions matching the SupportsIndex additions
These tests demonstrate that custom __index__ objects work with float and complex in convert mode, matching the typing.SupportsIndex type hint added in PR
5891.
* Reflect behavior changes going back from PR 5879 to master. This diff will have to be reapplied under PR 5879.
* Add PyPy-specific __index__ handling for complex caster
Extract PyPy-specific __index__ backporting from PR 5879 to fix PyPy 3.10
test failures in PR 5891. This adds:
1. PYBIND11_INDEX_CHECK macro in detail/common.h:
- Uses PyIndex_Check on CPython
- Uses hasattr check on PyPy (workaround for PyPy 7.3.3 behavior)
2. PyPy-specific __index__ handling in complex.h:
- Handles __index__ objects on PyPy 7.3.7's 3.8 which doesn't
implement PyLong_*'s __index__ calls
- Mirrors the logic used in numeric_caster for ints and floats
This backports __index__ handling for PyPy, matching the approach
used in PR 5879's expand-float-strict branch.
* Centralize readable function signatures to avoid duplication
This seems to reduce size costs of adding enum_-specific implementations of dunder methods, but also should provide a nice to have size optimization for programs that use pybind11 in general.
* gate disabling of -Wdeprecated-redundant-constexpr-static-def to clang 17+
* fix gating to include Apple Clang 15
* Make GCC happy with types
* fix apple clang gating again. suppress -Wdeprecated for GCC
* Gate warning suppressions to C++17. Suppress -Wdeprecated for clang as well.
* hopefully fix last straggler CI job
* attempt to address readability review feedback from @rwgk
* drop warning suppressions and instead just gate compilation the pre-C++17 compat code
* type_caster_generic: fix compiler error when casting a T that is implicitly convertible from T*
* style: pre-commit fixes
* Placate clang-tidy
* Expand NOLINT to specify Clang-Tidy check names
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
* Fix dangling pointer in internals::registered_types_cpp_fast from #5842
@oremanj pointed out in a comment on #5842 that I missed part
of the nanobind PR I was porting in such a way that we could have
dangling pointers in internals::registered_types_cpp_fast. This PR
adds a test that reproed the bug and then fixes the test.
* review feedback, attempt to fix -Werror in CI
* use const ref, skip test on python 3.13 free-threaded
* Skip test on 3.13t more robustly
* style: pre-commit fixes
* CI fix
---------
Co-authored-by: Joshua Oreman <oremanj@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Fixes potential thread-safety issues if types are concurrently
registered while `get_local_type_info()` is called in free threaded
Python.
Use the `internals` mutex to also protect `local_internals`. This
keeps the locking strategy simpler, and we already follow this pattern
in some places, such as `pybind11_meta_dealloc`.
* Add fast_type_map, use it authoritatively for local types and as a hint for global types
nanobind has a similar two-level lookup strategy, added and explained
by
b515b1f7f2
In this PR I've ported this approach to pybind11. To avoid an ABI
break, I've kept the fast maps to the `local_internals`. I think this
should be safe because any particular module should see its
`local_internals` reset at least as often as the global `internals`,
and misses in the fast "hint" map for global types fall back to the
global `internals`.
Performance seems to have improved. Using my patched fork of
pybind11_benchmark
(https://github.com/swolchok/pybind11_benchmark/tree/benchmark-updates,
specifically commit hash b6613d12607104d547b1c10a8145d1b3e9937266), I
run bench.py and observe the MyInt case. Each time, I do 3 runs and
just report all 3.
master, Mac: 75.9, 76.9, 75.3 nsec/loop
this PR, Mac: 73.8, 73.8, 73.6 nsec/loop
master, Linux box: 188, 187, 188 nsec/loop
this PR, Linux box: 164, 165, 164 nsec/loop
Note that the "real" percentage improvement is larger than implied by the
above because master does not yet include #5824.
* simplify unsafe_reset_local_internals in test
* pre-implement PYBIND11_INTERNALS_VERSION 12
* use PYBIND11_INTERNALS_VERSION 12 on Python 3.14 per suggestion
* Implement reviewer comments: revert PY_VERSION_HEX change, fix REVIEW comment, add two-level lookup comments. ci.yml coming separately
* Use the inplace build to smoke test ABI bump?
* [skip ci] Remove "smoke" from comment. This is full testing, just only on a few platforms.
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
* Use new 3.14 C APIs when available
Use the new "unstable" C APIs for the functions added in #5494.
* style: pre-commit fixes
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* ChatGPT-generated diamond virtual-inheritance test case.
* Report "virtual base at offset 0" but don't skip test.
* Remove Left/Right virtual default dtors, to resolve clang-tidy errors:
```
/__w/pybind11/pybind11/tests/test_class_sh_mi_thunks.cpp:44:13: error: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override,-warnings-as-errors]
44 | virtual ~Left() = default;
| ~~~~~~~ ^
| override
/__w/pybind11/pybind11/tests/test_class_sh_mi_thunks.cpp:48:13: error: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override,-warnings-as-errors]
48 | virtual ~Right() = default;
| ~~~~~~~ ^
| override
```
* Add assert(ptr) in register_instance_impl, deregister_instance_impl
* Proper bug fix
* Also exercise smart_holder_from_unique_ptr
* [skip ci] ChatGPT-generated bug fix: smart_holder::from_unique_ptr()
* Exception-safe ownership transfer from unique_ptr to shared_ptr
ChatGPT:
* shared_ptr’s ctor can throw (control-block alloc). Using get() keeps unique_ptr owning the memory if that happens, so no leak.
* Only after the shared_ptr is successfully constructed do you release(), transferring ownership exactly once.
* [skip ci] Rename alias_ptr to mi_subobject_ptr to distinguish from trampoline code (which often uses the term "alias", too)
* [skip ci] Also exercise smart_holder::from_raw_ptr_take_ownership
* [skip ci] Add st.first comments (generated by ChatGPT)
* [skip ci] Copy and extend (raw_ptr, unique_ptr) reproducer from PR #5796
* Some polishing: comments, add back Left/Right dtors for consistency within test_class_sh_mi_thunks.cpp
* explicitly default copy/move for VBase to silence -Wdeprecated-copy-with-dtor
* Resolve clang-tidy error:
```
/__w/pybind11/pybind11/tests/test_class_sh_mi_thunks.cpp:67:5: error: 'auto ptr' can be declared as 'auto *ptr' [readability-qualified-auto,-warnings-as-errors]
67 | auto ptr = new Diamond;
| ^~~~
| auto *
```
* Expand comment in `smart_holder::from_unique_ptr()`
* Better Left/Right padding to make it more likely that we avoid "all at offset 0". Clarify comment.
* Give up on `alignas(16)` to resolve MSVC warning:
```
"D:\a\pybind11\pybind11\build\ALL_BUILD.vcxproj" (default target) (1) ->
"D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj" (default target) (13) ->
(ClCompile target) ->
D:\a\pybind11\pybind11\tests\test_class_sh_mi_thunks.cpp(70,17): warning C4316: 'test_class_sh_mi_thunks::Diamond': object allocated on the heap may not be aligned 16 [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
D:\a\pybind11\pybind11\tests\test_class_sh_mi_thunks.cpp(80,43): warning C4316: 'test_class_sh_mi_thunks::Diamond': object allocated on the heap may not be aligned 16 [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\memory(2913,46): warning C4316: 'std::_Ref_count_obj2<_Ty>': object allocated on the heap may not be aligned 16 [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\memory(2913,46): warning C4316: with [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\memory(2913,46): warning C4316: [ [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\memory(2913,46): warning C4316: _Ty=test_class_sh_mi_thunks::Diamond [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.44.35207\include\memory(2913,46): warning C4316: ] [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
D:\a\pybind11\pybind11\include\pybind11\detail\init.h(77,21): warning C4316: 'test_class_sh_mi_thunks::Diamond': object allocated on the heap may not be aligned 16 [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
```
The warning came from alignas(16) making Diamond over-aligned, while regular new/make_shared aren’t guaranteed to return 16-byte aligned memory on MSVC (hence C4316). I’ve removed the explicit alignment and switched to asymmetric payload sizes (char[4] vs char[24]), which still nudges MI layout without relying on over-alignment. This keeps the test goal and eliminates the warning across all MSVC builds. If we ever want to stress over-alignment explicitly, we can add aligned operator new/delete under __cpp_aligned_new, but that’s more than we need here.
* Rename test_virtual_base_at_offset_0() → test_virtual_base_not_at_offset_0() and replace pytest.skip() with assert. Add helpful comment for future maintainers.
Python may leave behind temporary `.pyc.*` files inside `__pycache__`
on some filesystems (e.g. WSL2 mounts). Adding `__pycache__/` ensures
these directories and any leftover files are consistently ignored.
Background: Python writes bytecode to a temp file with an extra suffix
before renaming it to `.pyc`. If the process is interrupted or the
filesystem rename isn’t fully atomic, those temp files may remain.
See: https://docs.python.org/3/library/py_compile.html#py_compile.compile
Occasionally a test will get stuck and run for 6 hours until Github cancels the workflow.
This reduces the timeout to 90 minutes to not waste resources.
Pybind11's tests seem to run in 30 minutes so this should be plenty of time.
* Revert type hint changes to int_ and float_
These two types do not support casting from int-like and float-like types.
* Fix tests
* Add a custom py::float_ caster
The default py::object caster only works if the object is an instance of the type.
py::float_ should accept python int objects as well as float.
This caster will pass through float as usual and cast int to float.
The caster handles the type name so the custom one is not required.
* style: pre-commit fixes
* Fix name
* Fix variable
* Try satisfying the formatter
* Rename test function
* Simplify type caster
* Fix reference counting issue
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>