* docs: add 3.1 entries to the changelog
Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
* chore: prepare 3.1.0 release
Assisted-by: ClaudeCode:claude-opus-5
* [skip ci] Change release date to August 4, 2026
* docs: add #6127 entry and set release date to August 6, 2026
Assisted-by: ClaudeCode:claude-opus-5
---------
Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
* chore(deps): update pre-commit hooks
updates:
- [github.com/pre-commit/mirrors-clang-format: v22.1.5 → v22.1.8](https://github.com/pre-commit/mirrors-clang-format/compare/v22.1.5...v22.1.8)
- [github.com/astral-sh/ruff-pre-commit: v0.15.20 → v0.16.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.20...v0.16.1)
- [github.com/pre-commit/mirrors-mypy: v2.1.0 → v2.3.0](https://github.com/pre-commit/mirrors-mypy/compare/v2.1.0...v2.3.0)
- [github.com/codespell-project/codespell: v2.4.2 → v2.4.3](https://github.com/codespell-project/codespell/compare/v2.4.2...v2.4.3)
* style: pre-commit fixes
* fix: adapt to the ruff 0.16 default rule set
The hook update pulled in ruff 0.16, which expanded its default rules and
autofixed `self: S -> S` to `-> Self`. That fix added a runtime
`typing_extensions` import to setup_helpers.py, which must stay
dependency-free; it broke every test job whose environment does not supply
that package. The import is now guarded by TYPE_CHECKING.
Also replace the `exec` in docs/conf.py with an importlib module load,
parenthesize implicit string concatenations in list literals, mark unused
unpacked variables with a leading underscore, and make noxfile.py
executable to match its shebang.
The remaining new rules are silenced per-file, with reasons: the chrono
tests check naive local time on purpose, and the other rules conflict with
how the tests are written.
Assisted-by: ClaudeCode:claude-opus-5
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <henryfs@princeton.edu>
* feat!: drop support for Python 3.8
The minimum supported version is now Python 3.9. pybind11 v3.0 was the last
release that supports Python 3.8. The deprecation note said that support goes
away in 3.1.
Remove the code paths that this makes dead:
- the `_PyObject_Vectorcall` fallback in `cast.h`
- the `frame->f_code` and `frame->f_back` fallbacks in `pytypes.h`
- the `PyFrame_FastToLocals` path in `get_type_override`
- the conditional `Py_VISIT(Py_TYPE(self))` in `tp_traverse`
- `PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX`, the pre-PyConfig interpreter
init, and the `widen_chars` helpers in `embed.h`
Assisted-by: ClaudeCode:claude-opus-5
* ci(appveyor): use Python 3.9
The AppVeyor job set `PYTHON: 38`, which makes the path `C:\Python38`.
The image gives Python 3.9.13 as `C:\Python39`.
Assisted-by: ClaudeCode:claude-opus-5
* feat!: require MSVC 2019 or newer
Python 3.9 is the new minimum, so MSVC 2017 is no longer needed. Raise the
compile-time floor to _MSC_VER 1920 and remove the workarounds that only
applied below it: std::launder, fold expressions, weak_from_this, aligned
new/delete, the C4100 warning helper, and the func_handle syntax error.
AppVeyor now builds with Visual Studio 2019.
Assisted-by: ClaudeCode:claude-opus-5
* fix(appveyor): build against the Python that has the test packages
CMake 4 has no FindPythonLibs, so pybind11 uses FindPython. FindPython reads
the registry before PATH and selected `C:\Python314-x64`, but the test packages
go into the Python on PATH. Pass `Python_ROOT_DIR` to name the correct one.
Also set `CMAKE_ARCH`. It was never set, so the architecture came from the
generator. Visual Studio 2017 defaults to Win32, but Visual Studio 2019
defaults to x64, which made this x86 job build 64-bit code.
Assisted-by: ClaudeCode:claude-opus-5
* fix(appveyor): give the linker Python's libs directory
The build compiled but failed to link with LNK1104 on a bare `python39.lib`.
That name comes from the `#pragma comment(lib, ...)` in pyconfig.h, so the
linker needs the directory. CMake 4 has no FindPythonLibs, and FindPython does
not add it for this Debug x86 build. Put it on LIB instead.
The directory listing is temporary, to confirm the library is present.
Assisted-by: ClaudeCode:claude-opus-5
* fix(appveyor): link the release Python library in Debug
The image ships python39_d.lib next to python39.lib, so FindPython picks the
debug import library for a Debug build. pybind11 undefines _DEBUG around
Python.h, so pyconfig.h asks for python39.lib instead and the link failed with
LNK1104. Name the release library for the debug slot.
Setting LIB does not work, because MSBuild replaces it from the toolset, and it
would link both import libraries.
Assisted-by: ClaudeCode:claude-opus-5
* chore(appveyor): print link settings to debug LNK1104
Revert the two attempted fixes. Neither changed the failure: setting LIB does
not survive MSBuild, and naming the release library for Python_LIBRARY_DEBUG
had no effect.
Print the Python cache entries and the link settings of a generated project
file instead, to see what the linker really gets. Temporary.
Assisted-by: ClaudeCode:claude-opus-5
* fix(appveyor): take the release Python library in Debug
The generated project file linked C:\Python39\libs\python39_d.lib in the Debug
configuration, because the image ships debug binaries next to the release ones.
pybind11 undefines _DEBUG around Python.h, so pyconfig.h asks for python39.lib
in a #pragma comment(lib), which nothing on the link line satisfies and no
library directory holds. Map Debug to the release artifacts.
Assisted-by: ClaudeCode:claude-opus-5
* chore(appveyor): drop the temporary link diagnostic
Assisted-by: ClaudeCode:claude-opus-5
* fix(tests): guard the unraisable warning filter for pytest < 6
The distro pytest in the Clang and GCC Docker jobs has no
PytestUnraisableExceptionWarning, so an unconditional filterwarnings
mark makes pytest fail with an INTERNALERROR after the tests pass.
Assisted-by: ClaudeCode:claude-opus-5
Claude-Session: https://claude.ai/code/session_01Aimf6HuSz1vLRwBnbxmCTc
* docs: address review items on version hints, embed docs, and a PyPy xfail
Extend Python_ADDITIONAL_VERSIONS through 3.15, describe the PyConfig
behavior of initialize_interpreter, and drop the stale Python 3.8 wording
from the PyPy xfail reason.
Assisted-by: ClaudeCode:claude-opus-5
* Update README.rst
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
* feat: small command line helpers for quick tests
Add --cflags, --ldflags, --embed, and --file to the pybind11 command
line tool, based on python-config. This makes quick one-off compiles
easy:
c++ $(python3 -m pybind11 --file=example.cpp)
Assisted-by: ClaudeCode:claude-fable-5
* refactor: quote paths, clarify CLI output logic, strengthen tests
- Quote include and library dirs in get_cflags/get_ldflags so paths with
spaces work, sharing one quote helper in commands.py
- Restructure the --file/--cflags/--ldflags printing into a single print
- Note the Unix-compiler orientation in help text and docs
- Test -L presence for --embed and quoting of paths with spaces
Assisted-by: ClaudeCode:claude-fable-5
* refactor: simplify flag helpers and keep import pybind11 light
- Replace _get_config_var(name, fmt, quote) with a plain _config(name)
string helper; formatting and quoting happen at the call sites
- Defer sysconfig/shlex imports so import pybind11 does not pay for the
CLI (~1ms -> ~0.08ms for pybind11.commands)
- Fetch EXT_SUFFIX once in main()
- Import commands normally in the quoting test instead of importlib
file loading
Assisted-by: ClaudeCode:claude-fable-5
* fix: shared-library flags on all Unix platforms
The --file/--ldflags output only added -shared and -fPIC on Linux, so
other Unix platforms (FreeBSD, Solaris, AIX) linked an executable and
failed on the missing main. Gate on os.name instead.
Assisted-by: ClaudeCode:claude-opus-5
* revert: "revert: add life support to handles cast to string_view (#6092)"
This re-applies #6092 (reverting #6097) so the follow-up fixes in this PR can build on it.
Assisted-by: ClaudeCode:claude-opus-4.8
* fix: don't throw from string_view life support outside a bound function
PR #6092 added loader_life_support::add_patient(src) to keep the source
object alive when loading a string view, fixing a real use-after-free when
a container of views is built from a non-sequence iterable (e.g. a
generator): list_caster materializes a temporary tuple that owns the
strings and destroys it when load() returns, before the bound function
body runs.
add_patient throws when there is no life support frame, so casting to a
view outside a bound function (e.g. a manual py::cast<std::string_view>)
now raises instead of relying on the caller-owned source, a regression
from #6092.
For these view-into-src cases registration is best effort: inside a bound
function it keeps src alive (fixing the UAF), and outside one the caller
owns src's lifetime as before. Add try_add_patient(), which returns false
instead of throwing when there is no frame, and use it at the three view
load sites. add_patient() keeps its strict contract for value-creating
conversions.
Assisted-by: ClaudeCode:claude-opus-4.8
* fix: only add string_view life support for transient sources
Refine the previous commit. Best-effort registration (try_add_patient)
silently produces a dangling view when a container of views is built from
a generator outside a bound function: there the materialized temporary is
released before the view is used, and with no frame nothing keeps it
alive. Such a cast cannot be made safe, so it should fail loudly, while a
view into a durable, caller-owned object needs no life support at all.
The view caster cannot tell a durable source from a pybind11-managed
transient one; that provenance lives in the container caster. Introduce an
ambient transient_source_guard that the list, set, map, and array casters
set around their generator/materialized paths, and have the string caster
keep the source alive only when loading from a transient source (via the
throwing add_patient, so try_add_patient is no longer needed). This means:
- views into durable sources (direct arguments, sequences, manual casts)
add no life support and no longer throw outside a bound function, and
- a generator used outside a frame throws, rather than silently dangling.
The guard restores (rather than clears) the previous value, so a durable
container nested in a transient one is correctly treated as transient.
Verified with AddressSanitizer: the in-frame generator case is clean, the
out-of-frame durable cases succeed, and the out-of-frame generator case
throws.
Assisted-by: ClaudeCode:claude-opus-4.8
* Revert "fix: only add string_view life support for transient sources"
This reverts commit e18b8346a2.
* test: cover string_view argument life support
* test: cover generated and nested string_view lifetimes
* test: cover temporary-backed string_view casts
* test: explain string_view lifetime regression tests
* docs: clarify string_view lifetime requirements
* docs: explain life support for custom view casters
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
* feat(subinterpreter): add opt-in TLS-cached thread state mode
subinterpreter_scoped_activate previously created and destroyed a fresh
PyThreadState on every activation when the calling OS thread was not
already running the target interpreter. Workloads that repeatedly
re-enter the same sub-interpreter from the same thread therefore churn
thread states and lose per-thread interpreter state between activations
(see pybind/pybind11#6040).
Add an opt-in subinterpreter_thread_state::cached policy: on first use a
PyThreadState is created and stored in OS-thread-local storage keyed by
the target interpreter; subsequent activations on that thread only swap
it in/out and never destroy it. The default stays transient, so existing
behavior is unchanged.
Since pybind11 does not control thread lifetime, cleanup is explicit:
subinterpreter::release_cached_thread_state() releases the calling
thread's cached state for one interpreter, and the static
release_all_cached_thread_states() releases all of the calling thread's
cached states as an end-of-thread hook. The TLS map's destructor only
frees its own nodes and never touches the Python C API, so an
unreleased state leaks rather than crashing at thread exit.
Includes test coverage and embedding docs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* style: pre-commit fixes
* refactor(subinterpreter): replace cached enum/TLS with subinterpreter_thread_state RAII
Address review feedback on the original "cached" mode by switching to an
explicit two-RAII design suggested by @b-pass:
"Create a class ... to RAII-manage the PyThreadState but start its
lifetime in an already released state. You could create another
class (or modify scoped_activate) to scoped/RAII activate the
inactive threadstate."
Removed
- enum subinterpreter_thread_state { transient, cached } and the
defaulted ctor parameter on subinterpreter_scoped_activate.
- detail::subinterpreter_thread_state_cache thread_local map.
- subinterpreter::release_cached_thread_state() and
subinterpreter::release_all_cached_thread_states().
This eliminates: the hidden per-thread map, the "release_all" footgun
across pybind11 modules (the cache was module-local), and the implicit
"must not be active when called" contract on the release functions.
Added
- Public class subinterpreter_thread_state that owns one PyThreadState
for a given subinterpreter on its constructing OS thread, created in
a released state (not current, no GIL). Non-copyable, non-movable
(PyThreadState is bound to its creating OS thread).
- subinterpreter_scoped_activate(subinterpreter_thread_state &)
overload: swaps the owned PyThreadState in on entry, swaps it out
on exit, does not touch its lifetime.
Behavior
- The existing subinterpreter_scoped_activate(subinterpreter const &)
overload is unchanged (still transient: New on entry, Delete on
exit). All previously-working code keeps working.
- With subinterpreter_thread_state, one OS thread can alternate
between multiple subinterpreters and each PyThreadState is preserved
across activations -- the use case that gil_scoped_release/acquire
+ a long-lived scoped_activate cannot solve alone (the per-thread
internals.tstate slot holds only one inactive tstate).
- The dtor of subinterpreter_thread_state guards against the
"destroyed-while-active" contract violation: if Swap reveals the
cached tstate was current, do not Swap back to a now-deleted
pointer (the safe-when-active fix b-pass requested for the old
release_* functions, applied at the natural location instead).
Lifetime contract is enforced by ordinary C++ scope: typical placement
is `thread_local`. No new release/cleanup APIs are required.
Tests cover (a) tstate identity preserved across activations on a
thread, (b) transient and reusing modes do not share state, (c)
different OS threads get distinct PyThreadStates, and (d) the
multi-subinterpreter alternation case.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(subinterpreter): address review on #6073 (same-thread checks, test scoping)
Per @b-pass's review:
- ~subinterpreter_thread_state(): add a PYBIND11_DETAILED_ERROR_MESSAGES-
guarded check that destruction happens on the OS thread that created the
PyThreadState (same PyThread_get_thread_native_id pattern as ~subinterpreter),
failing with pybind11_fail otherwise.
- subinterpreter_scoped_activate(subinterpreter_thread_state &): add the
matching DETAILED_ERROR_MESSAGES check that activation happens on the
creating OS thread, enforcing the newly documented rule.
- docs: document that activating a subinterpreter_thread_state on another OS
thread is illegal.
- tests: keep each subinterpreter (and its subinterpreter_thread_state) in an
enclosing scope so destruction order is thread-state -> subinterpreter ->
unsafe_reset_internals_for_single_interpreter(). The previous top-level
declarations ran the reset while the subinterpreters were still alive, which
is the likely cause of the CI crashes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs: fix codespell (re-used -> reused) in embedding.rst
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* build: support Eigen 5
fix#6034
* build: probe Eigen 3 and 5 separately in CMake config mode
Avoid relying on package-specific handling of a bounded version range when discovering Eigen through Eigen3Config.cmake.
Made-with: Cursor
* [skip ci] build: clarify Eigen 5 module fallback comment
Explain that the MODULE-mode fallback only exists for older Eigen 3 setups so the remaining fallback path does not look like an unresolved Eigen 5 issue.
Made-with: Cursor
* [skip ci] docs: add Eigen 5 entry to v3.0.4 changelog
Document the Eigen 5 CMake package detection fix in the 3.0.4 release notes before merging the PR.
Made-with: Cursor
---------
Co-authored-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
Document the post-v3.0.3 fixes and CI changes ahead of the patch release so the release prep can be reviewed before the version bump work.
Made-with: Cursor
* init
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* Add constexpr to is_floating_point check
This is known at compile time so it can be constexpr
* Allow noconvert float to accept int
* Update noconvert documentation
* Allow noconvert complex to accept int and float
* Add complex strict test
* style: pre-commit fixes
* Update unit tests so int, becomes double.
* style: pre-commit fixes
* remove if (constexpr)
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* fix spelling error
* bump order in #else
* Switch order in c++11 only section
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* ci: trigger build
* ci: trigger build
* Allow casting from float to int
The int type caster allows anything that implements __int__ with explicit exception of the python float. I can't see any reason for this.
This modifies the int casting behaviour to accept a float.
If the argument is marked as noconvert() it will only accept int.
* tests for py::float into int
* Update complex_cast tests
* Add SupportsIndex to int and float
* style: pre-commit fixes
* fix assert
* Update docs to mention other conversions
* fix pypy __index__ problems
* style: pre-commit fixes
* extract out PyLong_AsLong __index__ deprecation
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* style: pre-commit fixes
* Add back env.deprecated_call
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* remove note
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* remove untrue comment
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* fix noconvert_args
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* resolve error
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* Add comment
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
* [skip ci]
tests: Add overload resolution test for float/int breaking change
Add test_overload_resolution_float_int() to explicitly test the breaking
change where int arguments now match float overloads when registered first.
The existing tests verify conversion behavior (int -> float, int/float -> complex)
but do not test overload resolution when both float and int overloads exist.
This test fills that gap by:
- Testing that float overload registered before int overload matches int(42)
- Testing strict mode (noconvert) overload resolution breaking change
- Testing complex overload resolution with int/float/complex overloads
- Documenting the breaking change explicitly
This complements existing tests which verify 'can it convert?' by testing
'which overload wins when multiple can convert?'
* Add test to verify that custom __index__ objects (not PyLong) work correctly with complex conversion. These should be consistent across CPython, PyPy, and GraalPy.
* Improve comment clarity for PyPy __index__ handling
Replace cryptic 'So: PYBIND11_INDEX_CHECK(src.ptr())' comment with
clearer explanation of the logic:
- Explains that we need to call PyNumber_Index explicitly on PyPy
for non-PyLong objects
- Clarifies the relationship to the outer condition: when convert
is false, we only reach this point if PYBIND11_INDEX_CHECK passed
above
This makes the code more maintainable and easier to understand
during review.
* Undo inconsequential change to regex in test_enum.py
During merge, HEAD's regex pattern was kept, but master's version is preferred.
The order of ` ` and `\|` in the character class is arbitrary. Keep master's order
(already fixed in PR #5891; sorry I missed looking back here when working on 5891).
* test_methods_and_attributes.py: Restore existing `m.overload_order(1.1)` call and clearly explain the behavior change.
* Reject float → int conversion even in convert mode
Enabling implicit float → int conversion in convert mode causes
silent truncation (e.g., 1.9 → 1). This is dangerous because:
1. It's implicit - users don't expect truncation when calling functions
2. It's silent - no warning or error
3. It can hide bugs - precision loss is hard to detect
This change restores the explicit rejection of PyFloat_Check for integer
casters, even in convert mode. This is more in line with Python's behavior
where int(1.9) must be explicit.
Note that the int → float conversion in noconvert mode is preserved,
as that's a safe widening conversion.
* Revert test changes that sidestepped implicit float→int conversion
This reverts all test modifications that were made to accommodate
implicit float→int conversion in convert mode. With the production
code change that explicitly rejects float→int conversion even in
convert mode, these test workarounds are no longer needed.
Changes reverted:
- test_builtin_casters.py: Restored cant_convert(3.14159) and
np.float32 conversion with deprecated_call wrapper
- test_custom_type_casters.py: Restored TypeError expectation for
m.ints_preferred(4.0)
- test_methods_and_attributes.py: Restored TypeError expectation
for m.overload_order(1.1)
- test_stl.py: Restored float literals (2.0) that were replaced with
strings to avoid conversion
- test_factory_constructors.py: Restored original constructor calls
that were modified to avoid float→int conversion
Also removes the unused avoid_PyLong_AsLong_deprecation fixture
and related TypeVar imports, as all uses were removed.
* Replace env.deprecated_call() with pytest.deprecated_call()
The env.deprecated_call() function was removed, but two test cases
still reference it. Replace with pytest.deprecated_call(), which is
the standard pytest context manager for handling deprecation warnings.
Since we already require pytest>=6 (see tests/requirements.txt), the
compatibility function is obsolete and pytest.deprecated_call() is
available.
* Update test expectations for swapped NoisyAlloc overloads
PR 5879 swapped the order of NoisyAlloc constructor overloads:
- (int i, double) is now placement new (comes first)
- (double d, double) is now factory pointer (comes second)
This swap is necessary because pybind11 tries overloads in order
until one matches. With int → float conversion now allowed:
- create_and_destroy(4, 0.5): Without the swap, (double d, double)
would match first (since int → double conversion is allowed),
bypassing the more specific (int i, double) overload. With the
swap, (int i, double) matches first (exact match), which is
correct.
- create_and_destroy(3.5, 4.5): (int i, double) fails (float → int
is rejected), then (double d, double) matches, which is correct.
The swap ensures exact int matches are preferred over double matches
when an int is provided, which is the expected overload resolution
behavior.
Update the test expectations to match the new overload resolution
order.
* Resolve clang-tidy error:
/__w/pybind11/pybind11/include/pybind11/cast.h:253:46: error: repeated branch body in conditional chain [bugprone-branch-clone,-warnings-as-errors]
253 | } else if (PyFloat_Check(src.ptr())) {
| ^
/__w/pybind11/pybind11/include/pybind11/cast.h:258:10: note: end of the original
258 | } else if (convert || PYBIND11_LONG_CHECK(src.ptr()) || PYBIND11_INDEX_CHECK(src.ptr())) {
| ^
/__w/pybind11/pybind11/include/pybind11/cast.h:283:16: note: clone 1 starts here
283 | } else {
| ^
* Add test coverage for __index__ and __int__ edge cases: incorrectly returning float
These tests ensure that:
- Invalid return types (floats) are properly rejected
- The fallback from __index__ to __int__ works correctly in convert mode
- noconvert mode correctly prevents fallback when __index__ fails
* Minor comment-only changes: add PR number, for easy future reference
* Ensure we are not leaking a Python error is something is wrong elsewhere (e.g. UB, or bug in Python beta testing).
See also: https://github.com/pybind/pybind11/pull/5879#issuecomment-3521099331
* [skip ci] Bump PYBIND11_INTERNALS_VERSION to 12 (for PRs 5879, 5887, 5960)
---------
Signed-off-by: Michael Carlstrom <rmc@carlstrom.com>
Co-authored-by: gentlegiantJGC <gentlegiantJGC@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>
* Bump internals version
* Prevent internals destruction before all pybind11 types are destroyed
* Use Py_XINCREF and Py_XDECREF
* Hold GIL before decref
* Use weakrefs
* Remove unused code
* Move code location
* Move code location
* Move code location
* Try add tests
* Fix PYTHONPATH
* Fix PYTHONPATH
* Skip tests for subprocess
* Revert to leak internals
* Revert to leak internals
* Revert "Revert to leak internals"
This reverts commit c5ec1cf886.
This reverts commit 72c2e0aa9b.
* Revert internals version bump
* Reapply to leak internals
This reverts commit 8f25a254e8.
* Add re-entrancy detection for internals creation
Prevent re-creation of internals after destruction during interpreter
shutdown. If pybind11 code runs after internals have been destroyed,
fail early with a clear error message instead of silently creating
new empty internals that would cause type lookup failures.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix C++11/C++14 support
* Add lock under multiple interpreters
* Try fix tests
* Try fix tests
* Try fix tests
* Update comments and assertion messages
* Update comments and assertion messages
* Update comments
* Update lock scope
* Use original pointer type for Windows
* Change hard error to warning
* Update lock scope
* Update lock scope to resolve deadlock
* Remove scope release of GIL
* Update comments
* Lock pp on reset
* Mark content created after assignment
* Update comments
* Simplify implementation
* Update lock scope when delete unique_ptr
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* docs: seed 3.0.2 changelog from needs-changelog PRs
Collect suggested entries early to streamline release prep.
* Misc trivial manual fixes.
* Shorten changelog entry for PR 5862
* Remove mention of a minor doc formatting fix.
* Cursor-generated "all past-tense" style
* Restore the meaning of the 5958 entry using the "... now ..." trick, and restore a couple other entries that also use the "now" trick.
* Replace ... now ... style with ... updated to ... style
* [skip ci] docs: group 3.0.2 entries under Internal heading
Align changelog categories with recent releases for review.
* Update changelog with CMake policy compatibility fix
Fix compatibility with CMake policy CMP0190 for cross-compiling.
* Add changelog entries for 5965 and 5968
* docs: make CMP0190 changelog entry past tense
Align 3.0.2 bug-fix entry with changelog style.
* [skip ci] docs: add missing 3.0.2 changelog entries
Capture remaining needs-changelog PRs across categories. (These slipped through the cracks somehow.)
---------
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.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>
* Remove enum from bold in doc
* [skip ci] Remove bold formatting around (see #5528)
---------
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.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>
When comparing buffer types there are some edge cases on some platforms that are equivalent but the format string is not identical.
item_type_is_equivalent_to is more forgiving than direct string comparison.
Created using [mini-swe-agent](https://mini-swe-agent.com) and the propmt:
I'd like to find usages of PYBIND11_MODULE in the docs folder and add py::mod_gil_not_used() as a third argument if there ar
e only two arguments. These are examples, and it's really a good idea to always include that now.
I removed a few of the changes.
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
* [skip ci] Small docs/release.rst update, mainly to warn about `git push --tags`.
* Remove mention of `git push --tags`
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
---------
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
* Update docs/changelog.md and change version to v3.0.0 (final)
* [skip ci] Add `|SPEC 4 — Using and Creating Nightly Wheels|` badge in main README.rst
* feat: scoped_critical_section
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
* refactor: pull out to file
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
* style: pre-commit fixes
* fix: GIL code in some compilers
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
* fix: move to correct spot
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
---------
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* refactor: use CPython macros to construct `PYBIND11_VERSION_HEX`
* docs: update release guide
* tests: add test to keep version values in sync
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
* style: pre-commit fixes
* test: update version test
* test: update version test
* test: update version test
* chore: update code comments
* Update docs/release.rst
---------
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>