Commit Graph
3306 Commits
Author SHA1 Message Date
Henry Schreiner c538993a7c fix(cmake): don't link SHARED modules against libpython in FindPython mode
Python_add_library() hard-links non-MODULE libraries against
Python::Python. On macOS with a statically linked interpreter (e.g.
uv / python-build-standalone), importing such a module loads a second,
uninitialized copy of the Python runtime and aborts with a fatal
PyInterpreterState_Get error. Bypass python_add_library for SHARED and
link pybind11::module instead of pybind11::embed, matching the classic
pybind11Tools.cmake behavior.

Assisted-by: ClaudeCode:claude-fable-5
2026-08-07 00:18:37 -04:00
Henry SchreinerandRalf W. Grosse-Kunstleve 97bf890db6 chore: prepare 3.1.0 release (#6125)
* 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>
v3.1.0
2026-08-06 11:44:21 -04:00
ymwang78 05f6e6f681 fix(subinterpreter): don't touch the thread state before create() attaches one (#6127)
`subinterpreter::create()` documents that "the main interpreter and its GIL
are not required to be held prior to calling this function", but its first
statement is `error_scope err_scope;`, i.e. `PyErr_Fetch()`, before
`main_guard` attaches a thread state. With no current `PyThreadState`,
`PyErr_Fetch()` -> `_PyErr_GetRaisedException(NULL)` dereferences null and
the process dies (SIGSEGV; 0xC0000005 on Windows). `~error_scope` is the
mirror image: it calls `PyErr_Restore()` after `main_guard` has already
swapped the thread state back away.

Two ordinary situations reach `create()` with no thread state:

- an embedder that ends its initialization with `PyEval_SaveThread()`,
  which is the documented way to hand the GIL back after
  `Py_InitializeFromConfig()`;
- any worker thread that has never touched Python.

Existing tests never hit this because they all run under the
`py::scoped_interpreter guard{}` in catch.cpp, which keeps the GIL held on
the main thread for the whole run.

Move `error_scope` inside the `main_guard` scope. The case it exists for is
unaffected: a caller that already holds the main GIL takes
`subinterpreter_scoped_activate`'s `simple_gil_` fast path, which keeps the
same thread state, so its pending error is still saved across
`Py_NewInterpreterFromConfig()` and restored afterwards. A caller sitting on
some other interpreter never had its error indicator touched in the first
place, since everything inside the block runs on the main interpreter's
thread state and `PyThreadState_Swap()` does not move error indicators. It
also makes the `pybind11_fail()` path unwind in a safer order: `~error_scope`
now runs while `main_guard` is still alive.

Add "Create Subinterpreter without a thread state", covering both a thread
that dropped its thread state via `gil_scoped_release` and a thread that
never had one. It segfaults without the fix and passes with it.

Verified on Windows / MSVC 14.51 / CPython 3.13.14: test_with_catch goes
from 33 to 34 test cases, all passing.

Assisted-by: ClaudeCode:claude-opus-5
2026-08-06 00:05:23 -07:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
6dd1756f98 chore(deps): update pre-commit hooks (#6126)
* 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>
2026-08-06 01:26:39 -04:00
Ralf W. Grosse-Kunstleve 59565095fa Delegate py::print to Python's native print (#6121)
* refactor: delegate py::print to native print

* style: use auto for print result

* test: focus py::print coverage on delegation

* docs: describe native py::print delegation

* fix: keep py::print silent when builtin is missing

* test: cover py::print with unavailable stdout

* docs: clarify py::print builtins lookup
2026-08-02 22:37:26 -07:00
Henry SchreinerandRalf W. Grosse-Kunstleve 63d627c574 feat!: drop support for Python 3.8, MSVC 2017 (#6110)
* 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>
2026-07-31 22:04:32 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 695a7a421d chore(deps): bump the actions group with 3 updates (#6119)
Bumps the actions group with 3 updates: [actions/setup-python](https://github.com/actions/setup-python), [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) and [actions/labeler](https://github.com/actions/labeler).


Updates `actions/setup-python` from 6 to 7
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v6...v7)

Updates `astral-sh/setup-uv` from 8.2.0 to 9.0.0
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v8.2.0...v9.0.0)

Updates `actions/labeler` from 6 to 7
- [Release notes](https://github.com/actions/labeler/releases)
- [Commits](https://github.com/actions/labeler/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: astral-sh/setup-uv
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: actions/labeler
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-31 22:58:26 -04:00
Henry Schreiner ea9e6e6a23 feat: small command line helpers for quick tests (#4272)
* 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
2026-07-31 14:17:21 -04:00
Henry Schreinerandpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 652c69437b fix: add py::mod_gil_used() spelling, support pedantic tests (#5797)
* tests: add linking warnings/error

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* tests: check pedantic C++14

* fix: some pedantic warnings

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* feat: add py::mod_gil_used()

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: use not_supported()

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* style: pre-commit fixes

* Update CMakeLists.txt

* fix: remove the true/false parameter from mod_gil_not_used

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* style: pre-commit fixes

* Update tests/CMakeLists.txt

* fix: deprecate mod_gil_not_used(bool) instead of removing it

Keep the bool constructor public and mark it deprecated, so existing
code that spells mod_gil_not_used(false) still compiles. mod_gil_used()
now sets the flag through its friendship, which keeps the deprecated
constructor the only bool overload and stops pybind11 warning against
itself.

Also use the py:: alias in exo_planet_pybind11.cpp to match its sibling
home_planet_very_lonely_traveler.cpp.

Assisted-by: ClaudeCode:claude-opus-5

* fix: add trailing comma to macros picked up in rebase

test_smart_ptr.cpp and standalone_enum_module.cpp came from master after
this branch was written, so they still invoked variadic macros with no
variadic argument. That is a pedantic error below C++20.

Assisted-by: ClaudeCode:claude-opus-5

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-29 14:53:47 -04:00
Henry SchreinerandRalf W. Grosse-Kunstleve 2f85cc8c4a chore(ci): bump NVHPC to 26.5 (#6117)
* chore(ci): bump NVHPC to 26.5

Assisted-by: ClaudeCode:claude-opus-5

* chore(ci): download NVHPC deb with curl retries to dodge CDN 404s

Assisted-by: ClaudeCode:claude-fable-5

---------

Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
2026-07-29 12:51:20 -04:00
Henry SchreinerandRalf W. Grosse-Kunstleve 5540f96802 fix: only add string_view life support for transient sources (#6096)
* 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>
2026-07-28 18:53:36 -07:00
Henry Schreiner a647cddd4e fix(cmake): respect explicit PYBIND11_USE_CROSSCOMPILING under CMP0190 (#6094)
* fix(cmake): respect explicit PYBIND11_USE_CROSSCOMPILING under CMP0190

PR #5829 added `AND NOT DEFINED CMAKE_CROSSCOMPILING_EMULATOR` to the
condition setting `_PYBIND11_CROSSCOMPILING`. That gate was meant to only
control the auto-default of `PYBIND11_USE_CROSSCOMPILING`, but it ended up
overriding a value the project set explicitly. Emscripten/Pyodide defines
`CMAKE_CROSSCOMPILING_EMULATOR` (node) yet still wants cross-compiling
mode, so the flag was forced OFF and the build failed with a spurious
"Cannot run the interpreter" / pointer-size mismatch.

Move the emulator check up so it only guards the auto-default, and never
override an explicitly set `PYBIND11_USE_CROSSCOMPILING`.

Fixes #6043

Assisted-by: ClaudeCode:claude-opus-4.8

* fix(cmake): keep CMP0190 auto-default in add_subdirectory builds

The previous commit's `NOT DEFINED PYBIND11_USE_CROSSCOMPILING` guard
broke the intended auto-default for top-level / add_subdirectory builds:
CMakeLists.txt runs `option(PYBIND11_USE_CROSSCOMPILING ... OFF)` before
including pybind11Common.cmake, so the variable is already defined (OFF)
and the CMP0190 default never applied.

Capture, before the option() call, whether the project set the value
itself, and let pybind11Common.cmake apply its default unless the value
was set explicitly. This keeps both the emulator override fix and the
CMP0190 auto-default for subdirectory consumers.

Assisted-by: ClaudeCode:claude-opus-4.8
2026-07-27 09:41:15 -04:00
Henry Schreiner 95ebcb3643 chore(tools): make_changelog missed and resurrected PRs (#6108) 2026-07-27 01:41:07 -04:00
Henry Schreiner f4d31b743d fix(cmake): don't pass -fno-fat-lto-objects on Apple GCC (#6114)
GCC on macOS has no linker plugin, so `-fno-fat-lto-objects` makes every
LTO probe fail and LTO is silently disabled. Plain `-flto=auto` works.

Fixes #6060

Assisted-by: ClaudeCode:claude-opus-5
Claude-Session: https://claude.ai/code/session_013JABmnjt9oAh29p1pytAB3
2026-07-26 21:26:04 -07:00
Henry SchreinerandRalf W. Grosse-Kunstleve f95b7a5860 fix: include complex in std::complex input annotation (#6113)
* fix: include `complex` in std::complex input annotation

The input annotation for `std::complex<T>` omitted the builtin `complex`
type, which typeshed only makes a `typing.SupportsComplex` on Python 3.11+.

Assisted-by: ClaudeCode:claude-opus-5
Claude-Session: https://claude.ai/code/session_013JABmnjt9oAh29p1pytAB3

* Add comment to explain why the explicit `complex` is needed.

---------

Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
2026-07-26 21:25:24 -07:00
Henry Schreiner 17b3b605a5 test: remove dead PR3068 workaround branch (#6109)
`WORKAROUND_ENABLING_ROLLBACK_OF_PR3068` compared the 5-element
`sys.version_info` tuple to `(3, 9)`, so it was always False. The guarded
branch never ran. Remove the constant and keep only the branch that runs.

Assisted-by: ClaudeCode:claude-opus-5
2026-07-26 19:08:59 -07:00
Henry SchreinerandRalf W. Grosse-Kunstleve 57e7a8de34 fix(stl_bind): correct __delitem__ for negative-step slices and re-enable contiguous erase fast path (#6088)
* fix(stl_bind): correct __delitem__ for negative-step slices and re-enable contiguous erase fast path

The slice __delitem__ binding advanced the erase index by step - 1 for
all steps. That correction is only valid for positive steps, where
erasing shifts later elements down by one. For negative steps the
visited indices are strictly decreasing and erasing never shifts them,
so the extra -1 deleted the wrong elements (e.g. del v[::-2] on
[0,1,2,3] yielded [1,2] instead of [0,2]) and del v[::-1] walked off the
front of the vector (v.begin() - 1, observed SIGBUS).

Switch to the signed slice::compute overload so negative steps stay
signed, advance by step for negative steps and step - 1 for positive
ones, and drop the && false that had disabled the O(n) contiguous fast
path since 2016.

Assisted-by: ClaudeCode:claude-fable-5

* refactor: address review — static_cast and parametrized test

Use static_cast instead of a C-style cast for the slice.compute() size
argument, and convert the __delitem__ slice test to
pytest.mark.parametrize over the slice cases.

Assisted-by: ClaudeCode:claude-fable-5

* test(stl_bind): cover slice deletion edge cases

* fix(stl_bind): erase strided slices in descending order

* Eliminate a variable and avoid redundant index increment (i + 1, ++i).

The control flow handles all relevant boundaries:

- slicelength == 0: excluded by the outer guard.
- slicelength == 1: erases once, decrements to zero, and breaks without touching start.
- Larger slices: updates start exactly when another erase remains.
- slicelength cannot underflow because the loop exits when it reaches zero.
- Mutating slicelength is harmless because it is not used afterward.
- The potentially dangerous final start += step remains eliminated.

It also removes the separate loop counter. The compiler would probably
optimize the former i + 1, ++i mechanics away, but the new source expresses
the real state more directly: "number of erasures remaining."

The unconditional while (true) is safe because entry is strictly guarded by
slicelength > 0, and the decrement guarantees eventual termination.

---------

Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
2026-07-26 03:14:56 -07:00
Henry Schreiner 36341ba9ba ci: test Python 3.15 (#6107) 2026-07-24 20:32:52 -04:00
Henry Schreiner fb836a2f1f ci: drop near-duplicate jobs (#6106)
Remove ten jobs whose coverage is already provided by other jobs:
duplicate ubuntu pypy/graalpy/3.11/3.14t runs, an intel-mac 3.11
smart_holder run, a windows job pinning the default MSVC runtime,
sandwiched clang 14 and gcc 10/C++20 entries, and extra win32 and
win32-debug variants. Also delete the gcc PYBIND11_TEST_OVERRIDE steps,
dead since gcc 12 left the matrix (the windows-2022 job still runs the
same exercise).

Assisted-by: ClaudeCode:claude-fable-5
2026-07-24 17:38:59 -04:00
Henry SchreinerandRalf W. Grosse-Kunstleve 85198b598f fix(ci): use the intended Python interpreter for CMake discovery (#6105)
* fix(ci): pin the discovered Python to the venv/setup-python interpreter

The manylinux/musllinux images added Python 3.15 and dropped 3.13t;
FindPython's version scan then picked /usr/local/bin/python3.15 over
the uv-created venv (Python_ROOT_DIR is only a hint). Similarly, the
macOS and Windows 3.14t jobs picked a system 3.14 over setup-python's
free-threaded interpreter. Pin the interpreter explicitly in both
places, and drop the 3.13t manylinux jobs.

Assisted-by: ClaudeCode:claude-fable-5

* ci: use setup-python's python-path output instead of a locate step

Assisted-by: ClaudeCode:claude-fable-5

* Apply suggestions from code review

Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>

---------

Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
2026-07-24 10:45:22 -04:00
Henry Schreiner 7478df9420 fix(cmake): unset stale PYTHON_MODULE_DEBUG_POSTFIX and correct USE_PYTHON_INCLUDE_DIR variable (#6086)
When the Python executable changes between CMake runs,
PYTHON_MODULE_DEBUG_POSTFIX was not being unset alongside PYTHON_IS_DEBUG
and PYTHON_MODULE_EXTENSION, allowing a stale postfix to survive interpreter
changes.

In the USE_PYTHON_INCLUDE_DIR block, the elseif branch checked
PYTHON_INCLUDE_DIR (singular) but expanded PYTHON_INCLUDE_DIRS (plural),
always silently resolving to an empty string. Correct it to expand
${PYTHON_INCLUDE_DIR}. Also add a Python3_INCLUDE_DIRS branch so the
option works when pybind11NewTools resolves Python via the Python3
find-package component.

Assisted-by: ClaudeCode:claude-fable-5
2026-07-23 01:40:11 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 34566e1d2a chore(deps): bump soupsieve from 2.5 to 2.8.4 in /docs (#6100)
Bumps [soupsieve](https://github.com/facelessuser/soupsieve) from 2.5 to 2.8.4.
- [Release notes](https://github.com/facelessuser/soupsieve/releases)
- [Commits](https://github.com/facelessuser/soupsieve/compare/2.5...2.8.4)

---
updated-dependencies:
- dependency-name: soupsieve
  dependency-version: 2.8.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-15 22:51:27 -05:00
Henry Schreiner 28b98f2d39 ci: update cibuildwheel to v4.1 and pyodide to 314 (#6095)
* ci: update cibuildwheel to v4.1 and pyodide to 314

Bump pypa/cibuildwheel from v3.4 to v4.1 across the Pyodide, iOS, and
Android jobs. Move the Pyodide build to cp314-pyodide_wasm32
(pyodide 314.0.0).

Drop the iOS CIBW_SKIP: cp314-* workaround now that pypa/cibuildwheel#2494
is resolved.

Assisted-by: ClaudeCode:claude-opus-4.8

* test: xfail array resize on numpy<2.4 + Python 3.14

Removing the cp314 iOS skip surfaced a pre-existing numpy bug, not a
cibuildwheel regression: numpy<2.4 has a resize(refcheck=True) regression
on Python 3.14 where the reference held by the bound function isn't
detected, so a resize that should raise instead succeeds and the later
reshape rejects the non-square size. Fixed in numpy>=2.4, but the iOS test
environment has no numpy wheel newer than 2.3.5.post1, so xfail the test
for that specific combination.

Assisted-by: ClaudeCode:claude-opus-4.8

* test: link numpy resize aliasing issue and trim comment

iOS numpy wheels updated to 2.5.0, so the xfail is a general numpy<2.4 +
Python 3.14 guard rather than iOS-specific. Reference numpy/numpy#30265.

Assisted-by: ClaudeCode:claude-opus-4.8
2026-07-08 23:31:36 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 7ca651c0e5 chore(deps): update pre-commit hooks (#6099)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.15.15 → v0.15.20](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.15...v0.15.20)
- [github.com/adhtruong/mirrors-typos: v1.47.0 → v1.48.0](https://github.com/adhtruong/mirrors-typos/compare/v1.47.0...v1.48.0)
- [github.com/PyCQA/pylint: v4.0.5 → v4.0.6](https://github.com/PyCQA/pylint/compare/v4.0.5...v4.0.6)
- [github.com/python-jsonschema/check-jsonschema: 0.37.2 → 0.37.4](https://github.com/python-jsonschema/check-jsonschema/compare/0.37.2...0.37.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-08 16:45:20 -04:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Ralf W. Grosse-Kunstleve
b57b4393ff chore(deps): bump the actions group with 3 updates (#6098)
* chore(deps): bump the actions group with 3 updates

Bumps the actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) and [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel).


Updates `actions/checkout` from 6 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

Updates `astral-sh/setup-uv` from 8.1.0 to 8.2.0
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v8.1.0...v8.2.0)

Updates `pypa/cibuildwheel` from 3.4 to 4.1
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.4...v4.1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: astral-sh/setup-uv
  dependency-version: 8.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: pypa/cibuildwheel
  dependency-version: '4.1'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>

* ci: restore checkout v1 for i386 job

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
2026-07-03 14:50:43 -07:00
Henry Schreiner db92ad940f revert: "add life support to handles cast to string_view (#6092)" (#6097)
This reverts commit 59d7cb28c1 (#6092).

#6092 introduced regressions that are being addressed in #6096; reverting

Assisted-by: ClaudeCode:claude-opus-4.8
2026-06-29 00:38:56 -04:00
Henry Schreiner 84da0e2545 refactor: remove needless load_src alias in string_caster (#6093)
`load_src` was a Python 2-era leftover. A removed branch used to reassign
it to a temporary unicode object; since that was deleted with Python 2
support, it is now an exact, never-reassigned alias of `src`. Use `src`
directly.

Spotted in review of #6092.

Assisted-by: ClaudeCode:claude-opus-4.8
2026-06-23 21:15:58 -07:00
Henry SchreinerandRalf W. Grosse-Kunstleve 3de0402476 chore: add agent files (#6082)
* chore: add agent files

Assisted-by: ClaudeCode:claude-opus-4.8
Signed-off-by: Henry Schreiner <henryfs@princeton.edu>

* fix: better AGENTS.md

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>

* Apply suggestions from code review

Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
2026-06-23 23:49:20 -04:00
Henry Schreiner 085b66068a fix: data race on last_storage_ptr_ cache in gil_safe_call_once_and_store (#6087)
Under free-threaded CPython (Py_GIL_DISABLED) the GIL provides no mutual
exclusion, so the plain pointer last_storage_ptr_ was read and written
concurrently without synchronization, a C++ data race. Make it a
std::atomic<T *>.

Also reorder get_stored() to check is_last_storage_valid() before loading
the cached pointer. The writer publishes the pointer before setting the
validity flag, so the flag must be observed first for correct
acquire/release ordering.

Assisted-by: ClaudeCode:claude-fable-5
2026-06-23 21:48:26 -04:00
Charles Beattieandpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 59d7cb28c1 fix: add life support to handles cast to string_view (#6092)
* Fix handling of string_view to prevent GC'ing strings before they are used.

* style: pre-commit fixes

* Update cast.h

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-06-23 21:44:39 -04:00
Henry Schreiner da3bdcad04 chore(setup_helpers): remove dead cpp_flag_cache and fix parameter typo (#6085)
Remove the module-level `cpp_flag_cache = None` variable and its stale
comment "Every call will cache the result". The actual caching is handled
by the `@lru_cache` decorator on `auto_cpp_level` directly below.

Also rename the typo'd parameter `obg` to `obj` in `no_recompile`.
Nothing passes this argument by keyword, so there is no API break.

Part of #6084

Assisted-by: ClaudeCode:claude-sonnet-4-6
2026-06-17 08:16:49 -04:00
Henry Schreiner 99117da020 chore(eval): drop Python 2 coding cookie prepended to evaluated source (#6089)
The `# -*- coding: utf-8 -*-` line prepended to every string passed to
PyRun_String was a Python 2 workaround. Python 3's PyRun_String already
assumes UTF-8 source encoding, so the cookie is dead weight — and
harmful: it shifts all line numbers up by one in tracebacks and
SyntaxErrors from evaluated code (a `raise` on line 2 would incorrectly
appear as line 3).

Remove the cookie and replace the stale comment with one that explains
the actual reason for the `std::string` conversion (need a C string for
PyRun_String). No other location in eval.h uses this pattern
(eval_file reads directly from a FILE*).

Assisted-by: ClaudeCode:claude-fable-5
2026-06-17 08:16:04 -04:00
Henry Schreiner f00aa6fe07 ci: drop boost from 32-bit mingw32 install (#6091)
* ci: drop boost from 32-bit mingw32 install

MSYS2 removed the mingw-w64-i686-boost package (32-bit i686 is being
phased out), so the mingw32 matrix entry now fails at the pacman install
step with "target not found: mingw-w64-i686-boost". Boost is optional
test coverage (boost::optional / boost::variant casters, gated behind
PYBIND11_TEST_BOOST); without it those tests are skipped and the rest of
the job builds and runs normally. Move boost to the mingw64 extra_install
so the 64-bit job keeps that coverage.

Assisted-by: ClaudeCode:claude-opus-4.8

* Apply suggestion from @henryiii
2026-06-17 08:13:47 -04:00
Henry Schreiner ff1a35cb84 ci: update GraalPy from 24.2 to 25.0 (Python 3.12 based) (#6083)
* ci: update GraalPy from 24.2 to 25.0 (Python 3.12 based)

- Replace graalpy-24.2 with graalpy-25.0 in CI matrix
- Replace graalpy-24.1 with graalpy-24.2 (shift older version up)
- Remove dead GRAALPY_VERSION < (24, 2) xfail guards from tests
- Remove unused GRAALPY_VERSION from tests/env.py
- Update internals.h comment to reference v25.0

Assisted-by: OpenCode:glm-5

* fix: use numpy 2.2.x for GraalPy 3.12 (graalpy312 wheels)

numpy 1.26.x only has graalpy311 wheels; GraalPy 25.0 (Python 3.12)
requires numpy 2.2.x which has graalpy312 wheels on the GraalVM index.

Assisted-by: OpenCode:glm-5

* fix: simplify numpy requirement for GraalPy (drop 3.11 branch)

We no longer test GraalPy 3.11, so the version split is unnecessary.

Assisted-by: OpenCode:glm-5
2026-06-10 16:03:38 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ec1d8762a8 chore(deps): update pre-commit hooks (#6079)
updates:
- [github.com/pre-commit/mirrors-clang-format: v22.1.4 → v22.1.5](https://github.com/pre-commit/mirrors-clang-format/compare/v22.1.4...v22.1.5)
- [github.com/astral-sh/ruff-pre-commit: v0.15.12 → v0.15.15](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.12...v0.15.15)
- [github.com/pre-commit/mirrors-mypy: v1.20.2 → v2.1.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.20.2...v2.1.0)
- [github.com/adhtruong/mirrors-typos: v1.46.0 → v1.47.0](https://github.com/adhtruong/mirrors-typos/compare/v1.46.0...v1.47.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-06-06 11:06:45 -07:00
Matti PicusandRalf W. Grosse-Kunstleve 6079989cf7 Pypy testing no longer xfails (#6077)
* test passes on PyPy macOS

* adjust tests for pypy HEAD

* fixes from review

* pypy 7.3.23 was released, drop some PyPy testing

* pin to pypy version 7.3.23

* Restore xfail for cross-module translator platforms

Keep the expected failure for Android and FreeBSD while limiting the PyPy-specific part to versions before 7.3.23. Android CIBW still raises RuntimeError for this test, matching the existing tracked platform issue.

---------

Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
2026-05-27 08:07:53 -07:00
ymwang78Claude Opus 4.7pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
46ebf5031b feat(subinterpreter): reusable PyThreadState via subinterpreter_thread_state (#6073)
* 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>
2026-05-25 09:31:14 -04:00
f891299e6a Fix custom __str__ for enum_ (#6078)
* fix: prioritize custom enum __str__

* test: strengthen custom enum __str__ regression

* refactor: move enum __str__ handling into enum_

Keep class_::def() generic and let enum_ own the enum-specific
behavior for custom __str__ overloads. This avoids using the private
__entries attribute as a runtime sentinel for py::enum_ while preserving
the prepend behavior that lets user-defined enum __str__ methods take
precedence over the generated default.

One caveat is that this applies to normal py::enum_ API usage. Code that
intentionally upcasts an enum_ binding to class_& and then calls
class_::def("__str__", ...) will bypass this enum_ override and keep the
generic class_ behavior.

* fix: avoid enum def ambiguity on MinGW

Remove the inherited class_::def overload set from enum_ and add an explicit forwarding overload for non-string def() calls. GCC 15 on MinGW otherwise sees the duplicate dependent-base def(const char *, ...) template as ambiguous with enum_::def(const char *, ...), breaking the C++11 build.

---------

Co-authored-by: ctmd1234567 <ctmd1234567@users.noreply.github.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
2026-05-24 21:04:39 -07:00
jjuang-appleandpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> a2592ad9d6 Apply -undefined dynamic_lookup to all Apple platforms (#6075)
* Apply -undefined dynamic_lookup to all Apple platforms

* style: pre-commit fixes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-05-24 11:28:53 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 5205df97fc chore(deps): bump idna from 3.7 to 3.15 in /docs (#6074)
Bumps [idna](https://github.com/kjd/idna) from 3.7 to 3.15.
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md)
- [Commits](https://github.com/kjd/idna/compare/v3.7...v3.15)

---
updated-dependencies:
- dependency-name: idna
  dependency-version: '3.15'
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-20 15:23:32 -07:00
Ralf W. Grosse-Kunstleve 28bbda9ddf [skip ci] test: reject shared_ptr casts for custom holders (#6069)
Lock down the current behavior discussed in issue #6064: py::cast() from std::shared_ptr<T> remains rejected for custom holder bindings that are not std::shared_ptr or py::smart_holder.

This extracts the incompatible-holder coverage from PR #6068 and adds a test shaped like issue #6064, while PR #6065 and PR #6066 explore alternative support paths.
2026-05-18 21:36:16 -07:00
Ralf W. Grosse-Kunstleve 3160c82392 ci: pin Ubuntu PyPy 3.11 to 7.3.21 (#6070) 2026-05-18 11:31:19 -07:00
Matthias Klumpp 5a5f21deb6 fix: Invert input/output context if a Python function is called from C++ (#6055)
When the Callable itself is an input (parameter) to a C++ function, its
arguments are outputs (C++ passes them to the Python callback), and vice
versa.
Therefore, we must invert them if C++ calls a Python function, but keep
them the same in the other direction.
2026-05-16 11:28:05 -07:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Ralf W. Grosse-Kunstleve
00a9c6244c chore(deps): update pre-commit hooks (#6054)
* chore(deps): update pre-commit hooks

updates:
- [github.com/pre-commit/mirrors-clang-format: v22.1.2 → v22.1.4](https://github.com/pre-commit/mirrors-clang-format/compare/v22.1.2...v22.1.4)
- [github.com/astral-sh/ruff-pre-commit: v0.15.9 → v0.15.12](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.9...v0.15.12)
- [github.com/pre-commit/mirrors-mypy: v1.20.0 → v1.20.2](https://github.com/pre-commit/mirrors-mypy/compare/v1.20.0...v1.20.2)
- [github.com/adhtruong/mirrors-typos: v1.45.0 → v1.46.0](https://github.com/adhtruong/mirrors-typos/compare/v1.45.0...v1.46.0)
- [github.com/python-jsonschema/check-jsonschema: 0.37.1 → 0.37.2](https://github.com/python-jsonschema/check-jsonschema/compare/0.37.1...0.37.2)

* fix: correct detailed error message comment wording

Clarify when detailed error messages are enabled and remove the typo caught by typos.

---------

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>
2026-05-13 19:03:57 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 59a917db6b chore(deps): bump urllib3 from 2.6.3 to 2.7.0 in /docs (#6058)
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.6.3 to 2.7.0.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.6.3...2.7.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.7.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-13 17:16:53 -07:00
Ralf W. Grosse-KunstleveandCursor 81817aed7e ci: remove the deadsnakes job (#6052)
Drop the last remaining deadsnakes-based Linux job because it mostly duplicates the main Ubuntu coverage while failing in external Launchpad/PPA setup, and the old Valgrind/debug path it used to complement has already been retired.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-02 19:02:46 -07:00
Ralf W. Grosse-KunstleveandCursor 9cc298a481 ci: pass explicit ARM64 Python artifacts on windows-11-arm (#6051)
Avoid relying on Python_ROOT_DIR alone because CMake FindPython can still resolve the hosted x64 python.org install on the Windows ARM runner and then fail at link time with an x64/arm64 mismatch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-02 17:49:31 -07:00
Ralf W. Grosse-KunstleveandCursor c5b3ae8168 ci: pin PyPy 3.11 to 7.3.21 on macOS and Windows (#6050)
Temporarily pin the two failing PyPy 3.11 jobs while investigating the PyPy 7.3.22 import regression.

Refs #6049.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-02 16:03:42 -07:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> ee1d83f6c1 chore(deps): bump the actions group with 2 updates (#6047)
Bumps the actions group with 2 updates: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) and [scientific-python/upload-nightly-action](https://github.com/scientific-python/upload-nightly-action).


Updates `astral-sh/setup-uv` from 8.0.0 to 8.1.0
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v8.0.0...v8.1.0)

Updates `scientific-python/upload-nightly-action` from 0.6.3 to 0.6.4
- [Release notes](https://github.com/scientific-python/upload-nightly-action/releases)
- [Commits](https://github.com/scientific-python/upload-nightly-action/compare/5748273c71e2d8d3a61f3a11a16421c8954f9ecf...e76cfec8a4611fd02808a801b0ff5a7d7c1b2d99)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 8.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: scientific-python/upload-nightly-action
  dependency-version: 0.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-02 13:14:44 -07:00
Ralf W. Grosse-KunstleveandCursor 0f8396e4ff [skip ci] ci: schedule recurring CI and CIBW runs (#6048)
Run ci.yml and tests-cibw.yml twice weekly so master bitrot is easier to spot and root-cause before weekend maintenance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-02 11:47:01 -07:00