)]}'
{
  "log": [
    {
      "commit": "2a33aba3190cbf57ab3d46183858351b8321bba2",
      "tree": "adf7728ea58f8080e0254e7ef956d81231319253",
      "parents": [
        "11ee91ee87fe20b56528487247bccc804daade8a"
      ],
      "author": {
        "name": "Yuka Sadaoka",
        "email": "yukasadaoka@google.com",
        "time": "Tue Oct 27 05:04:38 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 21:04:38 2026 -0700"
      },
      "message": "Fix data race in registering instances (#6215)\n\n* Fix data race in registering instances\n\n* Keep the current registration order for holders that may run user code"
    },
    {
      "commit": "11ee91ee87fe20b56528487247bccc804daade8a",
      "tree": "4d27cd250f6c6eaae5a4b6b7143ef0fd63f89648",
      "parents": [
        "9516224054b6c219e877a3206eb32797abe9f582"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Fri Oct 23 20:53:49 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 20:53:49 2026 -0700"
      },
      "message": "feat(numpy): support negative indices in checked array accessors (#6201)\n\n* reject negative indices in numpy array bounds checks\n\n* fix(numpy): clarify negative index errors and document no wrapping\n\nUse a single unsigned bounds compare, say in the error message that\nnegative indices are not supported, document the behavior on the\naccessors, and cover offset_at/offset_at_t in test_bounds_check.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* feat(numpy): support negative indices in checked array accessors\n\n---------\n\nCo-authored-by: sayed ahrar \u003csayed@sproutxp.com\u003e\nCo-authored-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e"
    },
    {
      "commit": "9516224054b6c219e877a3206eb32797abe9f582",
      "tree": "c97ab9beac05390dfbdfad814b9e8aa8b6cf5bac",
      "parents": [
        "300bbd867fcda820a93672e68239c2d3a6afa379"
      ],
      "author": {
        "name": "sayed ahrar",
        "email": "sayed@sproutxp.com",
        "time": "Sat Oct 24 09:02:20 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 20:32:20 2026 -0700"
      },
      "message": "reject negative indices in numpy array bounds checks (#6187)\n\n* reject negative indices in numpy array bounds checks\n\n* fix(numpy): clarify negative index errors and document no wrapping\n\nUse a single unsigned bounds compare, say in the error message that\nnegative indices are not supported, document the behavior on the\naccessors, and cover offset_at/offset_at_t in test_bounds_check.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n---------\n\nCo-authored-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e"
    },
    {
      "commit": "300bbd867fcda820a93672e68239c2d3a6afa379",
      "tree": "f0356e47b62aa495d529c181fc115c38e006b3d0",
      "parents": [
        "d797942729072f643ad28f49653094cc93a35b19"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Fri Oct 23 17:17:43 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 17:17:43 2026 -0700"
      },
      "message": "chore(deps): bump certifi from 2024.7.4 to 2026.10.19 in /docs (#6210)\n\nBumps [certifi](https://github.com/certifi/python-certifi) from 2024.7.4 to 2026.10.19.\n- [Commits](https://github.com/certifi/python-certifi/compare/2024.07.04...2026.10.19)\n\n---\nupdated-dependencies:\n- dependency-name: certifi\n  dependency-version: 2026.10.19\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "d797942729072f643ad28f49653094cc93a35b19",
      "tree": "e616bf7c4305fb832a267dec23f757ea32534eb1",
      "parents": [
        "c85ac1bed36b0990d2cece7f7d3ef776c4078149"
      ],
      "author": {
        "name": "Yuka Sadaoka",
        "email": "yukasadaoka@outlook.com",
        "time": "Sat Oct 24 02:16:34 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 17:16:34 2026 -0700"
      },
      "message": "fix: lock the translator list when adding the local exception translator (#6208)\n\n* Initial commit for fixing a data race in the local exception translator\n\n* only run the translator race test on free-threaded builds\n\n* fix: guard translator locking on older free-threaded Python\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "c85ac1bed36b0990d2cece7f7d3ef776c4078149",
      "tree": "32cf7d966d1b589bdb9cc1759157cc40921fa03c",
      "parents": [
        "bf6e3afaae50ae85fd1069db3c0d8b6eaf9c04fa"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Fri Oct 23 15:38:48 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 15:38:48 2026 -0700"
      },
      "message": "ci: refresh Python runners and Pyodide build tooling (#6209)\n\n* ci: refresh Python runners and Pyodide build tooling\n\n* ci: pin Debian i386 job to Ubuntu 24.04"
    },
    {
      "commit": "bf6e3afaae50ae85fd1069db3c0d8b6eaf9c04fa",
      "tree": "f61edded5dba145fbaf816f20bf80dcea56d48e3",
      "parents": [
        "fdec8c350aa0c7fbb552ec70d8176f8a13eb0561"
      ],
      "author": {
        "name": "Junhyung Lee",
        "email": "70549809+espressolee@users.noreply.github.com",
        "time": "Sat Oct 24 01:30:25 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 10:30:25 2026 -0700"
      },
      "message": "fix(free-threading): cast `self` directly in `cpp_function::dispatcher` (#6177)\n\n* fix(free-threading): cast `self` directly in `cpp_function::dispatcher`\n\nPart of #6159 (item 59).\n\nUnder Py_GIL_DISABLED, cpp_function::dispatcher() took the internals lock\non every bound call: it reached its function_record through\nfunction_record_ptr_from_PyObject(), which calls\nget_function_record_PyTypeObject() (PYBIND11_LOCK_INTERNALS on\ninternals.mutex).\n\ndispatcher is installed in exactly one place (initialize_generic), and the\nPyCFunction there is created with m_self set to the function_record_PyObject\nallocated a few lines above, so self is always that object. The new\nfunction_record_ptr_from_dispatcher_self() states that invariant once and\ncasts directly; its assert compares the versioned tp_name instead of calling\nis_function_record_PyObject(), which would reacquire the lock in non-NDEBUG\nbuilds. is_function_record_PyObject() and function_record_ptr_from_PyObject()\nare unchanged, so the call sites that can see a foreign object keep the\nchecked conversion.\n\nAdds test_dispatch_does_not_need_internals_lock (free-threaded builds only):\na native thread holds internals.mutex through raw PyCFunction helpers and the\ntest checks that a bound call returns before the holder\u0027s watchdog releases\nthe mutex, with a positive control proving the held mutex is the one internals\nusers take. Fails without the fix, passes with it.\n\nAssisted-by: Claude Code:claude-opus-5\n\n* test: put the source tests dir on the subprocess path\n\npybind11_tests imports custom_exceptions from the source tests directory at\ninit, so the subprocess must see that directory as well as the build\ndirectory, as test_custom_type_setup.py does.\n\nAssisted-by: Claude Code:claude-opus-5\n\n* style: qualify function-record name comparisons with std::strcmp\n\nApply the review suggestion to both sibling comparisons; retain the existing cstring include.\n\nAssisted-by: Codex:GPT-6"
    },
    {
      "commit": "fdec8c350aa0c7fbb552ec70d8176f8a13eb0561",
      "tree": "0133621d86e8fd108ee7df7756c05cd9101874fc",
      "parents": [
        "f1f34ab0a01dbe0e6fd45239c2f0323d75aea6e2"
      ],
      "author": {
        "name": "sayed ahrar",
        "email": "sayed@sproutxp.com",
        "time": "Mon Oct 19 08:34:08 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 18 20:04:08 2026 -0700"
      },
      "message": "fix: avoid use-after-free when re-entering ostream_redirect (#6205)"
    },
    {
      "commit": "f1f34ab0a01dbe0e6fd45239c2f0323d75aea6e2",
      "tree": "00aba3c84d43c6111ddbe2e5e41868671761522c",
      "parents": [
        "e51c2fd861deed7d0d518d4824a209a76f60180a"
      ],
      "author": {
        "name": "Quinn Cheong",
        "email": "58715320+quinncheong@users.noreply.github.com",
        "time": "Mon Oct 19 10:37:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 18 19:37:28 2026 -0700"
      },
      "message": "fix: accept __index__ objects for unsigned integers without conversion so enum \u003d\u003d numpy int works (#6193)\n\n* fix: accept __index__ objects for unsigned integers without conversion\n\nSince #5887 an enum with an unsigned underlying type compares unequal to\nnumpy integers, because the no-convert pass rejects __index__ objects for\nunsigned targets and the catch-all overload returns false. Closes #6192.\n\n* style: brace the early return now compiled on CPython\n\nThe no-convert early return was previously PyPy-only, so clang-tidy never\nsaw it; readability-braces-around-statements now flags it.\n\n* test: cover the unsigned integer caster directly\n\nAdd uint_passthrough(_noconvert) and run the existing int conversion\nmatrix against it, which also pins __index__ taking precedence over\n__int__ for unsigned targets. Gate the explicit PyNumber_Index call on\nPYBIND11_INDEX_CHECK so objects without __index__ no longer raise and\nclear an extra TypeError in convert mode, and select the PyPy/unsigned\ncondition with a constexpr bool instead of two #if\u0027d if-heads.\n\nAssisted-by: ClaudeCode:claude-fable-5-1\n\n* test: only expect the 3.9 __int__ DeprecationWarning for signed ints\n\nPyLong_AsUnsignedLong does not call __int__, so the unsigned caster\nfalls back to PyNumber_Long and does not warn.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* refactor: drop the PyPy-only __index__ branch in the integer caster\n\nPyPy below the supported 7.3.17 is not a target, and supported PyPy calls __index__ in PyLong_AsLong[Long] like CPython, so only unsigned targets need the explicit PyNumber_Index call. Also drops the complex.h comment that pointed at the removed branch.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* fix: preserve complex conversion precedence on PyPy\n\nKeep complex instances and __complex__ methods ahead of the legacy __index__ fallback. Retain support for older PyPy versions and update the workaround comment.\n\nAdd regression coverage for mixed protocols, complex subclasses, and failing __complex__ methods.\n\nAssisted-by: Codex\n\n* Make PyPy PyComplex_AsCComplex workaround specific to PyPy \u003c 8.0\n\n---------\n\nCo-authored-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "e51c2fd861deed7d0d518d4824a209a76f60180a",
      "tree": "d3e361302030b9990ceaa6f020b44845ef9eeee7",
      "parents": [
        "c61cf2f6343ac0e67bff6494b0d88fb0f2e982b6"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sun Oct 18 22:35:18 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 18 19:35:18 2026 -0700"
      },
      "message": "fix: support PyPy 8.0.0 (3.11 and 3.12) (#6197)\n\n* ci: test PyPy 8.0.0 (3.11 and 3.12)\n\nFix two problems found with PyPy 3.12:\n\n- Deallocating a py::dynamic_attr() instance aborted, because PyPy 3.12\u0027s\n  _PyObject_GetDictPtr() cannot be called from tp_dealloc. Read the dict\n  slot from tp_dictoffset on PyPy instead.\n- memoryview::from_buffer() passed temporary shape/strides arrays, which\n  PyPy keeps without copying. Use PyPy\u0027s inline _shape/_strides arrays.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* tests: collect PyPrintDestructor inside its test\n\nA later PyPy GC at an arbitrary point can run the Python-calling destructor\nand abort.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* fix: limit PyPy dict deallocation workaround to 8.0.x\n\nPyPy 8.0.1 fixes the deallocation bug, but 8.0.x releases share an\nextension ABI. Retain the workaround throughout that minor series so\nextensions built with newer headers can still run on 8.0.0.\n\nRegister PYPY_VERSION_NUM with the inline-header configuration checker.\n\n* ci: test PyPy 8.0.1 while retaining 8.0.0 regression coverage\n\nUpdate the Linux Python 3.11 and macOS Python 3.12 jobs to PyPy 8.0.1.\nKeep Linux Python 3.12 on 8.0.0 to exercise the deallocation and memoryview\nworkarounds without adding jobs.\n\n* ci: retain a PyPy 7 Linux job\n\nKeep a pinned PyPy 7.3.23 / Python 3.11 job alongside the PyPy 8 matrix while PyPy 7 remains supported.\n\nAssisted-by: Codex\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "c61cf2f6343ac0e67bff6494b0d88fb0f2e982b6",
      "tree": "42962e474f3fa0bd007f99ede3c6ef46e7692957",
      "parents": [
        "d1a9692ebf46c1a7d7af73ea8a92fbb3ab4fde6f"
      ],
      "author": {
        "name": "ShurongCAO",
        "email": "3502119616@qq.com",
        "time": "Mon Oct 19 02:27:44 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 18 11:27:44 2026 -0700"
      },
      "message": "fix: support implicit value conversions in native trampolines (#6204)\n\n* fix: support implicit value conversions in native trampolines\n\n* test: avoid empty variadic arguments in embedded module\n\n* test: omit semicolon after opaque type declaration\n\n---------\n\nCo-authored-by: CAOShurong \u003c170531907+CAOShurong@users.noreply.github.com\u003e"
    },
    {
      "commit": "d1a9692ebf46c1a7d7af73ea8a92fbb3ab4fde6f",
      "tree": "6e0a231ffaa7a5d6f272c4f99643a03d9c88deb0",
      "parents": [
        "6254086d96062249c5153c17eab6b4437dd1589f"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Sat Oct 17 12:05:53 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 17 12:05:53 2026 -0700"
      },
      "message": "fix: preserve ambiguous local times in chrono conversions (#6202)\n\n* fix: preserve ambiguous local times in chrono conversions\n\n* fix: use GraalPy-compatible time zones in chrono tests\n\n* fix: satisfy clang-tidy in chrono conversions\n\n* test: isolate timezone changes on older GraalPy\n\n* test: skip timezone changes on older GraalPy"
    },
    {
      "commit": "6254086d96062249c5153c17eab6b4437dd1589f",
      "tree": "5e8518655e0920327556371a8d72e755a2471e8a",
      "parents": [
        "bb605110db023ff4a64259630ecd1902a9a917de"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Fri Oct 09 08:21:36 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 08:21:36 2026 -0400"
      },
      "message": "feat: move remaining non-template definitions to -inl.h files (#6189)"
    },
    {
      "commit": "bb605110db023ff4a64259630ecd1902a9a917de",
      "tree": "b76591801f7874ea22bebd0b8c74c627efc49b8c",
      "parents": [
        "688e74300ec5b975d96998dc9aaf38942a90fa2b"
      ],
      "author": {
        "name": "b-pass",
        "email": "b-pass@users.noreply.github.com",
        "time": "Fri Oct 09 00:10:12 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 00:10:12 2026 -0400"
      },
      "message": "Move the unref to below the multi-interpreter check. (#6195)\n\n* Move the unref to below the multi-interpreter check.\n\n* Remove ensure_internals from early module init.\n\nThe internals are not needed here, and this is always the main interpreter (which is sometimes NOT the interpreter we want).\n\n* test: cover internals initialization and interpreter cache lifetime\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "688e74300ec5b975d96998dc9aaf38942a90fa2b",
      "tree": "e4052cce6ef5b5923082fe3177cae0dacaf71457",
      "parents": [
        "9de3643672a88422dd7f5251286a63698974ecb2"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Thu Oct 08 14:16:53 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 11:16:53 2026 -0700"
      },
      "message": "fix: never run keep_alive for a failed overload or failed return conversion (#6183)\n\n* fix: do not run keep_alive for an overload that failed argument conversion\n\nCalling an overloaded function bound with `py::keep_alive\u003c0, N\u003e` segfaults\nwhenever the call is not matched by the first overload tried.\n\n    .def(\"make\", \u0026Holder::from_int,    py::keep_alive\u003c0, 1\u003e())\n    .def(\"make\", \u0026Holder::from_string, py::keep_alive\u003c0, 1\u003e());\n\n    h.make(1)    # fine\n    h.make(\"x\")  # SIGSEGV\n\nThe dispatch lambda in `cpp_function::initialize` invokes the post-call hook\nunconditionally:\n\n    auto result \u003d call_impl\u003c...\u003e(call, ...);\n    process_attributes\u003cExtra...\u003e::postcall(call, result);\n\nbut `call_impl` returns `PYBIND11_TRY_NEXT_OVERLOAD` when `load_args` fails,\nand that sentinel is `((PyObject *) 1)` rather than an object. For a\n`keep_alive` whose nurse or patient is index 0 the work happens in postcall,\nso `keep_alive_impl` receives the sentinel as `ret`, hands it to `get_arg(0)`\nand dereferences it in `_Py_TYPE`.\n\nThe existing guards do not catch it: the sentinel is neither null nor\n`Py_None`, so it passes straight through the checks added in #341.\n\nGuard inside `keep_alive_impl`, next to those checks. Only the\n`Nurse \u003d\u003d 0 || Patient \u003d\u003d 0` specialization does its work in postcall, and\n`keep_alive` is the only call policy with a non-trivial postcall, so this\ncovers every path that can observe the sentinel. `keep_alive\u003c1, 2\u003e` and\nfriends run in precall against fully populated `call.args` and are unaffected.\n\nThe regression test crashes the interpreter without the fix. Reaching the\nsecond overload is what matters: it is the first overload\u0027s failed conversion\nthat produces the sentinel.\n\n* fix: never run keep_alive for a failed overload or failed return conversion\n\nMove keep_alive activation entirely to postcall, so an argument-to-argument\nkeep_alive no longer fires in precall for an overload that later fails\nargument conversion. Extend the postcall guard to also skip a null return\nhandle, so a failed return-value conversion raises its own error instead of\n\"Could not activate keep_alive!\". Document that postcall can receive the\nPYBIND11_TRY_NEXT_OVERLOAD sentinel or a null handle.\n\nTests cover the sentinel as nurse and as patient, the argument-to-argument\ncase, and the failed return conversion, and no longer make the test object\nits own patient.\n\nAssisted-by: ClaudeCode:claude-fable-5\nClaude-Session: https://claude.ai/code/session_01WRPhwYhrJKvFXU2NWe1p3W\n\n* fix: run argument-to-argument keep_alive before the call again\n\nMoving keep_alive\u003cN, P\u003e (N, P !\u003d 0) to postcall meant a keep_alive error\nwas raised after the function ran, so its side effects stayed. Run the\nprecall hook in call_impl after load_args succeeds instead, so a failed\noverload still does not trigger it and an error still stops the call.\n\nAlso release the return value when a postcall keep_alive throws, as the\ndispatcher drops it.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* test: collect the child before capturing output on PyPy\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* fix: skip postcall for an overload that failed argument conversion\n\nThe dispatcher now runs postcall only for the overload that matched, like\nprecall. Add a test for a rejected sole candidate, and clarify the\npostcall and keep_alive_impl comments.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* fix: complete call policy conversion and result cleanup\n\nRun precall after cast_op and parameter conversion without adding copies or moves, and keep it before guard construction. Protect the owned return throughout postcall so any throwing hook releases it.\n\nExtend regression coverage for reference rejection, converting overloads, constructors, return retention, custom hooks and return conversion errors.\n\n* refactor: clarify call guard conversion boundaries\n\nRemove unused argument-loader invocation overloads, standardize precall naming, and explain the function_ref parameter boundary and copy elision.\n\nDocument guard ordering and test caster rejection, guarded calls, by-value parameter destruction, and extraction before GIL release.\n\n* test: make call guard caster extraction const\n\n* test: explain moved-from lifetime logging [skip ci]\n\n---------\n\nCo-authored-by: Justin Turney \u003cjustin.turney@gmail.com\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "9de3643672a88422dd7f5251286a63698974ecb2",
      "tree": "aa576c66d0add98d369facae3870cb12fba0e573",
      "parents": [
        "bd99d60b437004fec01c582dc52e8c6d962029e7"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Wed Oct 07 14:38:42 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 14:38:42 2026 -0400"
      },
      "message": "chore(deps): bump the actions group across 1 directory with 2 updates (#6186)\n\nBumps the actions group with 2 updates in the / directory: [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).\n\n\nUpdates `astral-sh/setup-uv` from 10.0.1 to 10.2.0\n- [Release notes](https://github.com/astral-sh/setup-uv/releases)\n- [Commits](https://github.com/astral-sh/setup-uv/compare/v10.0.1...v10.2.0)\n\nUpdates `scientific-python/upload-nightly-action` from 0.6.4 to 0.6.5\n- [Release notes](https://github.com/scientific-python/upload-nightly-action/releases)\n- [Commits](https://github.com/scientific-python/upload-nightly-action/compare/e76cfec8a4611fd02808a801b0ff5a7d7c1b2d99...16fa02eacee1655195143de09f03676e60ef2bf5)\n\n---\nupdated-dependencies:\n- dependency-name: astral-sh/setup-uv\n  dependency-version: 10.2.0\n  dependency-type: direct:production\n  update-type: version-update:semver-minor\n  dependency-group: actions\n- dependency-name: scientific-python/upload-nightly-action\n  dependency-version: 0.6.5\n  dependency-type: direct:production\n  update-type: version-update:semver-patch\n  dependency-group: actions\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "bd99d60b437004fec01c582dc52e8c6d962029e7",
      "tree": "a150ce9012c95e2eadb2cddc7439a80753d7900b",
      "parents": [
        "46bfd9997ddb993d2b59d5a790d6a467d7889841"
      ],
      "author": {
        "name": "Jad Fahmi",
        "email": "jadfahmi07@gmail.com",
        "time": "Wed Oct 07 23:45:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 11:45:58 2026 -0400"
      },
      "message": "fix: return None for null Eigen matrix pointers (#6184)"
    },
    {
      "commit": "46bfd9997ddb993d2b59d5a790d6a467d7889841",
      "tree": "6864c74a59596d3aa962ab423e5a1fcb3dd04f79",
      "parents": [
        "8434567daadde4e87db9dcd966155abc032755d1"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Tue Oct 06 16:45:39 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 06 16:45:39 2026 -0400"
      },
      "message": "chore: start 3.2.0a0 development and block final-version nightlies (#6191)\n\nMaster was left at 3.1.0 final, so nightly wheels had the same version as\nthe PyPI release. Bump to 3.2.0a0 and make the nightly upload fail when a\nwheel does not have a prerelease version.\n\nFixes #6182.\n\nAssisted-by: ClaudeCode:claude-opus-5-5"
    },
    {
      "commit": "8434567daadde4e87db9dcd966155abc032755d1",
      "tree": "8e2b652543caf695ea5624bf642c7827d9d923e9",
      "parents": [
        "1c25312df107a3f94db0ac634b9748e638424e95"
      ],
      "author": {
        "name": "pre-commit-ci[bot]",
        "email": "66853113+pre-commit-ci[bot]@users.noreply.github.com",
        "time": "Tue Oct 06 11:58:25 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 06 11:58:25 2026 -0400"
      },
      "message": "chore(deps): update pre-commit hooks (#6194)\n\nupdates:\n- [github.com/pre-commit/mirrors-clang-format: v23.1.0 → v23.1.2](https://github.com/pre-commit/mirrors-clang-format/compare/v23.1.0...v23.1.2)\n- [github.com/astral-sh/ruff-pre-commit: v0.16.6 → v0.16.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.16.6...v0.16.10)\n- [github.com/pre-commit/mirrors-mypy: v2.3.1 → v2.4.0](https://github.com/pre-commit/mirrors-mypy/compare/v2.3.1...v2.4.0)\n- [github.com/adhtruong/mirrors-typos: v1.50.1 → v1.50.3](https://github.com/adhtruong/mirrors-typos/compare/v1.50.1...v1.50.3)\n- [github.com/PyCQA/pylint: v4.0.8 → v4.1.2](https://github.com/PyCQA/pylint/compare/v4.0.8...v4.1.2)\n- [github.com/python-jsonschema/check-jsonschema: 0.38.0 → 0.38.2](https://github.com/python-jsonschema/check-jsonschema/compare/0.38.0...0.38.2)\n\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "1c25312df107a3f94db0ac634b9748e638424e95",
      "tree": "de86aeb02160e57a598eaef4f76dcd74a26808e8",
      "parents": [
        "a968c2755e68ba71f7ddd221420a7d9dacba7bd1"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Tue Oct 06 01:02:48 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:02:48 2026 -0700"
      },
      "message": "fix: only cache the internals pp after a successful lookup (#6190)\n\n* fix: only cache the internals pp after a successful lookup\n\nIn get_pp(), last_istate_tls was set before get_or_create_pp_in_state_dict().\nIf that call threw, the thread cache matched the interpreter but held a null\npp, so later calls returned nullptr (\"get_internals: get_pp() returned\nnullptr\"). Seen intermittently on MinGW in\ntest_import_in_subinterpreter_concurrently.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* test: cover internals cache retries after failed lookup\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "a968c2755e68ba71f7ddd221420a7d9dacba7bd1",
      "tree": "01f5a1445e4749c512f5641c035ab7c165fae18c",
      "parents": [
        "e0cd29d343d23ea865606250c69f84fea7404177"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Oct 05 09:43:29 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 09:43:29 2026 -0400"
      },
      "message": "chore(deps): bump urllib3 from 2.7.0 to 2.8.0 in /docs (#6188)\n\nBumps [urllib3](https://github.com/urllib3/urllib3) from 2.7.0 to 2.8.0.\n- [Release notes](https://github.com/urllib3/urllib3/releases)\n- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)\n- [Commits](https://github.com/urllib3/urllib3/compare/2.7.0...2.8.0)\n\n---\nupdated-dependencies:\n- dependency-name: urllib3\n  dependency-version: 2.8.0\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "e0cd29d343d23ea865606250c69f84fea7404177",
      "tree": "59a549149f9c7d761473c60166b0412fd4b02f68",
      "parents": [
        "7a57de5980d53cd81e363a02602909176855103a"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Mon Oct 05 00:04:01 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 04 21:04:01 2026 -0700"
      },
      "message": "fix(smart_holder): keep void-cast semantics in from_unique_ptr (#6163)\n\n* fix(smart_holder): keep void-cast semantics in from_unique_ptr\n\nFixes item 4 of #6159.\n\n* test: cover base unique_ptr factories and trampoline lifetime\n\n* test: limit prompt trampoline destruction check to CPython\n\n* docs: clarify smart_holder void-cast ownership safeguard\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "7a57de5980d53cd81e363a02602909176855103a",
      "tree": "10ebc72d558ebe3765f47b9ffb7b370e88571aca",
      "parents": [
        "f21c591b5801ff79544d2b594afc6eb7250c6e6f"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Oct 03 13:56:12 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 13:56:12 2026 -0400"
      },
      "message": "[feat/precompile-tooling] docs: document the opt-in precompiled mode (#6138)\n\n* docs: document the opt-in precompiled mode\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* chore: lint the -inl.h invariants of the precompiled mode\n\ntools/check_inl_headers.py checks that each namespace-scope definition\nin an -inl.h file has PYBIND11_INLINE, and that each macro in a\npreprocessor condition is known: either the same for the library and\nthe module, or encoded in the precompiled config guard. Also document\nthat a custom PYBIND11_NAMESPACE must reach the library.\n\nAssisted-by: ClaudeCode:claude-opus-5-5\n\n* docs: note the call overhead of a non-LTO precompiled library\n\nRelease build, trivial bound functions, against an LTO header-only\nmodule: AppleClang arm64 adds 2-4 ns per call (7-11%), GCC 15 Linux\naarch64 adds 1-2 ns (1-7%). With LTO on the library, both are within a\nfew percent.\n\nAssisted-by: ClaudeCode:claude-opus-5-5"
    },
    {
      "commit": "f21c591b5801ff79544d2b594afc6eb7250c6e6f",
      "tree": "b6932501e7285d9eb092226cff7f0982456c09ac",
      "parents": [
        "94269814a6842edc3b981597376a355d2ef60237"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Oct 03 13:56:12 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 13:56:12 2026 -0400"
      },
      "message": "feat: expose the precompiled-mode sources to non-CMake builds (#6137)\n\nAdds pybind11.get_source_dir() / python -m pybind11 --srcdir and a\nsrcdir variable in pybind11.pc, so build systems such as Meson can\ncompile src/pybind11_combined.cpp with PYBIND11_PRECOMPILED defined.\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "94269814a6842edc3b981597376a355d2ef60237",
      "tree": "68d155980fad8611253a1ac00e27a6d89d051d63",
      "parents": [
        "ba6d80ee9903fb10b40bc9454d42421e907641cb"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Oct 03 13:56:11 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 13:56:11 2026 -0400"
      },
      "message": "[feat/precompile-internals] feat: move pybind11.h non-template definitions to pybind11-inl.h (#6136)\n\n* feat: move pybind11.h non-template definitions to pybind11-inl.h\n\nThe headline of the split: cpp_function\u0027s make_function_record,\ninitialize_generic, destruct, and the 440-line dispatcher move out of\nline, along with generic_type::initialize, enum_base, the function\nsignature generators, module cache helpers, keep_alive_impl,\nget_type_override, error_already_set::what, and detail::print. The\ntemplated initialize(), descr.h machinery, and the module/class_ API\nstay in the header.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* fix: drop redundant redeclarations in pybind11.h\n\nThese functions are already declared in function_record_pyobject.h,\nattr.h, and type_caster_base.h; GCC 13 -Wredundant-decls rejects the\nrepeats.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* fix: keep call_operator_delete(void*) inline in precompiled mode\n\nIt selects the aligned and sized operator delete from C++ feature macros.\nThe precompiled library can use a different C++ standard than the module\nthat allocated the object, so the deallocation must be compiled with the\nmodule.\n\nAssisted-by: ClaudeCode:claude-opus-5-5"
    },
    {
      "commit": "ba6d80ee9903fb10b40bc9454d42421e907641cb",
      "tree": "c0291f1a524e3a77a530fe3be424ca3baacab351",
      "parents": [
        "40e87a38294217350286de86d1c793eb3be4fb3a"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Oct 03 13:56:11 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 13:56:11 2026 -0400"
      },
      "message": "[feat/precompile-type-caster-base] feat: move internals.h, exception_translation.h, and pybind11_fail out of line (#6135)\n\n* feat: move internals.h, exception_translation.h, and pybind11_fail out of line\n\nThe internals accessor family (get_internals, ensure_internals, the\nlocal-internals key and capsules, exception translators) moves into\ninternals-inl.h; per-module identity is unchanged because the\nfunction-local statics move with their functions into whatever binary\neach module links. Also adds common-inl.h (pybind11_fail) and\nexception_translation-inl.h. Tiny hot accessors and all templates stay\nin the headers.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* fix: drop duplicate translate_exception declaration\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "40e87a38294217350286de86d1c793eb3be4fb3a",
      "tree": "b8d82ebbe400b0beb7a20bf80d14447b612543b5",
      "parents": [
        "76ad1f35644a1cc39f95e97024128245dedc6a5c"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Oct 03 13:56:11 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 13:56:11 2026 -0400"
      },
      "message": "[feat/precompile-class] feat: move type_caster_base.h non-template definitions to type_caster_base-inl.h (#6134)\n\n* feat: move type_caster_base.h non-template definitions to type_caster_base-inl.h\n\nMoves the free functions (type-info lookup and registration, instance\nlayout, isinstance_generic, cpp_conduit_method, type_info_description),\nthe loader_life_support members (the function-local thread_local stack\nstays per-module in both modes), and the two heavy type_caster_generic\nmembers (the type_info constructor and the main cast overload).\nTemplates, including load_impl\u003c\u003e, stay in the header.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* fix: make gil.h self-contained for PyPy/GraalPy and silence -Wredundant-decls\n\ngil.h evaluated PYBIND11_SIMPLE_GIL_MANAGEMENT before including common.h,\nwhich defines it on PyPy/GraalPy. Every existing TU included common.h\nfirst through pybind11.h, so this only surfaced when src/type_caster_base.cpp\nreached gil.h directly. Also suppress GCC -Wredundant-decls for the\nisinstance_generic declaration duplicated in pytypes.h.\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "76ad1f35644a1cc39f95e97024128245dedc6a5c",
      "tree": "e0d431e38058327ac3300307b4c6a3be6c97040c",
      "parents": [
        "b143f6cdb6f15020da434220d20eccbfcdde6b9e"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Oct 03 13:56:10 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 13:56:10 2026 -0400"
      },
      "message": "[feat/precompile-pytypes] feat: move detail/class.h definitions to class-inl.h (#6133)\n\n* feat: move detail/class.h definitions to class-inl.h\n\nAll 32 functions in detail/class.h are non-template plumbing (type/slot\nmachinery); move them out of line for the precompiled mode. Forward\ndeclarations of these functions in other headers lose their inline\nkeyword to stay ODR-consistent in both modes.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* fix: suppress -Wredundant-decls for class.h declarations\n\nSeveral functions are forward-declared in headers that cannot include\nclass.h; GCC\u0027s -Wredundant-decls (used in CI cxx_flags) flags the\nsecond declaration.\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "b143f6cdb6f15020da434220d20eccbfcdde6b9e",
      "tree": "e1522e47c8a58a3b832ea9d5587e9e6c2c5e850b",
      "parents": [
        "ef7892d7f289e245773ff870acbabefd0b230184"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Oct 03 13:56:10 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 13:56:10 2026 -0400"
      },
      "message": "[feat/precompile-macro-infra] feat(cmake): opt-in precompiled static library, starting with pytypes.h (#6132)\n\n* feat(cmake): opt-in precompiled pybind11 static library, starting with pytypes.h\n\nSplit the out-of-line pytypes.h definitions into pytypes-inl.h (fmtlib/\nCLI11 style): inline by default, compiled once into a per-project static\nlibrary when PYBIND11_PRECOMPILED is defined. Infrastructure:\n\n- pybind11_precompile() creates the lazy pybind11::precompiled STATIC\n  library from the installed or in-tree src/ sources; PRECOMPILE /\n  NO_PRECOMPILE keywords on pybind11_add_module and a global\n  PYBIND11_PRECOMPILE switch select it per target.\n- A link-time guard symbol encodes PYBIND11_INTERNALS_VERSION,\n  Py_GIL_DISABLED, PYBIND11_SIMPLE_GIL_MANAGEMENT, and\n  PYBIND11_DETAILED_ERROR_MESSAGES, so a configuration mismatch is one\n  readable undefined symbol.\n- src/ is installed to share/pybind11/src (wheel stays pure);\n  src/pybind11_combined.cpp is a single-TU build for non-CMake use.\n- Tests: PYBIND11_TEST_PRECOMPILE builds the whole suite against the\n  library, two new test_cmake_build cases, packaging file lists, tidy\n  preset, and a 3-platform CI job.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* fix(tidy): keep the tidy preset header-only\n\nIn precompiled mode the -inl.h definitions are intentionally\nnon-inline, so misc-definitions-in-headers fires on every one. The\nheader-only tidy build already analyzes all -inl.h bodies via the\nbottom-of-header includes.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* fix(cmake): compile the precompiled library with the interpreter ABI macros\n\npybind11::pybind11 only carries headers; Py_GIL_DISABLED lives on\nPython::Module via pybind11::module. Without it the library is\nABI-mismatched on free-threaded builds, and on Windows the pyconfig.h\nautolink pragma in its objects requests pythonXY.lib instead of\npythonXYt.lib.\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "ef7892d7f289e245773ff870acbabefd0b230184",
      "tree": "c8a1cfcbc5ec90b4e5af114756afc5bc97973df7",
      "parents": [
        "bf21a6dfe775edbd53dce32057cf907fe6e6c064"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Oct 03 13:56:09 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 13:56:09 2026 -0400"
      },
      "message": "feat: add PYBIND11_NOINLINE_ATTR and PYBIND11_INLINE macros (#6131)\n\nDecompose PYBIND11_NOINLINE into the attribute part plus inline, and\nadd PYBIND11_INLINE, which becomes empty under PYBIND11_PRECOMPILED.\nGroundwork for optional pre-compilation; all current expansions are\nunchanged and PYBIND11_INLINE is not used yet.\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "bf21a6dfe775edbd53dce32057cf907fe6e6c064",
      "tree": "f97488c74b9c5fc7ce8eae02ea3f7eb77738fb60",
      "parents": [
        "43c8226119919e30b2a7073e320f48b296fa2eef"
      ],
      "author": {
        "name": "Junhyung Lee",
        "email": "70549809+espressolee@users.noreply.github.com",
        "time": "Thu Sep 24 02:20:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 14:20:31 2026 -0400"
      },
      "message": "test: assert line numbers of evaluated source (#6169)\n\n* test: assert line numbers of evaluated source\n\n#6089 dropped the coding cookie prepended to py::eval/py::exec source,\nwhich had shifted reported SyntaxError and traceback line numbers by one,\nand noted that no test asserted on them. Add one: errors on line 2 of the\nevaluated source must report line 2. With pybind11\u0027s own test target the\nnew test reports (3, 3) against the parent of #6089 and (2, 2) with the fix.\n\nCo-Authored-By: Claude Fable 5.1 \u003cnoreply@anthropic.com\u003e\n\n* style: pre-commit fixes\n\n---------\n\nCo-authored-by: Claude Fable 5.1 \u003cnoreply@anthropic.com\u003e\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "43c8226119919e30b2a7073e320f48b296fa2eef",
      "tree": "f6ea6c5cef8e6c10abfa38bd391052386ebdb881",
      "parents": [
        "296d5d1d3664dd0e0616e81920342e56b7249171"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Wed Sep 23 14:16:44 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 14:16:44 2026 -0400"
      },
      "message": "chore(deps): bump soupsieve from 2.8.4 to 2.9 in /docs (#6181)\n\nBumps [soupsieve](https://github.com/facelessuser/soupsieve) from 2.8.4 to 2.9.\n- [Release notes](https://github.com/facelessuser/soupsieve/releases)\n- [Commits](https://github.com/facelessuser/soupsieve/compare/2.8.4...2.9)\n\n---\nupdated-dependencies:\n- dependency-name: soupsieve\n  dependency-version: \u00272.9\u0027\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "296d5d1d3664dd0e0616e81920342e56b7249171",
      "tree": "e15f3172d30f58173f017940be37c596aa2657b0",
      "parents": [
        "63121f7b01c88717971233a3937e8869c2947c57"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Thu Sep 17 01:30:23 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 17 01:30:23 2026 -0700"
      },
      "message": "fix: Clean sibling storage after old-style init (#6180)"
    },
    {
      "commit": "63121f7b01c88717971233a3937e8869c2947c57",
      "tree": "97617e7018ea190fc3ad57047d9b2c6870df5d52",
      "parents": [
        "80f435b8c79b4cab35b1151da1a6b768d19aa70d"
      ],
      "author": {
        "name": "Andrew James",
        "email": "Andrew.m.james2@gmail.com",
        "time": "Tue Sep 15 17:05:42 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 15 15:05:42 2026 -0700"
      },
      "message": "fix: Narrow conditions for `load_value` to give invalid address (#6157)\n\n* fix: Guard against using a uninitialized value after `__new__` allocating python object\n\nfixes: #6153\n\nObjects initialized with `cls.__new__(cls)` (`cls` is a pybind11 bound\ntype). Will not have the C++ object allocated. When hitting `load_value`\nstorage is allocated but not initialized, calling a virtual method will\nload a garbage vptr and segfault. This is similar to #2152, but the\nguard in metaclass `__call__` is not triggered when using `__new__`.\n\nProtect against giving a pointer to garbage in all cases except the\n`__init__` + `__setstate__` path.\n\nAuthored with claude\n\n* fix: free lazily allocated storage on failed init and only permit lazy allocation for old-style constructors\n\nIf an old-style placement-new `__init__`/`__setstate__` failed after\n`self` was loaded, the lazily allocated storage stayed behind with a\nnull-holder instance, so the uninitialized-value guard never fired again\nand later use read uninitialized memory. `instance_construction_scope`\nnow tracks the constructor\u0027s `value_and_holder` and frees storage that\nwas lazily allocated during a construction that did not complete.\n\nAlso arm the scope only when the overload chain contains an old-style\nconstructor. New-style constructors receive `self` directly and never\nneed lazy allocation, so reentrant loads of the half-built instance now\nraise `ValueError` instead of handing out uninitialized storage.\n\nAssisted-by: ClaudeCode:claude-fable-5\nClaude-Session: https://claude.ai/code/session_01TQXCSykMn5EL7sc6VgTUTC\n\n* fix: isolate old-style constructor storage\n\nTrack construction per value-and-holder, grant a one-shot loader-frame permission only to the exact legacy constructor self conversion, and keep its raw storage private until the native callback returns.\n\nReject reentrant, nested, cross-base, and cross-thread loads while preserving overload fallback, failure cleanup, pickle setstate callbacks, and repeated initialization behavior.\n\n* test: skip constructor thread test on Emscripten\n\n* fix: bump internals version to 13\n\nThe new detail::instance construction state has cross-DSO semantics that internals-v12 modules do not understand. Isolate the incompatible domains for v3.2.0 and document that future structural or semantic instance changes require another bump.\n\n* Revert \"fix: bump internals version to 13\"\n\nThis reverts commit 14e32ae23af529df8d82681c2d3064884b259a3c.\n\n* fix: recover from legacy constructor storage collisions\n\n* test: fix collision subprocess imports\n\n* refactor: simplify old-style constructor storage tracking\n\nThe loader frame already identifies the constructor candidate, so the\none-shot `self` permission only needs a frame match and a claimed flag.\nThis removes both argument guard classes, the changes to cast.h, and the\nper-call TLS lookups they added.\n\nAlso:\n- Hoist deallocate_instance_value to a detail free function and use it\n  from instance_construction_scope.\n- Take the dispatcher\u0027s constructor lock before the construction scope and\n  drop the nested critical sections it made redundant.\n- Keep the non-constructor path inline: the loader destructor checks for\n  storage before the out-of-line cleanup, and the construction scope\n  defaults to not started.\n- Commit old-style storage once in cpp_function::initialize, gated on\n  is_constructor.\n- Share one __index__ probe across the reentrancy tests and turn the\n  subprocess script into a plain function.\n\nAssisted-by: ClaudeCode:claude-fable-5-1\n\n* test: reject later self alias during old-style init\n\n* fix: restrict old-style constructor self permission to self\u0027s own load phase\n\nThe one-shot `self` permission granted by `loader_life_support` matched only the\nframe and the value slot, not the *phase* of the load. The slot is identified by\nthe instance, so any later argument that aliases the same, still-unconstructed\n`self` matched too, consumed the reservation, and reached C++ over raw storage.\n\nTrack the frame\u0027s phase instead: authorize the load of positional argument 0\n(the typed-`self` variant) and casts performed from within the C++ callable (the\nlegacy `py::object`-self variant), and deny every load during conversion of\npositional arguments \u003e\u003d 1. `argument_loader` reports the argument index, and the\ndispatcher flips the frame to the callable phase once loading is done. The frame\npointer is resolved once in the dispatcher, where `is_constructor` is known, so\nno non-constructor call pays a thread-local lookup.\n\nThis restores the restriction that 89a5f72e dropped, re-enabling the regression\ntest added in 7a7e9f34, and adds three more tests. Both new negative tests\nassert the decisive observable rather than only that the callback was entered,\nand both use types chosen so that a build where the guard has regressed reports\nan assertion failure instead of crashing during teardown:\n\n- A later argument typed as a *base* of the class under construction. It shares\n  the value slot, so it matched, and the reservation was then sized from the\n  base\u0027s `type_info`: 16 bytes for a 144-byte derived object. Because the claim\n  is one-shot it also denied `self` its own storage, so the callback could not\n  placement-new at all; the value was nevertheless committed, and destroying it\n  ran a virtual destructor over never-constructed memory. The test asserts that\n  no reservation was made at the base\u0027s size.\n- The still-unconstructed `self` reached through a container argument. Here\n  `stl.h`\u0027s element caster copy-constructs, so the read of uninitialized memory\n  happens inside pybind11 and no binding author can guard against it. The test\n  counts copy constructions whose source was raw storage and asserts zero; the\n  instrumented copy constructor does not read its source, so the test itself\n  performs no uninitialized read.\n- A positive test pinning the case that must keep working: a later argument that\n  is a different, already-constructed instance of the same class.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* style: pre-commit fixes\n\n* style: clang-tidy fixes\n\nThe Clang-Tidy job failed on two `modernize-use-default-member-init`\ndiagnostics in tests/test_class.cpp, both introduced by this branch:\n\n    tests/test_class.cpp:167:18: error: use default member initializer\n      for \u0027payload\u0027 [modernize-use-default-member-init,-warnings-as-errors]\n    tests/test_class.cpp:177:9: error: use default member initializer\n      for \u0027value\u0027 [modernize-use-default-member-init,-warnings-as-errors]\n\nApplied exactly the replacements clang-tidy emitted:\n\n- `AliasStealDerived::payload` gains a `{}` default member initializer\n  and drops `payload{}` from the constructor initializer list. Both\n  value-initialize the array.\n- `ContainerAliasItem::value` gains a `{-1}` default member initializer\n  and the copy constructor drops `value(-1)`. The converting constructor\n  keeps `value(v)`, which overrides the default, so both constructors\n  still produce the values the container-alias test asserts on.\n\nNo behavior change; clang-tidy is not installed locally, so the fix-its\nwere transcribed from the CI diagnostic rather than auto-applied, and\nthe translation unit was compiled clean at -std\u003dc++17 with the CI\nwarning set.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* fix: GraalPY exceptions\n\nBoth GraalPy jobs failed on the same assertion in the legacy-v12\ncollision test:\n\n    tests/test_class.py:469: assert stats() \u003d\u003d (3, 3, constructed + 1, constructed + 1)\n\nThat is the final check, reached after `del obj` and two `gc.collect()`\ncalls. GraalPy is not refcounted and does not guarantee finalization\nfrom `gc.collect()`, so the destruction counters lag and the assertion\nfails while every preceding assertion in the loop passes.\n\nGate only that assertion behind `if not env.GRAALPY:`. This follows the\nexisting convention in the suite, where GC-timing-dependent checks are\nexempted on GraalPy with the same \"Cannot reliably trigger GC\" reason\n(test_call_policies.py, test_callbacks.py,\ntest_class_sh_trampoline_shared_ptr_cpp_arg.py, and others).\n\nNothing this branch introduces stops being tested on GraalPy. The gated\nline only observes ordinary teardown of a normal, fully constructed\nretry object. The rollback properties the test exists for are pinned by\nthe assertions above it, which still run everywhere: after rollback both\ncollision allocations are freed with no spurious destruction, and after\nthe retry exactly one allocation is live with the private value\u0027s\ndestructor having run neither early nor twice.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* test: pin the two gaps identified in the load-phase review\n\nAdds coverage for the two limitations called out in the review of the\nload-phase restriction. Both tests pass, pinning today\u0027s behavior; both\nfail against `master`\u0027s headers, which is what makes them meaningful.\n\ntest_old_style_init_value_error_hides_later_overload\n\n  Two old-style candidates take the same two Python arguments. The\n  first one\u0027s argument 1 is the `self` alias that the construction\n  guard rejects; the second matches the same call and constructs.\n  The guard reports rejection with `value_error`, and only\n  `reference_cast_error` becomes PYBIND11_TRY_NEXT_OVERLOAD, so the\n  throw escapes the overload loop and the second candidate is never\n  attempted.\n\n  Verified counterfactual, same test files built against master\u0027s\n  headers: master reaches the second candidate and constructs\n  (`entered \u003d\u003d [\"second candidate entered\"]`); here the call raises\n  ValueError with `entered \u003d\u003d []`.\n\n  Note this is a new trigger for pre-existing behavior rather than a\n  new behavior: master\u0027s casters already throw `value_error` from load\n  paths with the same non-fallthrough consequence.\n\ntest_old_style_init_callable_phase_grant_is_not_self_specific\n\n  While the callable runs, the one-shot grant is keyed on the value\n  slot, not on the `self` handle, so a cast of `stash[0]` claims the\n  reservation and the genuine `self` cast then fails. Narrowing the\n  grant to \"a cast of the `self` object\" would not close this: the\n  claiming cast targets the same Python object as `self`, so the two\n  are indistinguishable at cast time.\n\n  Verified counterfactual: on master both casts succeed\n  (`[\"stash cast claimed the reservation\", \"self cast succeeded\"]`)\n  because every load lazily allocates. The one-shot reservation is\n  therefore a narrowing of master\u0027s behavior, and this gap is the\n  residue rather than a regression.\n\nNeither callback inspects the reference it obtains over storage whose\nlifetime has not begun, so the tests themselves stay free of undefined\nbehavior. Both verify the object is still retryable afterwards.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* perf: only test the old-style frame pointer where the phase can change\n\nAddresses the review suggestion to stop paying the null check once per\nargument.\n\nThe literal form suggested, `I \u003d\u003d 0 \u0026\u0026`, is not safe: `begin_argument_load`\nis what moves the frame from `self_argument` to `later_argument`, so\nskipping it for arguments 1 and up leaves the phase at `self_argument` for\nthe whole argument list. That re-opens exactly the hole 955cb193 closed. It\nregresses four tests:\n\n    test_old_style_init_does_not_authorize_later_self_alias\n    test_old_style_init_does_not_authorize_base_typed_later_alias\n    test_old_style_init_does_not_authorize_self_alias_inside_container\n    test_old_style_init_value_error_hides_later_overload\n\nGate on `I \u003c 2` instead. The phase only changes at argument 0 and argument\n1; from argument 2 on it is already `later_argument`, so those arguments\nneed no call and no test. Two checks per call rather than one, but it is\nthe minimum that preserves the invariant. All 55 tests pass.\n\n`I` is a template parameter, so no `if constexpr` is needed and none can be\nused: pybind11 still supports C++11 and `if constexpr` is a C++17\nextension there. A plain `if` on a constant condition already folds\ncompletely. clang -O2, the `I \u003d\u003d 5` instantiation of a reduction of this\nfunction tail-calls straight through with no pointer test emitted, while\n`I \u003d\u003d 0` and `I \u003d\u003d 1` keep theirs.\n\nMSVC C4127 (constant conditional) is already disabled file-wide at the top\nof cast.h, and the header compiles clean at -std\u003dc++11/14/17/20 with\n-Wall -Wextra -Wpedantic -Wconversion -Werror.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* docs: describe status_value_constructing with the other status bits\n\nThe non-simple layout comment enumerated status_holder_constructed and\nstatus_instance_registered but not status_value_constructing, which was\nadded alongside them. Addresses the review comment on that block.\n\nAlso states what the bit means for readers of the value pointer: while it\nis set, the pointer must not be treated as denoting a live C++ object.\nThat is the invariant the rest of this change depends on, and the status\nbyte is where someone will look for it.\n\nComment-only. Longest line is 94 columns, within the 99-column limit, so\nclang-format does not reflow it.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* style: pre-commit fixes\n\n* style: clang-tidy/format\n\n* fix: narrow uninitialized-instance guard to direct misuse\n\nReturn to the minimal scope needed for #6153: ordinary loads of a wrapper with no constructed C++ value raise ValueError, while overload chains containing deprecated placement-new constructors retain their historical lazy allocation. Failed old-style construction also frees lazily allocated storage so the object remains guarded and retryable.\n\nRemove the expanded per-value construction protocol, including private candidate storage, argument and callable phases, cross-thread locking, and stale-v12 collision recovery. Those mechanisms attempted to make deprecated placement-new construction safe under reentry rather than fixing direct __new__ misuse.\n\nAccordingly, remove tests requiring special handling for later arguments (both distinct instances and self aliases), base-typed and container aliases, nested initialization, Python multiple-inheritance bases, concurrent access, mixed old/new overloads, and old-style __setstate__ reentry. Also remove tests pinning protocol-specific overload fallthrough, callable-phase grants, and legacy-v12 collision cleanup.\n\nKeep focused coverage for direct __new__ misuse, reentry during new-style construction, deprecated __init__/__setstate__ compatibility, failed-construction cleanup, and successful retry.\n\n* test: characterize old-style reentrant load limitation\n\nKeep one pointer-only probe for the historical broad lazy-allocation window. It records the known hazard that a reentrant load can expose a pointer to unconstructed storage, without inspecting or dereferencing that storage.\n\nThe cleanup and retry assertions remain in place so the behavior retained by the minimal fix stays covered.\n\n* docs: document deprecated placement-new limitations\n\nExplain that the compatibility window spans an entire constructor overload chain and can expose unconstructed storage during reentrant conversion or callbacks, nested initialization, Python multiple inheritance, or concurrent access.\n\nRecommend new-style constructor and pickle APIs, and add source-level references at the compatibility flag and scope so future changes encounter the accepted limitations and rationale before attempting to narrow the window.\n\n---------\n\nCo-authored-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e\nCo-authored-by: Andrew M. James \u003cajames@openteams.com\u003e\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "80f435b8c79b4cab35b1151da1a6b768d19aa70d",
      "tree": "7b00cf878c89cd525c503efa798078fb65a7f57b",
      "parents": [
        "8d16d2084a37adc5ce400dc3411386ae38bfd365"
      ],
      "author": {
        "name": "Trim21",
        "email": "trim21.me@gmail.com",
        "time": "Tue Sep 15 17:06:41 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 15 02:06:41 2026 -0700"
      },
      "message": "fix: re-acquire the GIL in class_::init_instance before instance registration (#6172)\n\n* fix: re-acquire GIL in init_instance for thread-safe instance registration\n\nWith a factory-based py::init combined with py::call_guard\u003cpy::gil_scoped_release\u003e,\ninit_instance -\u003e register_instance runs while the GIL is released, racing on\ninternals.registered_instances with GIL-holding threads. This corrupts the\ninstance map and leads to \u0027pybind11_object_dealloc(): Tried to deallocate\nunregistered instance!\u0027 -\u003e std::terminate. Acquire the GIL (no-op if already\nheld) in both class_::init_instance overloads; free-threaded builds keep using\ntheir sharded mutex and are unaffected.\n\n* tests: avoid std::make_unique in test_gil_scoped (C++14 only)\n\nThe iOS/Android wheel CI jobs build the test suite with -std\u003dgnu++11.\n\n* tests: skip test_init_factory_gil_released_concurrent_construction on free-threaded builds\n\nOn free-threaded builds py::gil_scoped_release detaches the thread state and the\nconstructor machinery is not safe when called detached, so the test segfaults\n(pre-existing limitation of call_guard\u003cgil_scoped_release\u003e, unrelated to the\ninit_instance fix). The instance map is mutex-protected on free-threaded builds\nanyway, so there is nothing to test there. An early return inside the function\ncovers the _run_in_process parametrizations, where pytest skip markers do not\napply.\n\n* tests: run the init_instance race regression only as a direct test\n\nThe test was in ALL_BASIC_TESTS, so it also ran in the _run_in_process\nparametrizations, whose subprocesses impose a 10s timeout; on Windows\n(sequential variant) the extra sleep timer granularity and GIL handoff\noverhead pushed that over the limit. It is a data-race regression, not a\ndeadlock check, so define it after ALL_BASIC_TESTS like the\ntest_run_in_process_* functions and drop the now-unneeded free-threaded\nearly return.\n\n* chore: retrigger CI (GCC 9 job failed on apt 404 for python3-setuptools, unrelated)\n\n* fix: make init_instance GIL acquisition unconditional\n\nThe `#if !defined(Py_GIL_DISABLED)` guards skipped the acquire on free-threaded builds, where `gil_scoped_release` detaches the thread state. `init_instance` then crashes in `PyCriticalSection_BeginMutex` (via `get_type_info`) even single-threaded, because the critical section requires an attached thread state.\n\n`gil_scoped_acquire` attaches the thread state without taking a global lock, so this is safe on free-threaded builds and does not serialize threads.\n\n* test: run init_instance regression on free-threaded builds too\n\nThe acquire in init_instance is now unconditional, so the regression test also covers the free-threaded detached-thread-state crash. Drop the PY_GIL_DISABLED skip.\n\n* docs: cover free-threaded thread-state attach in init_instance comments\n\nThe unconditional gil_scoped_acquire is also needed on free-threaded builds, where gil_scoped_release detaches the thread state and get_type_info requires it to be attached. Mention this in the init_instance comment and the regression-test docstring."
    },
    {
      "commit": "8d16d2084a37adc5ce400dc3411386ae38bfd365",
      "tree": "7023c67501f4fb855d3180ba837fca3f9b19bf7c",
      "parents": [
        "74839a58382dc95586291008874a0f3a42ccc09a"
      ],
      "author": {
        "name": "Michael Šimáček",
        "email": "michael.simacek@oracle.com",
        "time": "Sun Sep 13 22:04:02 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 13:04:02 2026 -0700"
      },
      "message": "Add GraalPy 3.13 (25.3) to the testing matrix (#6166)\n\n* Add GraalPy 3.13 (25.3) to the testing matrix\n\n* Update numpy version used by test on GraalPy\n\n* Unmark fixed xfail"
    },
    {
      "commit": "74839a58382dc95586291008874a0f3a42ccc09a",
      "tree": "7011aad0b04289a965a04055d257b54964136a9a",
      "parents": [
        "e856bbfe67e56f133913f5216bb18a2feb68f864"
      ],
      "author": {
        "name": "pre-commit-ci[bot]",
        "email": "66853113+pre-commit-ci[bot]@users.noreply.github.com",
        "time": "Sun Sep 13 12:35:01 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 12:35:01 2026 -0700"
      },
      "message": "chore(deps): update pre-commit hooks (#6173)\n\n* chore(deps): update pre-commit hooks\n\nupdates:\n- [github.com/pre-commit/mirrors-clang-format: v22.1.8 → v23.1.0](https://github.com/pre-commit/mirrors-clang-format/compare/v22.1.8...v23.1.0)\n- [github.com/astral-sh/ruff-pre-commit: v0.16.1 → v0.16.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.16.1...v0.16.6)\n- [github.com/pre-commit/mirrors-mypy: v2.3.0 → v2.3.1](https://github.com/pre-commit/mirrors-mypy/compare/v2.3.0...v2.3.1)\n- [github.com/adhtruong/mirrors-typos: v1.48.0 → v1.50.1](https://github.com/adhtruong/mirrors-typos/compare/v1.48.0...v1.50.1)\n- [github.com/shellcheck-py/shellcheck-py: v0.11.0.1 → v0.11.0.1-1](https://github.com/shellcheck-py/shellcheck-py/compare/v0.11.0.1...v0.11.0.1-1)\n- [github.com/PyCQA/pylint: v4.0.6 → v4.0.8](https://github.com/PyCQA/pylint/compare/v4.0.6...v4.0.8)\n- [github.com/python-jsonschema/check-jsonschema: 0.37.4 → 0.38.0](https://github.com/python-jsonschema/check-jsonschema/compare/0.37.4...0.38.0)\n\n* style: pre-commit fixes\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crwgkio@gmail.com\u003e"
    },
    {
      "commit": "e856bbfe67e56f133913f5216bb18a2feb68f864",
      "tree": "f7e67e5e676cc369fe8c6e5141ac88881349ad7c",
      "parents": [
        "d87cf0b873e42f0e541a4be9b29ea4b2681148ed"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Sat Sep 12 13:49:56 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 12 13:49:56 2026 -0700"
      },
      "message": "ci: handle Debian Bullseye end of life (#6175)\n\n* ci: pin legacy Clang jobs to Debian snapshot\n\n* ci: move supported compiler jobs to Bookworm\n\n* ci: move x86 install job to Bookworm\n\n* ci: keep legacy GCC jobs on pinned Bullseye\n\n* ci: link Bullseye snapshot steps to PR 6175"
    },
    {
      "commit": "d87cf0b873e42f0e541a4be9b29ea4b2681148ed",
      "tree": "b82d8fab4361445e759608e749cd6f3bf3ea2d05",
      "parents": [
        "782bba5a4399e56e0dd9b6fd6b9402c4c901343a"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Tue Sep 01 10:06:02 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 10:06:02 2026 -0400"
      },
      "message": "chore(deps): bump the actions group with 2 updates (#6158)\n\nBumps the actions group with 2 updates: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) and [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel).\n\n\nUpdates `astral-sh/setup-uv` from 9.0.0 to 10.0.1\n- [Release notes](https://github.com/astral-sh/setup-uv/releases)\n- [Commits](https://github.com/astral-sh/setup-uv/compare/v9.0.0...v10.0.1)\n\nUpdates `pypa/cibuildwheel` from 4.1 to 4.2\n- [Release notes](https://github.com/pypa/cibuildwheel/releases)\n- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)\n- [Commits](https://github.com/pypa/cibuildwheel/compare/v4.1...v4.2)\n\n---\nupdated-dependencies:\n- dependency-name: astral-sh/setup-uv\n  dependency-version: 10.0.1\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n  dependency-group: actions\n- dependency-name: pypa/cibuildwheel\n  dependency-version: \u00274.2\u0027\n  dependency-type: direct:production\n  update-type: version-update:semver-minor\n  dependency-group: actions\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "782bba5a4399e56e0dd9b6fd6b9402c4c901343a",
      "tree": "d8fb3b6993587ff5d61e13e05e9bd3b2ea430e4e",
      "parents": [
        "f90c430c3a1ce8f08c09942a5a1c3a797bb2295b"
      ],
      "author": {
        "name": "Advit Arora",
        "email": "advitarora2@gmail.com",
        "time": "Tue Sep 01 01:13:55 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 31 12:43:55 2026 -0700"
      },
      "message": "feat(numpy): add NPY_HALF_ to npy_api::constants (#6151)\n\n* feat(numpy): add NPY_HALF_ to npy_api::constants\n\n* tests: round-trip a user-defined half dtype as numpy.float16"
    },
    {
      "commit": "f90c430c3a1ce8f08c09942a5a1c3a797bb2295b",
      "tree": "a4ee51066fdbf3c1ab3484d773679fc8ce1be056",
      "parents": [
        "5e9611aacc0bdd2054aa36800055014ebcd8e805"
      ],
      "author": {
        "name": "Lucas Colley",
        "email": "lucas.colley8@gmail.com",
        "time": "Sat Aug 29 00:48:12 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 28 16:48:12 2026 -0700"
      },
      "message": "fix: unused-template warnings (#6156)\n\n* fix: remove `static` from `type_id`\n\n* Add -Wunused-template for Clang 18\n\n* fix: remove `static` from `type_has_shared_from_this`\n\n* Remove unreachable overload.\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "5e9611aacc0bdd2054aa36800055014ebcd8e805",
      "tree": "0d23e47b478bc7225b08153634c7a08c511ede5c",
      "parents": [
        "08f89f7b2155097295ec0357e9f2d8e2dec514b7"
      ],
      "author": {
        "name": "Aaron Gokaslan",
        "email": "aaronGokaslan@gmail.com",
        "time": "Mon Aug 24 20:39:53 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 24 20:39:53 2026 -0700"
      },
      "message": "(BE)(NFC): Use much more specific CPP feature flags (#6150)"
    },
    {
      "commit": "08f89f7b2155097295ec0357e9f2d8e2dec514b7",
      "tree": "34c4c734b16aade24d3697a1da89e3155ce7665a",
      "parents": [
        "22bf5b6ed4487e11d10a474d0b32081626bbb78a"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sun Aug 23 00:58:05 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 23 00:58:05 2026 -0400"
      },
      "message": "chore: add prepare-release and publish-release agent skills (#6147)\n\n* chore: add prepare-release and publish-release agent skills\n\nSplit the release process from docs/release.rst into two agent skills:\na changelog/version-bump PR, and the manual publication steps after\nthat PR merges. Un-ignore .agents (the MSVC \u0027Release\u0027 pattern matched\nthe release skill directory case-insensitively) and drop the outdated\nmanual _version.py step from docs/release.rst.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* [no ci] chore: document changelog style normalization in release skill\n\nTeach the prepare-release skill to proofread generated changelog entries for tense, concision, categorization, and PR-link consistency before opening release-prep PRs.\n\n* [no ci] chore: fix release skill portability\n\n* [no ci] fix: harden release workflows\n\n* [no ci] docs: show explicit manual artifact upload\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "22bf5b6ed4487e11d10a474d0b32081626bbb78a",
      "tree": "2a5acf671549a258dc104a75f0de139f08da71ad",
      "parents": [
        "a49c4dbfa478d98c8b43493d1c2a9699b9726909"
      ],
      "author": {
        "name": "Advit Arora",
        "email": "72540117+advitrocks9@users.noreply.github.com",
        "time": "Thu Aug 20 04:35:59 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 19 16:05:59 2026 -0700"
      },
      "message": "fix(numpy): accept PYBIND11_TYPE-wrapped types in the dtype macros (#6148)\n\n* fix(numpy): accept PYBIND11_TYPE-wrapped types in the dtype macros\n\n* docs: point at the macro notes from the structured types section\n\n* fix(numpy): accept bare types in direct field descriptor macro calls"
    },
    {
      "commit": "a49c4dbfa478d98c8b43493d1c2a9699b9726909",
      "tree": "06cb900fecb99511e985173eae1c9cb1d91a29bb",
      "parents": [
        "a9524c8254eefbe855d0a1757b6a435254437bdb"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Mon Aug 17 00:50:31 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 17 00:50:31 2026 -0400"
      },
      "message": "chore(cmake): carry option-driven defines on pybind11_headers INTERFACE (#6130)\n\n* chore(cmake): carry option-driven defines on pybind11_headers INTERFACE\n\nPYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION and\nPYBIND11_SIMPLE_GIL_MANAGEMENT were directory-scoped\nadd_compile_definitions, which only reached the master-project test\nbuild. On the pybind11_headers INTERFACE (like\nPYBIND11_INTERNALS_VERSION) they also apply in add_subdirectory mode\nand in the exported/installed targets.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* test(cmake): verify option-driven defines reach consumer targets\n\nExtend subdirectory_target and installed_target to check that\nPYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION and\nPYBIND11_SIMPLE_GIL_MANAGEMENT propagate through the pybind11_headers\nusage requirements. Fails without the parent commit.\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "a9524c8254eefbe855d0a1757b6a435254437bdb",
      "tree": "def1a63b8e40832997bb6873add3be241a0af5f3",
      "parents": [
        "0599909bfebc7d3440cc1fda3144e437e6ade056"
      ],
      "author": {
        "name": "aidaodedjl",
        "email": "55816803+aidaodedjl@users.noreply.github.com",
        "time": "Mon Aug 17 02:02:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 16 11:02:48 2026 -0700"
      },
      "message": "Guard cxxabi.h include with __has_include for clang-cl (#6145)\n\n* fix: guard cxxabi.h include with __has_include for clang-cl\n\nclang-cl on Windows defines __GNUG__ but does not ship \u003ccxxabi.h\u003e,\nmaking detail/typeid.h fail to compile. Introduce PYBIND11_HAS_CXXABI_H,\ndefined only when \u003ccxxabi.h\u003e is actually available (__has_include with\na fallback for compilers without it, including C++11), and use it to\nguard both the include and the abi::__cxa_demangle call site.\n\nFixes #6129\n\n* docs: explain the __has_include fallback for GCC \u003c 5\n\n---------\n\nCo-authored-by: aidaodedjl \u003cjialiang.dong@ju-shen.com\u003e"
    },
    {
      "commit": "0599909bfebc7d3440cc1fda3144e437e6ade056",
      "tree": "4e5efda59ae4eef7d0fab33022e5ebb047b6ebb8",
      "parents": [
        "856a3485ca5b704fc7614e89540670cb553e6e4f"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Fri Aug 14 16:33:49 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 14 16:33:49 2026 -0400"
      },
      "message": "fix: returning a copyable type with a deleted move constructor (#6143)\n\n* fix: returning a copyable type with a deleted move constructor (#6142)\n\ndetail::function_ref\u0027s constructor SFINAE required\nis_convertible\u003cRet, Ret\u003e, which is false for a copyable type whose move\nconstructor is explicitly deleted (the trait tests conversion from an\nxvalue). In C++17, such a prvalue return is legal via guaranteed copy\nelision, so also accept an exact type match. Regression introduced in\n3.1.0 by the call_impl outlining (#5887).\n\nFixes #6142\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* refactor: guard with __cpp_guaranteed_copy_elision\n\nPer review: the feature-test macro expresses the intent more precisely\nthan PYBIND11_CPP17.\n\nAssisted-by: ClaudeCode:claude-opus-5"
    },
    {
      "commit": "856a3485ca5b704fc7614e89540670cb553e6e4f",
      "tree": "1b2db8cabdbeef0535f821d8907984870cd455de",
      "parents": [
        "97bf890db679505a14dfe547a5e77bb2bd05dc90"
      ],
      "author": {
        "name": "Michael Šimáček",
        "email": "michael.simacek@oracle.com",
        "time": "Sat Aug 08 03:07:55 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 07 18:07:55 2026 -0700"
      },
      "message": "Prepare for GraalPy 3.13 (#6141)"
    },
    {
      "commit": "97bf890db679505a14dfe547a5e77bb2bd05dc90",
      "tree": "aea838909d16836e7d2515dd1ba6e67e2b3f19ae",
      "parents": [
        "05f6e6f6815f91a2df52e270f19f70a5e65c113e"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Thu Aug 06 11:44:21 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 06 11:44:21 2026 -0400"
      },
      "message": "chore: prepare 3.1.0 release (#6125)\n\n* docs: add 3.1 entries to the changelog\n\nAssisted-by: ClaudeCode:claude-opus-5\nSigned-off-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e\n\n* chore: prepare 3.1.0 release\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* [skip ci] Change release date to August 4, 2026\n\n* docs: add #6127 entry and set release date to August 6, 2026\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n---------\n\nSigned-off-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crwgkio@gmail.com\u003e"
    },
    {
      "commit": "05f6e6f6815f91a2df52e270f19f70a5e65c113e",
      "tree": "59f1161c85d92a96430e376c195fba05961808e0",
      "parents": [
        "6dd1756f985816fbd06e13faeac9cda86c6b262e"
      ],
      "author": {
        "name": "ymwang78",
        "email": "wangym@gmail.com",
        "time": "Thu Aug 06 15:05:23 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 06 00:05:23 2026 -0700"
      },
      "message": "fix(subinterpreter): don\u0027t touch the thread state before create() attaches one (#6127)\n\n`subinterpreter::create()` documents that \"the main interpreter and its GIL\nare not required to be held prior to calling this function\", but its first\nstatement is `error_scope err_scope;`, i.e. `PyErr_Fetch()`, before\n`main_guard` attaches a thread state. With no current `PyThreadState`,\n`PyErr_Fetch()` -\u003e `_PyErr_GetRaisedException(NULL)` dereferences null and\nthe process dies (SIGSEGV; 0xC0000005 on Windows). `~error_scope` is the\nmirror image: it calls `PyErr_Restore()` after `main_guard` has already\nswapped the thread state back away.\n\nTwo ordinary situations reach `create()` with no thread state:\n\n- an embedder that ends its initialization with `PyEval_SaveThread()`,\n  which is the documented way to hand the GIL back after\n  `Py_InitializeFromConfig()`;\n- any worker thread that has never touched Python.\n\nExisting tests never hit this because they all run under the\n`py::scoped_interpreter guard{}` in catch.cpp, which keeps the GIL held on\nthe main thread for the whole run.\n\nMove `error_scope` inside the `main_guard` scope. The case it exists for is\nunaffected: a caller that already holds the main GIL takes\n`subinterpreter_scoped_activate`\u0027s `simple_gil_` fast path, which keeps the\nsame thread state, so its pending error is still saved across\n`Py_NewInterpreterFromConfig()` and restored afterwards. A caller sitting on\nsome other interpreter never had its error indicator touched in the first\nplace, since everything inside the block runs on the main interpreter\u0027s\nthread state and `PyThreadState_Swap()` does not move error indicators. It\nalso makes the `pybind11_fail()` path unwind in a safer order: `~error_scope`\nnow runs while `main_guard` is still alive.\n\nAdd \"Create Subinterpreter without a thread state\", covering both a thread\nthat dropped its thread state via `gil_scoped_release` and a thread that\nnever had one. It segfaults without the fix and passes with it.\n\nVerified on Windows / MSVC 14.51 / CPython 3.13.14: test_with_catch goes\nfrom 33 to 34 test cases, all passing.\n\nAssisted-by: ClaudeCode:claude-opus-5"
    },
    {
      "commit": "6dd1756f985816fbd06e13faeac9cda86c6b262e",
      "tree": "1bf10ca8de9c4628fdf5c179a7d9c4759264ef20",
      "parents": [
        "59565095fafae453b15d2a9e8a66d8ca4758b6d5"
      ],
      "author": {
        "name": "pre-commit-ci[bot]",
        "email": "66853113+pre-commit-ci[bot]@users.noreply.github.com",
        "time": "Thu Aug 06 01:26:39 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 06 01:26:39 2026 -0400"
      },
      "message": "chore(deps): update pre-commit hooks (#6126)\n\n* chore(deps): update pre-commit hooks\n\nupdates:\n- [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)\n- [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)\n- [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)\n- [github.com/codespell-project/codespell: v2.4.2 → v2.4.3](https://github.com/codespell-project/codespell/compare/v2.4.2...v2.4.3)\n\n* style: pre-commit fixes\n\n* fix: adapt to the ruff 0.16 default rule set\n\nThe hook update pulled in ruff 0.16, which expanded its default rules and\nautofixed `self: S -\u003e S` to `-\u003e Self`. That fix added a runtime\n`typing_extensions` import to setup_helpers.py, which must stay\ndependency-free; it broke every test job whose environment does not supply\nthat package. The import is now guarded by TYPE_CHECKING.\n\nAlso replace the `exec` in docs/conf.py with an importlib module load,\nparenthesize implicit string concatenations in list literals, mark unused\nunpacked variables with a leading underscore, and make noxfile.py\nexecutable to match its shebang.\n\nThe remaining new rules are silenced per-file, with reasons: the chrono\ntests check naive local time on purpose, and the other rules conflict with\nhow the tests are written.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e\nCo-authored-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e"
    },
    {
      "commit": "59565095fafae453b15d2a9e8a66d8ca4758b6d5",
      "tree": "78b45e061935b328576c6a4f4f023fda034ebd4e",
      "parents": [
        "63d627c5747befad7720a43ebbe5614fd5d83247"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Sun Aug 02 22:37:26 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 02 22:37:26 2026 -0700"
      },
      "message": "Delegate py::print to Python\u0027s native print (#6121)\n\n* refactor: delegate py::print to native print\n\n* style: use auto for print result\n\n* test: focus py::print coverage on delegation\n\n* docs: describe native py::print delegation\n\n* fix: keep py::print silent when builtin is missing\n\n* test: cover py::print with unavailable stdout\n\n* docs: clarify py::print builtins lookup"
    },
    {
      "commit": "63d627c5747befad7720a43ebbe5614fd5d83247",
      "tree": "8eba4f9dffd1fb2beebd011d53adfb873d22da69",
      "parents": [
        "695a7a421dc8a2dccde5d5b07b69e9d2ef917c02"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sat Aug 01 01:04:32 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 31 22:04:32 2026 -0700"
      },
      "message": "feat!: drop support for Python 3.8, MSVC 2017 (#6110)\n\n* feat!: drop support for Python 3.8\n\nThe minimum supported version is now Python 3.9. pybind11 v3.0 was the last\nrelease that supports Python 3.8. The deprecation note said that support goes\naway in 3.1.\n\nRemove the code paths that this makes dead:\n\n- the `_PyObject_Vectorcall` fallback in `cast.h`\n- the `frame-\u003ef_code` and `frame-\u003ef_back` fallbacks in `pytypes.h`\n- the `PyFrame_FastToLocals` path in `get_type_override`\n- the conditional `Py_VISIT(Py_TYPE(self))` in `tp_traverse`\n- `PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX`, the pre-PyConfig interpreter\n  init, and the `widen_chars` helpers in `embed.h`\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* ci(appveyor): use Python 3.9\n\nThe AppVeyor job set `PYTHON: 38`, which makes the path `C:\\Python38`.\nThe image gives Python 3.9.13 as `C:\\Python39`.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* feat!: require MSVC 2019 or newer\n\nPython 3.9 is the new minimum, so MSVC 2017 is no longer needed. Raise the\ncompile-time floor to _MSC_VER 1920 and remove the workarounds that only\napplied below it: std::launder, fold expressions, weak_from_this, aligned\nnew/delete, the C4100 warning helper, and the func_handle syntax error.\n\nAppVeyor now builds with Visual Studio 2019.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* fix(appveyor): build against the Python that has the test packages\n\nCMake 4 has no FindPythonLibs, so pybind11 uses FindPython. FindPython reads\nthe registry before PATH and selected `C:\\Python314-x64`, but the test packages\ngo into the Python on PATH. Pass `Python_ROOT_DIR` to name the correct one.\n\nAlso set `CMAKE_ARCH`. It was never set, so the architecture came from the\ngenerator. Visual Studio 2017 defaults to Win32, but Visual Studio 2019\ndefaults to x64, which made this x86 job build 64-bit code.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* fix(appveyor): give the linker Python\u0027s libs directory\n\nThe build compiled but failed to link with LNK1104 on a bare `python39.lib`.\nThat name comes from the `#pragma comment(lib, ...)` in pyconfig.h, so the\nlinker needs the directory. CMake 4 has no FindPythonLibs, and FindPython does\nnot add it for this Debug x86 build. Put it on LIB instead.\n\nThe directory listing is temporary, to confirm the library is present.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* fix(appveyor): link the release Python library in Debug\n\nThe image ships python39_d.lib next to python39.lib, so FindPython picks the\ndebug import library for a Debug build. pybind11 undefines _DEBUG around\nPython.h, so pyconfig.h asks for python39.lib instead and the link failed with\nLNK1104. Name the release library for the debug slot.\n\nSetting LIB does not work, because MSBuild replaces it from the toolset, and it\nwould link both import libraries.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* chore(appveyor): print link settings to debug LNK1104\n\nRevert the two attempted fixes. Neither changed the failure: setting LIB does\nnot survive MSBuild, and naming the release library for Python_LIBRARY_DEBUG\nhad no effect.\n\nPrint the Python cache entries and the link settings of a generated project\nfile instead, to see what the linker really gets. Temporary.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* fix(appveyor): take the release Python library in Debug\n\nThe generated project file linked C:\\Python39\\libs\\python39_d.lib in the Debug\nconfiguration, because the image ships debug binaries next to the release ones.\npybind11 undefines _DEBUG around Python.h, so pyconfig.h asks for python39.lib\nin a #pragma comment(lib), which nothing on the link line satisfies and no\nlibrary directory holds. Map Debug to the release artifacts.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* chore(appveyor): drop the temporary link diagnostic\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* fix(tests): guard the unraisable warning filter for pytest \u003c 6\n\nThe distro pytest in the Clang and GCC Docker jobs has no\nPytestUnraisableExceptionWarning, so an unconditional filterwarnings\nmark makes pytest fail with an INTERNALERROR after the tests pass.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\nClaude-Session: https://claude.ai/code/session_01Aimf6HuSz1vLRwBnbxmCTc\n\n* docs: address review items on version hints, embed docs, and a PyPy xfail\n\nExtend Python_ADDITIONAL_VERSIONS through 3.15, describe the PyConfig\nbehavior of initialize_interpreter, and drop the stale Python 3.8 wording\nfrom the PyPy xfail reason.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* Update README.rst\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crwgkio@gmail.com\u003e\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crwgkio@gmail.com\u003e"
    },
    {
      "commit": "695a7a421dc8a2dccde5d5b07b69e9d2ef917c02",
      "tree": "f8b97d77119279a846a4c9c4aee36c8cd4385d9e",
      "parents": [
        "ea9e6e6a23b1069a561631e7dbf73eb4bb16fa81"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Fri Jul 31 22:58:26 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 31 22:58:26 2026 -0400"
      },
      "message": "chore(deps): bump the actions group with 3 updates (#6119)\n\nBumps 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).\n\n\nUpdates `actions/setup-python` from 6 to 7\n- [Release notes](https://github.com/actions/setup-python/releases)\n- [Commits](https://github.com/actions/setup-python/compare/v6...v7)\n\nUpdates `astral-sh/setup-uv` from 8.2.0 to 9.0.0\n- [Release notes](https://github.com/astral-sh/setup-uv/releases)\n- [Commits](https://github.com/astral-sh/setup-uv/compare/v8.2.0...v9.0.0)\n\nUpdates `actions/labeler` from 6 to 7\n- [Release notes](https://github.com/actions/labeler/releases)\n- [Commits](https://github.com/actions/labeler/compare/v6...v7)\n\n---\nupdated-dependencies:\n- dependency-name: actions/setup-python\n  dependency-version: \u00277\u0027\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n  dependency-group: actions\n- dependency-name: astral-sh/setup-uv\n  dependency-version: 9.0.0\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n  dependency-group: actions\n- dependency-name: actions/labeler\n  dependency-version: \u00277\u0027\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n  dependency-group: actions\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "ea9e6e6a23b1069a561631e7dbf73eb4bb16fa81",
      "tree": "5e440dd52ac06d4aa6901f0a07dee18c2e5e2994",
      "parents": [
        "652c69437bbd67e0075648c2fd633eb318f1ee40"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Fri Jul 31 14:17:21 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 31 14:17:21 2026 -0400"
      },
      "message": "feat: small command line helpers for quick tests (#4272)\n\n* feat: small command line helpers for quick tests\n\nAdd --cflags, --ldflags, --embed, and --file to the pybind11 command\nline tool, based on python-config. This makes quick one-off compiles\neasy:\n\n    c++ $(python3 -m pybind11 --file\u003dexample.cpp)\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* refactor: quote paths, clarify CLI output logic, strengthen tests\n\n- Quote include and library dirs in get_cflags/get_ldflags so paths with\n  spaces work, sharing one quote helper in commands.py\n- Restructure the --file/--cflags/--ldflags printing into a single print\n- Note the Unix-compiler orientation in help text and docs\n- Test -L presence for --embed and quoting of paths with spaces\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* refactor: simplify flag helpers and keep import pybind11 light\n\n- Replace _get_config_var(name, fmt, quote) with a plain _config(name)\n  string helper; formatting and quoting happen at the call sites\n- Defer sysconfig/shlex imports so import pybind11 does not pay for the\n  CLI (~1ms -\u003e ~0.08ms for pybind11.commands)\n- Fetch EXT_SUFFIX once in main()\n- Import commands normally in the quoting test instead of importlib\n  file loading\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* fix: shared-library flags on all Unix platforms\n\nThe --file/--ldflags output only added -shared and -fPIC on Linux, so\nother Unix platforms (FreeBSD, Solaris, AIX) linked an executable and\nfailed on the missing main. Gate on os.name instead.\n\nAssisted-by: ClaudeCode:claude-opus-5"
    },
    {
      "commit": "652c69437bbd67e0075648c2fd633eb318f1ee40",
      "tree": "ec0878064b050c6587e66834055c802d8e0177b7",
      "parents": [
        "2f85cc8c4ad7cd9d53edada33c581aad091da0aa"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Wed Jul 29 14:53:47 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 29 14:53:47 2026 -0400"
      },
      "message": "fix: add py::mod_gil_used() spelling, support pedantic tests (#5797)\n\n* tests: add linking warnings/error\n\nSigned-off-by: Henry Schreiner \u003chenryschreineriii@gmail.com\u003e\n\n* tests: check pedantic C++14\n\n* fix: some pedantic warnings\n\nSigned-off-by: Henry Schreiner \u003chenryschreineriii@gmail.com\u003e\n\n* feat: add py::mod_gil_used()\n\nSigned-off-by: Henry Schreiner \u003chenryschreineriii@gmail.com\u003e\n\n* fix: use not_supported()\n\nSigned-off-by: Henry Schreiner \u003chenryschreineriii@gmail.com\u003e\n\n* style: pre-commit fixes\n\n* Update CMakeLists.txt\n\n* fix: remove the true/false parameter from mod_gil_not_used\n\nSigned-off-by: Henry Schreiner \u003chenryschreineriii@gmail.com\u003e\n\n* style: pre-commit fixes\n\n* Update tests/CMakeLists.txt\n\n* fix: deprecate mod_gil_not_used(bool) instead of removing it\n\nKeep the bool constructor public and mark it deprecated, so existing\ncode that spells mod_gil_not_used(false) still compiles. mod_gil_used()\nnow sets the flag through its friendship, which keeps the deprecated\nconstructor the only bool overload and stops pybind11 warning against\nitself.\n\nAlso use the py:: alias in exo_planet_pybind11.cpp to match its sibling\nhome_planet_very_lonely_traveler.cpp.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* fix: add trailing comma to macros picked up in rebase\n\ntest_smart_ptr.cpp and standalone_enum_module.cpp came from master after\nthis branch was written, so they still invoked variadic macros with no\nvariadic argument. That is a pedantic error below C++20.\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n---------\n\nSigned-off-by: Henry Schreiner \u003chenryschreineriii@gmail.com\u003e\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "2f85cc8c4ad7cd9d53edada33c581aad091da0aa",
      "tree": "dfecd25d356a87c4421b6139e65fdb40f698d66f",
      "parents": [
        "5540f968020451da2c1bf7211b8c861c0fc30cbf"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Wed Jul 29 12:51:20 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 29 12:51:20 2026 -0400"
      },
      "message": "chore(ci): bump NVHPC to 26.5 (#6117)\n\n* chore(ci): bump NVHPC to 26.5\n\nAssisted-by: ClaudeCode:claude-opus-5\n\n* chore(ci): download NVHPC deb with curl retries to dodge CDN 404s\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "5540f968020451da2c1bf7211b8c861c0fc30cbf",
      "tree": "e729027b40a925e5c45348dde6a672cd8d72c7b9",
      "parents": [
        "a647cddd4e9f44c033eeb1d423e1bf86c6c198c1"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Tue Jul 28 21:53:36 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jul 28 18:53:36 2026 -0700"
      },
      "message": "fix: only add string_view life support for transient sources (#6096)\n\n* revert: \"revert: add life support to handles cast to string_view (#6092)\"\n\nThis re-applies #6092 (reverting #6097) so the follow-up fixes in this PR can build on it.\n\nAssisted-by: ClaudeCode:claude-opus-4.8\n\n* fix: don\u0027t throw from string_view life support outside a bound function\n\nPR #6092 added loader_life_support::add_patient(src) to keep the source\nobject alive when loading a string view, fixing a real use-after-free when\na container of views is built from a non-sequence iterable (e.g. a\ngenerator): list_caster materializes a temporary tuple that owns the\nstrings and destroys it when load() returns, before the bound function\nbody runs.\n\nadd_patient throws when there is no life support frame, so casting to a\nview outside a bound function (e.g. a manual py::cast\u003cstd::string_view\u003e)\nnow raises instead of relying on the caller-owned source, a regression\nfrom #6092.\n\nFor these view-into-src cases registration is best effort: inside a bound\nfunction it keeps src alive (fixing the UAF), and outside one the caller\nowns src\u0027s lifetime as before. Add try_add_patient(), which returns false\ninstead of throwing when there is no frame, and use it at the three view\nload sites. add_patient() keeps its strict contract for value-creating\nconversions.\n\nAssisted-by: ClaudeCode:claude-opus-4.8\n\n* fix: only add string_view life support for transient sources\n\nRefine the previous commit. Best-effort registration (try_add_patient)\nsilently produces a dangling view when a container of views is built from\na generator outside a bound function: there the materialized temporary is\nreleased before the view is used, and with no frame nothing keeps it\nalive. Such a cast cannot be made safe, so it should fail loudly, while a\nview into a durable, caller-owned object needs no life support at all.\n\nThe view caster cannot tell a durable source from a pybind11-managed\ntransient one; that provenance lives in the container caster. Introduce an\nambient transient_source_guard that the list, set, map, and array casters\nset around their generator/materialized paths, and have the string caster\nkeep the source alive only when loading from a transient source (via the\nthrowing add_patient, so try_add_patient is no longer needed). This means:\n\n- views into durable sources (direct arguments, sequences, manual casts)\n  add no life support and no longer throw outside a bound function, and\n- a generator used outside a frame throws, rather than silently dangling.\n\nThe guard restores (rather than clears) the previous value, so a durable\ncontainer nested in a transient one is correctly treated as transient.\n\nVerified with AddressSanitizer: the in-frame generator case is clean, the\nout-of-frame durable cases succeed, and the out-of-frame generator case\nthrows.\n\nAssisted-by: ClaudeCode:claude-opus-4.8\n\n* Revert \"fix: only add string_view life support for transient sources\"\n\nThis reverts commit e18b8346a28c125964fcb9d192e6643d5ef3b420.\n\n* test: cover string_view argument life support\n\n* test: cover generated and nested string_view lifetimes\n\n* test: cover temporary-backed string_view casts\n\n* test: explain string_view lifetime regression tests\n\n* docs: clarify string_view lifetime requirements\n\n* docs: explain life support for custom view casters\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "a647cddd4e9f44c033eeb1d423e1bf86c6c198c1",
      "tree": "513839dd7cf686f044de86af0a19352fb022ffc9",
      "parents": [
        "95ebcb3643d4573425aa78a042496a133fb322a3"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Mon Jul 27 09:41:15 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 27 09:41:15 2026 -0400"
      },
      "message": "fix(cmake): respect explicit PYBIND11_USE_CROSSCOMPILING under CMP0190 (#6094)\n\n* fix(cmake): respect explicit PYBIND11_USE_CROSSCOMPILING under CMP0190\n\nPR #5829 added `AND NOT DEFINED CMAKE_CROSSCOMPILING_EMULATOR` to the\ncondition setting `_PYBIND11_CROSSCOMPILING`. That gate was meant to only\ncontrol the auto-default of `PYBIND11_USE_CROSSCOMPILING`, but it ended up\noverriding a value the project set explicitly. Emscripten/Pyodide defines\n`CMAKE_CROSSCOMPILING_EMULATOR` (node) yet still wants cross-compiling\nmode, so the flag was forced OFF and the build failed with a spurious\n\"Cannot run the interpreter\" / pointer-size mismatch.\n\nMove the emulator check up so it only guards the auto-default, and never\noverride an explicitly set `PYBIND11_USE_CROSSCOMPILING`.\n\nFixes #6043\n\nAssisted-by: ClaudeCode:claude-opus-4.8\n\n* fix(cmake): keep CMP0190 auto-default in add_subdirectory builds\n\nThe previous commit\u0027s `NOT DEFINED PYBIND11_USE_CROSSCOMPILING` guard\nbroke the intended auto-default for top-level / add_subdirectory builds:\nCMakeLists.txt runs `option(PYBIND11_USE_CROSSCOMPILING ... OFF)` before\nincluding pybind11Common.cmake, so the variable is already defined (OFF)\nand the CMP0190 default never applied.\n\nCapture, before the option() call, whether the project set the value\nitself, and let pybind11Common.cmake apply its default unless the value\nwas set explicitly. This keeps both the emulator override fix and the\nCMP0190 auto-default for subdirectory consumers.\n\nAssisted-by: ClaudeCode:claude-opus-4.8"
    },
    {
      "commit": "95ebcb3643d4573425aa78a042496a133fb322a3",
      "tree": "e2590c924068cbd0f86c4b453837d552962f07f4",
      "parents": [
        "f4d31b743dc1a121eb7c3a49efdd7c08cd43b77f"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Mon Jul 27 01:41:07 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 27 01:41:07 2026 -0400"
      },
      "message": "chore(tools): make_changelog missed and resurrected PRs (#6108)"
    },
    {
      "commit": "f4d31b743dc1a121eb7c3a49efdd7c08cd43b77f",
      "tree": "1efb8407551668d3442cc3d289df41bcc5d79f98",
      "parents": [
        "f95b7a58605a91cc832efb821b0c69ccd938b709"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Mon Jul 27 00:26:04 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jul 26 21:26:04 2026 -0700"
      },
      "message": "fix(cmake): don\u0027t pass -fno-fat-lto-objects on Apple GCC (#6114)\n\nGCC on macOS has no linker plugin, so `-fno-fat-lto-objects` makes every\nLTO probe fail and LTO is silently disabled. Plain `-flto\u003dauto` works.\n\nFixes #6060\n\nAssisted-by: ClaudeCode:claude-opus-5\nClaude-Session: https://claude.ai/code/session_013JABmnjt9oAh29p1pytAB3"
    },
    {
      "commit": "f95b7a58605a91cc832efb821b0c69ccd938b709",
      "tree": "0311762ff2fcb77c9c53e56eca8b2479824d6a5b",
      "parents": [
        "17b3b605a5f74410a80d67a779de9871d27a4ca1"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Mon Jul 27 00:25:24 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jul 26 21:25:24 2026 -0700"
      },
      "message": "fix: include `complex` in std::complex input annotation (#6113)\n\n* fix: include `complex` in std::complex input annotation\n\nThe input annotation for `std::complex\u003cT\u003e` omitted the builtin `complex`\ntype, which typeshed only makes a `typing.SupportsComplex` on Python 3.11+.\n\nAssisted-by: ClaudeCode:claude-opus-5\nClaude-Session: https://claude.ai/code/session_013JABmnjt9oAh29p1pytAB3\n\n* Add comment to explain why the explicit `complex` is needed.\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "17b3b605a5f74410a80d67a779de9871d27a4ca1",
      "tree": "30a70fdc26d8b46f75fbd03c262c94f071bca43c",
      "parents": [
        "57e7a8de342dc20d16859d4eda45bb960b4d18b5"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sun Jul 26 22:08:59 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jul 26 19:08:59 2026 -0700"
      },
      "message": "test: remove dead PR3068 workaround branch (#6109)\n\n`WORKAROUND_ENABLING_ROLLBACK_OF_PR3068` compared the 5-element\n`sys.version_info` tuple to `(3, 9)`, so it was always False. The guarded\nbranch never ran. Remove the constant and keep only the branch that runs.\n\nAssisted-by: ClaudeCode:claude-opus-5"
    },
    {
      "commit": "57e7a8de342dc20d16859d4eda45bb960b4d18b5",
      "tree": "89d0bcd12bfd62e6fc19c39d0ba2fdd0b1f2ad76",
      "parents": [
        "36341ba9ba53096a5c4cc7fe69be577430f69d04"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Sun Jul 26 06:14:56 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jul 26 03:14:56 2026 -0700"
      },
      "message": "fix(stl_bind): correct __delitem__ for negative-step slices and re-enable contiguous erase fast path (#6088)\n\n* fix(stl_bind): correct __delitem__ for negative-step slices and re-enable contiguous erase fast path\n\nThe slice __delitem__ binding advanced the erase index by step - 1 for\nall steps. That correction is only valid for positive steps, where\nerasing shifts later elements down by one. For negative steps the\nvisited indices are strictly decreasing and erasing never shifts them,\nso the extra -1 deleted the wrong elements (e.g. del v[::-2] on\n[0,1,2,3] yielded [1,2] instead of [0,2]) and del v[::-1] walked off the\nfront of the vector (v.begin() - 1, observed SIGBUS).\n\nSwitch to the signed slice::compute overload so negative steps stay\nsigned, advance by step for negative steps and step - 1 for positive\nones, and drop the \u0026\u0026 false that had disabled the O(n) contiguous fast\npath since 2016.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* refactor: address review — static_cast and parametrized test\n\nUse static_cast instead of a C-style cast for the slice.compute() size\nargument, and convert the __delitem__ slice test to\npytest.mark.parametrize over the slice cases.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* test(stl_bind): cover slice deletion edge cases\n\n* fix(stl_bind): erase strided slices in descending order\n\n* Eliminate a variable and avoid redundant index increment (i + 1, ++i).\n\nThe control flow handles all relevant boundaries:\n\n- slicelength \u003d\u003d 0: excluded by the outer guard.\n- slicelength \u003d\u003d 1: erases once, decrements to zero, and breaks without touching start.\n- Larger slices: updates start exactly when another erase remains.\n- slicelength cannot underflow because the loop exits when it reaches zero.\n- Mutating slicelength is harmless because it is not used afterward.\n- The potentially dangerous final start +\u003d step remains eliminated.\n\nIt also removes the separate loop counter. The compiler would probably\noptimize the former i + 1, ++i mechanics away, but the new source expresses\nthe real state more directly: \"number of erasures remaining.\"\n\nThe unconditional while (true) is safe because entry is strictly guarded by\nslicelength \u003e 0, and the decrement guarantees eventual termination.\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "36341ba9ba53096a5c4cc7fe69be577430f69d04",
      "tree": "2de14ed7320e7e9b1db843a427ea770670640401",
      "parents": [
        "fb836a2f1fc0c30bf9f8959ab54a42d9337f5824"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Fri Jul 24 20:32:52 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 24 20:32:52 2026 -0400"
      },
      "message": "ci: test Python 3.15 (#6107)"
    },
    {
      "commit": "fb836a2f1fc0c30bf9f8959ab54a42d9337f5824",
      "tree": "5e8aafdabc902447347ecd80843784184963a871",
      "parents": [
        "85198b598fd4e369dd9d766598713ee2d9c8d0b3"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Fri Jul 24 17:38:59 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 24 17:38:59 2026 -0400"
      },
      "message": "ci: drop near-duplicate jobs (#6106)\n\nRemove ten jobs whose coverage is already provided by other jobs:\nduplicate ubuntu pypy/graalpy/3.11/3.14t runs, an intel-mac 3.11\nsmart_holder run, a windows job pinning the default MSVC runtime,\nsandwiched clang 14 and gcc 10/C++20 entries, and extra win32 and\nwin32-debug variants. Also delete the gcc PYBIND11_TEST_OVERRIDE steps,\ndead since gcc 12 left the matrix (the windows-2022 job still runs the\nsame exercise).\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "85198b598fd4e369dd9d766598713ee2d9c8d0b3",
      "tree": "18a33b39b098a1d2986d8e761ca08155b8eaae38",
      "parents": [
        "7478df9420fbb1fe0db4fdfe032014c17fc66156"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Fri Jul 24 10:45:22 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 24 10:45:22 2026 -0400"
      },
      "message": "fix(ci): use the intended Python interpreter for CMake discovery (#6105)\n\n* fix(ci): pin the discovered Python to the venv/setup-python interpreter\n\nThe manylinux/musllinux images added Python 3.15 and dropped 3.13t;\nFindPython\u0027s version scan then picked /usr/local/bin/python3.15 over\nthe uv-created venv (Python_ROOT_DIR is only a hint). Similarly, the\nmacOS and Windows 3.14t jobs picked a system 3.14 over setup-python\u0027s\nfree-threaded interpreter. Pin the interpreter explicitly in both\nplaces, and drop the 3.13t manylinux jobs.\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* ci: use setup-python\u0027s python-path output instead of a locate step\n\nAssisted-by: ClaudeCode:claude-fable-5\n\n* Apply suggestions from code review\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crwgkio@gmail.com\u003e\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crwgkio@gmail.com\u003e"
    },
    {
      "commit": "7478df9420fbb1fe0db4fdfe032014c17fc66156",
      "tree": "3cdd9d93d8d137d1e7403f1f348f484343ef5988",
      "parents": [
        "34566e1d2ab190f38196d2c09ccd706fe4ccbeeb"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Thu Jul 23 01:40:11 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 23 01:40:11 2026 -0400"
      },
      "message": "fix(cmake): unset stale PYTHON_MODULE_DEBUG_POSTFIX and correct USE_PYTHON_INCLUDE_DIR variable (#6086)\n\nWhen the Python executable changes between CMake runs,\nPYTHON_MODULE_DEBUG_POSTFIX was not being unset alongside PYTHON_IS_DEBUG\nand PYTHON_MODULE_EXTENSION, allowing a stale postfix to survive interpreter\nchanges.\n\nIn the USE_PYTHON_INCLUDE_DIR block, the elseif branch checked\nPYTHON_INCLUDE_DIR (singular) but expanded PYTHON_INCLUDE_DIRS (plural),\nalways silently resolving to an empty string. Correct it to expand\n${PYTHON_INCLUDE_DIR}. Also add a Python3_INCLUDE_DIRS branch so the\noption works when pybind11NewTools resolves Python via the Python3\nfind-package component.\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "34566e1d2ab190f38196d2c09ccd706fe4ccbeeb",
      "tree": "2e653c62c1e683a8a312f26a532c9f2deefe5ad4",
      "parents": [
        "28b98f2d39296651917c9a63acf1bd679ae0a40f"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Wed Jul 15 22:51:27 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 15 22:51:27 2026 -0500"
      },
      "message": "chore(deps): bump soupsieve from 2.5 to 2.8.4 in /docs (#6100)\n\nBumps [soupsieve](https://github.com/facelessuser/soupsieve) from 2.5 to 2.8.4.\n- [Release notes](https://github.com/facelessuser/soupsieve/releases)\n- [Commits](https://github.com/facelessuser/soupsieve/compare/2.5...2.8.4)\n\n---\nupdated-dependencies:\n- dependency-name: soupsieve\n  dependency-version: 2.8.4\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "28b98f2d39296651917c9a63acf1bd679ae0a40f",
      "tree": "e3b0902d31bec62eb963e873c7a0f1502ab57318",
      "parents": [
        "7ca651c0e5e087a5d34c742c3c355726a4e9b8bb"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Wed Jul 08 23:31:36 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 08 23:31:36 2026 -0400"
      },
      "message": "ci: update cibuildwheel to v4.1 and pyodide to 314 (#6095)\n\n* ci: update cibuildwheel to v4.1 and pyodide to 314\n\nBump pypa/cibuildwheel from v3.4 to v4.1 across the Pyodide, iOS, and\nAndroid jobs. Move the Pyodide build to cp314-pyodide_wasm32\n(pyodide 314.0.0).\n\nDrop the iOS CIBW_SKIP: cp314-* workaround now that pypa/cibuildwheel#2494\nis resolved.\n\nAssisted-by: ClaudeCode:claude-opus-4.8\n\n* test: xfail array resize on numpy\u003c2.4 + Python 3.14\n\nRemoving the cp314 iOS skip surfaced a pre-existing numpy bug, not a\ncibuildwheel regression: numpy\u003c2.4 has a resize(refcheck\u003dTrue) regression\non Python 3.14 where the reference held by the bound function isn\u0027t\ndetected, so a resize that should raise instead succeeds and the later\nreshape rejects the non-square size. Fixed in numpy\u003e\u003d2.4, but the iOS test\nenvironment has no numpy wheel newer than 2.3.5.post1, so xfail the test\nfor that specific combination.\n\nAssisted-by: ClaudeCode:claude-opus-4.8\n\n* test: link numpy resize aliasing issue and trim comment\n\niOS numpy wheels updated to 2.5.0, so the xfail is a general numpy\u003c2.4 +\nPython 3.14 guard rather than iOS-specific. Reference numpy/numpy#30265.\n\nAssisted-by: ClaudeCode:claude-opus-4.8"
    },
    {
      "commit": "7ca651c0e5e087a5d34c742c3c355726a4e9b8bb",
      "tree": "20a05600cad173b8a2e6e4255e5d47a6431d379c",
      "parents": [
        "b57b4393ff92dfcea0da1b64eb359c8f900cbcec"
      ],
      "author": {
        "name": "pre-commit-ci[bot]",
        "email": "66853113+pre-commit-ci[bot]@users.noreply.github.com",
        "time": "Wed Jul 08 16:45:20 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 08 16:45:20 2026 -0400"
      },
      "message": "chore(deps): update pre-commit hooks (#6099)\n\nupdates:\n- [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)\n- [github.com/adhtruong/mirrors-typos: v1.47.0 → v1.48.0](https://github.com/adhtruong/mirrors-typos/compare/v1.47.0...v1.48.0)\n- [github.com/PyCQA/pylint: v4.0.5 → v4.0.6](https://github.com/PyCQA/pylint/compare/v4.0.5...v4.0.6)\n- [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)\n\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "b57b4393ff92dfcea0da1b64eb359c8f900cbcec",
      "tree": "9376218a795c592453aa83ad59038ef0c21cc1ee",
      "parents": [
        "db92ad940f143a48ba8c422d6bfee7f536f35e6d"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Fri Jul 03 14:50:43 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 03 14:50:43 2026 -0700"
      },
      "message": "chore(deps): bump the actions group with 3 updates (#6098)\n\n* chore(deps): bump the actions group with 3 updates\n\nBumps 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).\n\n\nUpdates `actions/checkout` from 6 to 7\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Commits](https://github.com/actions/checkout/compare/v6...v7)\n\nUpdates `astral-sh/setup-uv` from 8.1.0 to 8.2.0\n- [Release notes](https://github.com/astral-sh/setup-uv/releases)\n- [Commits](https://github.com/astral-sh/setup-uv/compare/v8.1.0...v8.2.0)\n\nUpdates `pypa/cibuildwheel` from 3.4 to 4.1\n- [Release notes](https://github.com/pypa/cibuildwheel/releases)\n- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)\n- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.4...v4.1)\n\n---\nupdated-dependencies:\n- dependency-name: actions/checkout\n  dependency-version: \u00277\u0027\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n  dependency-group: actions\n- dependency-name: astral-sh/setup-uv\n  dependency-version: 8.2.0\n  dependency-type: direct:production\n  update-type: version-update:semver-minor\n  dependency-group: actions\n- dependency-name: pypa/cibuildwheel\n  dependency-version: \u00274.1\u0027\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n  dependency-group: actions\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\n\n* ci: restore checkout v1 for i386 job\n\n---------\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "db92ad940f143a48ba8c422d6bfee7f536f35e6d",
      "tree": "32dbf9b2516e39e851b2cb294df4b872794e839e",
      "parents": [
        "84da0e25455a33634857f88491b72c9c835b88a7"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Mon Jun 29 00:38:56 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 29 00:38:56 2026 -0400"
      },
      "message": "revert: \"add life support to handles cast to string_view (#6092)\" (#6097)\n\nThis reverts commit 59d7cb28c1f5a014bb17ad4a8e80da2fb51a6159 (#6092).\n\n#6092 introduced regressions that are being addressed in #6096; reverting\n\nAssisted-by: ClaudeCode:claude-opus-4.8"
    },
    {
      "commit": "84da0e25455a33634857f88491b72c9c835b88a7",
      "tree": "c14ff2d3045c7cb5f7f7706c41d006eb8c412a34",
      "parents": [
        "3de0402476ed689052e6d709924755c52e901f5e"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Wed Jun 24 00:15:58 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 23 21:15:58 2026 -0700"
      },
      "message": "refactor: remove needless load_src alias in string_caster (#6093)\n\n`load_src` was a Python 2-era leftover. A removed branch used to reassign\nit to a temporary unicode object; since that was deleted with Python 2\nsupport, it is now an exact, never-reassigned alias of `src`. Use `src`\ndirectly.\n\nSpotted in review of #6092.\n\nAssisted-by: ClaudeCode:claude-opus-4.8"
    },
    {
      "commit": "3de0402476ed689052e6d709924755c52e901f5e",
      "tree": "097f96794d460ae4695b874912321692d8138a5b",
      "parents": [
        "085b66068af8ce82dab122a7b1c9cbc9e9ac99ea"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Tue Jun 23 23:49:20 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 23 23:49:20 2026 -0400"
      },
      "message": "chore: add agent files (#6082)\n\n* chore: add agent files\n\nAssisted-by: ClaudeCode:claude-opus-4.8\nSigned-off-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e\n\n* fix: better AGENTS.md\n\nSigned-off-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e\n\n* Apply suggestions from code review\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crwgkio@gmail.com\u003e\nCo-authored-by: Henry Schreiner \u003cHenrySchreinerIII@gmail.com\u003e\n\n---------\n\nSigned-off-by: Henry Schreiner \u003chenryfs@princeton.edu\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crwgkio@gmail.com\u003e"
    },
    {
      "commit": "085b66068af8ce82dab122a7b1c9cbc9e9ac99ea",
      "tree": "92b490f4d8e3d3ea039503602a9480adc11f6632",
      "parents": [
        "59d7cb28c1f5a014bb17ad4a8e80da2fb51a6159"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Tue Jun 23 21:48:26 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 23 21:48:26 2026 -0400"
      },
      "message": "fix: data race on last_storage_ptr_ cache in gil_safe_call_once_and_store (#6087)\n\nUnder free-threaded CPython (Py_GIL_DISABLED) the GIL provides no mutual\nexclusion, so the plain pointer last_storage_ptr_ was read and written\nconcurrently without synchronization, a C++ data race. Make it a\nstd::atomic\u003cT *\u003e.\n\nAlso reorder get_stored() to check is_last_storage_valid() before loading\nthe cached pointer. The writer publishes the pointer before setting the\nvalidity flag, so the flag must be observed first for correct\nacquire/release ordering.\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "59d7cb28c1f5a014bb17ad4a8e80da2fb51a6159",
      "tree": "2c16d087a829a8f11d10682992adf11d2771bc3a",
      "parents": [
        "da3bdcad040c1c2da02358e0ff5e281e9e97348a"
      ],
      "author": {
        "name": "Charles Beattie",
        "email": "cbeattie@google.com",
        "time": "Wed Jun 24 02:44:39 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 23 21:44:39 2026 -0400"
      },
      "message": "fix: add life support to handles cast to string_view (#6092)\n\n* Fix handling of string_view to prevent GC\u0027ing strings before they are used.\n\n* style: pre-commit fixes\n\n* Update cast.h\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "da3bdcad040c1c2da02358e0ff5e281e9e97348a",
      "tree": "bff2fcdd3dd02b4cbf21847f7a8255f78baac379",
      "parents": [
        "99117da02050edef2802322031eac9c40cfc1872"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Wed Jun 17 08:16:49 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 17 08:16:49 2026 -0400"
      },
      "message": "chore(setup_helpers): remove dead cpp_flag_cache and fix parameter typo (#6085)\n\nRemove the module-level `cpp_flag_cache \u003d None` variable and its stale\ncomment \"Every call will cache the result\". The actual caching is handled\nby the `@lru_cache` decorator on `auto_cpp_level` directly below.\n\nAlso rename the typo\u0027d parameter `obg` to `obj` in `no_recompile`.\nNothing passes this argument by keyword, so there is no API break.\n\nPart of #6084\n\nAssisted-by: ClaudeCode:claude-sonnet-4-6"
    },
    {
      "commit": "99117da02050edef2802322031eac9c40cfc1872",
      "tree": "a3d3de03cfbe932ffd61d2e0e51c3dcd8722138c",
      "parents": [
        "f00aa6fe079a77e2cf9a114ebafb3847d75e72cc"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Wed Jun 17 08:16:04 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 17 08:16:04 2026 -0400"
      },
      "message": "chore(eval): drop Python 2 coding cookie prepended to evaluated source (#6089)\n\nThe `# -*- coding: utf-8 -*-` line prepended to every string passed to\nPyRun_String was a Python 2 workaround. Python 3\u0027s PyRun_String already\nassumes UTF-8 source encoding, so the cookie is dead weight — and\nharmful: it shifts all line numbers up by one in tracebacks and\nSyntaxErrors from evaluated code (a `raise` on line 2 would incorrectly\nappear as line 3).\n\nRemove the cookie and replace the stale comment with one that explains\nthe actual reason for the `std::string` conversion (need a C string for\nPyRun_String). No other location in eval.h uses this pattern\n(eval_file reads directly from a FILE*).\n\nAssisted-by: ClaudeCode:claude-fable-5"
    },
    {
      "commit": "f00aa6fe079a77e2cf9a114ebafb3847d75e72cc",
      "tree": "0cd1e3d0064bd350e347c635f83246ebcdd8f380",
      "parents": [
        "ff1a35cb849247dd14d5c6c9aefae45a7ab6f695"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Wed Jun 17 08:13:47 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 17 08:13:47 2026 -0400"
      },
      "message": "ci: drop boost from 32-bit mingw32 install (#6091)\n\n* ci: drop boost from 32-bit mingw32 install\n\nMSYS2 removed the mingw-w64-i686-boost package (32-bit i686 is being\nphased out), so the mingw32 matrix entry now fails at the pacman install\nstep with \"target not found: mingw-w64-i686-boost\". Boost is optional\ntest coverage (boost::optional / boost::variant casters, gated behind\nPYBIND11_TEST_BOOST); without it those tests are skipped and the rest of\nthe job builds and runs normally. Move boost to the mingw64 extra_install\nso the 64-bit job keeps that coverage.\n\nAssisted-by: ClaudeCode:claude-opus-4.8\n\n* Apply suggestion from @henryiii"
    },
    {
      "commit": "ff1a35cb849247dd14d5c6c9aefae45a7ab6f695",
      "tree": "bb463226e8dbee479146609331279afb9bfc1cd1",
      "parents": [
        "ec1d8762a8ed9d786ba6ef500c3d1e54d5016288"
      ],
      "author": {
        "name": "Henry Schreiner",
        "email": "HenrySchreinerIII@gmail.com",
        "time": "Wed Jun 10 16:03:38 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 10 16:03:38 2026 -0400"
      },
      "message": "ci: update GraalPy from 24.2 to 25.0 (Python 3.12 based) (#6083)\n\n* ci: update GraalPy from 24.2 to 25.0 (Python 3.12 based)\n\n- Replace graalpy-24.2 with graalpy-25.0 in CI matrix\n- Replace graalpy-24.1 with graalpy-24.2 (shift older version up)\n- Remove dead GRAALPY_VERSION \u003c (24, 2) xfail guards from tests\n- Remove unused GRAALPY_VERSION from tests/env.py\n- Update internals.h comment to reference v25.0\n\nAssisted-by: OpenCode:glm-5\n\n* fix: use numpy 2.2.x for GraalPy 3.12 (graalpy312 wheels)\n\nnumpy 1.26.x only has graalpy311 wheels; GraalPy 25.0 (Python 3.12)\nrequires numpy 2.2.x which has graalpy312 wheels on the GraalVM index.\n\nAssisted-by: OpenCode:glm-5\n\n* fix: simplify numpy requirement for GraalPy (drop 3.11 branch)\n\nWe no longer test GraalPy 3.11, so the version split is unnecessary.\n\nAssisted-by: OpenCode:glm-5"
    },
    {
      "commit": "ec1d8762a8ed9d786ba6ef500c3d1e54d5016288",
      "tree": "cb93f2de17ed849bcaa3ee6822c525171b2ef86e",
      "parents": [
        "6079989cf70555d213add249cfb36dad14519791"
      ],
      "author": {
        "name": "pre-commit-ci[bot]",
        "email": "66853113+pre-commit-ci[bot]@users.noreply.github.com",
        "time": "Sat Jun 06 11:06:45 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 06 11:06:45 2026 -0700"
      },
      "message": "chore(deps): update pre-commit hooks (#6079)\n\nupdates:\n- [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)\n- [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)\n- [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)\n- [github.com/adhtruong/mirrors-typos: v1.46.0 → v1.47.0](https://github.com/adhtruong/mirrors-typos/compare/v1.46.0...v1.47.0)\n\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "6079989cf70555d213add249cfb36dad14519791",
      "tree": "701efb0bff2bb6489518dc17fa6c2ca303c6d880",
      "parents": [
        "46ebf5031b751f59337b498ce630df8659177492"
      ],
      "author": {
        "name": "Matti Picus",
        "email": "matti.picus@gmail.com",
        "time": "Wed May 27 18:07:53 2026 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 27 08:07:53 2026 -0700"
      },
      "message": "Pypy testing no longer xfails (#6077)\n\n* test passes on PyPy macOS\n\n* adjust tests for pypy HEAD\n\n* fixes from review\n\n* pypy 7.3.23 was released, drop some PyPy testing\n\n* pin to pypy version 7.3.23\n\n* Restore xfail for cross-module translator platforms\n\nKeep 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.\n\n---------\n\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "46ebf5031b751f59337b498ce630df8659177492",
      "tree": "aee8932f774497abb998a63fcf55259822162684",
      "parents": [
        "f891299e6adb7f90155d979907d3787836dd47d9"
      ],
      "author": {
        "name": "ymwang78",
        "email": "wangym@gmail.com",
        "time": "Mon May 25 21:31:14 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 25 09:31:14 2026 -0400"
      },
      "message": "feat(subinterpreter): reusable PyThreadState via subinterpreter_thread_state (#6073)\n\n* feat(subinterpreter): add opt-in TLS-cached thread state mode\n\nsubinterpreter_scoped_activate previously created and destroyed a fresh\nPyThreadState on every activation when the calling OS thread was not\nalready running the target interpreter. Workloads that repeatedly\nre-enter the same sub-interpreter from the same thread therefore churn\nthread states and lose per-thread interpreter state between activations\n(see pybind/pybind11#6040).\n\nAdd an opt-in subinterpreter_thread_state::cached policy: on first use a\nPyThreadState is created and stored in OS-thread-local storage keyed by\nthe target interpreter; subsequent activations on that thread only swap\nit in/out and never destroy it. The default stays transient, so existing\nbehavior is unchanged.\n\nSince pybind11 does not control thread lifetime, cleanup is explicit:\nsubinterpreter::release_cached_thread_state() releases the calling\nthread\u0027s cached state for one interpreter, and the static\nrelease_all_cached_thread_states() releases all of the calling thread\u0027s\ncached states as an end-of-thread hook. The TLS map\u0027s destructor only\nfrees its own nodes and never touches the Python C API, so an\nunreleased state leaks rather than crashing at thread exit.\n\nIncludes test coverage and embedding docs.\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n* style: pre-commit fixes\n\n* refactor(subinterpreter): replace cached enum/TLS with subinterpreter_thread_state RAII\n\nAddress review feedback on the original \"cached\" mode by switching to an\nexplicit two-RAII design suggested by @b-pass:\n\n  \"Create a class ... to RAII-manage the PyThreadState but start its\n   lifetime in an already released state. You could create another\n   class (or modify scoped_activate) to scoped/RAII activate the\n   inactive threadstate.\"\n\nRemoved\n  - enum subinterpreter_thread_state { transient, cached } and the\n    defaulted ctor parameter on subinterpreter_scoped_activate.\n  - detail::subinterpreter_thread_state_cache thread_local map.\n  - subinterpreter::release_cached_thread_state() and\n    subinterpreter::release_all_cached_thread_states().\n\nThis eliminates: the hidden per-thread map, the \"release_all\" footgun\nacross pybind11 modules (the cache was module-local), and the implicit\n\"must not be active when called\" contract on the release functions.\n\nAdded\n  - Public class subinterpreter_thread_state that owns one PyThreadState\n    for a given subinterpreter on its constructing OS thread, created in\n    a released state (not current, no GIL). Non-copyable, non-movable\n    (PyThreadState is bound to its creating OS thread).\n  - subinterpreter_scoped_activate(subinterpreter_thread_state \u0026)\n    overload: swaps the owned PyThreadState in on entry, swaps it out\n    on exit, does not touch its lifetime.\n\nBehavior\n  - The existing subinterpreter_scoped_activate(subinterpreter const \u0026)\n    overload is unchanged (still transient: New on entry, Delete on\n    exit). All previously-working code keeps working.\n  - With subinterpreter_thread_state, one OS thread can alternate\n    between multiple subinterpreters and each PyThreadState is preserved\n    across activations -- the use case that gil_scoped_release/acquire\n    + a long-lived scoped_activate cannot solve alone (the per-thread\n    internals.tstate slot holds only one inactive tstate).\n  - The dtor of subinterpreter_thread_state guards against the\n    \"destroyed-while-active\" contract violation: if Swap reveals the\n    cached tstate was current, do not Swap back to a now-deleted\n    pointer (the safe-when-active fix b-pass requested for the old\n    release_* functions, applied at the natural location instead).\n\nLifetime contract is enforced by ordinary C++ scope: typical placement\nis `thread_local`. No new release/cleanup APIs are required.\n\nTests cover (a) tstate identity preserved across activations on a\nthread, (b) transient and reusing modes do not share state, (c)\ndifferent OS threads get distinct PyThreadStates, and (d) the\nmulti-subinterpreter alternation case.\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n* fix(subinterpreter): address review on #6073 (same-thread checks, test scoping)\n\nPer @b-pass\u0027s review:\n\n- ~subinterpreter_thread_state(): add a PYBIND11_DETAILED_ERROR_MESSAGES-\n  guarded check that destruction happens on the OS thread that created the\n  PyThreadState (same PyThread_get_thread_native_id pattern as ~subinterpreter),\n  failing with pybind11_fail otherwise.\n- subinterpreter_scoped_activate(subinterpreter_thread_state \u0026): add the\n  matching DETAILED_ERROR_MESSAGES check that activation happens on the\n  creating OS thread, enforcing the newly documented rule.\n- docs: document that activating a subinterpreter_thread_state on another OS\n  thread is illegal.\n- tests: keep each subinterpreter (and its subinterpreter_thread_state) in an\n  enclosing scope so destruction order is thread-state -\u003e subinterpreter -\u003e\n  unsafe_reset_internals_for_single_interpreter(). The previous top-level\n  declarations ran the reset while the subinterpreters were still alive, which\n  is the likely cause of the CI crashes.\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n* docs: fix codespell (re-used -\u003e reused) in embedding.rst\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n---------\n\nCo-authored-by: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "f891299e6adb7f90155d979907d3787836dd47d9",
      "tree": "49272c4c38d10051727dd4d7cf247b82bc039fdc",
      "parents": [
        "a2592ad9d6510a4d48b4706852ef812bb01401c4"
      ],
      "author": {
        "name": "ctmd1234567",
        "email": "wang195072@gmail.com",
        "time": "Mon May 25 12:04:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun May 24 21:04:39 2026 -0700"
      },
      "message": "Fix custom __str__ for enum_ (#6078)\n\n* fix: prioritize custom enum __str__\n\n* test: strengthen custom enum __str__ regression\n\n* refactor: move enum __str__ handling into enum_\n\nKeep class_::def() generic and let enum_ own the enum-specific\nbehavior for custom __str__ overloads. This avoids using the private\n__entries attribute as a runtime sentinel for py::enum_ while preserving\nthe prepend behavior that lets user-defined enum __str__ methods take\nprecedence over the generated default.\n\nOne caveat is that this applies to normal py::enum_ API usage. Code that\nintentionally upcasts an enum_ binding to class_\u0026 and then calls\nclass_::def(\"__str__\", ...) will bypass this enum_ override and keep the\ngeneric class_ behavior.\n\n* fix: avoid enum def ambiguity on MinGW\n\nRemove 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.\n\n---------\n\nCo-authored-by: ctmd1234567 \u003cctmd1234567@users.noreply.github.com\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "a2592ad9d6510a4d48b4706852ef812bb01401c4",
      "tree": "65c0deeecb7aa9f754c3ae24adc4b7136a575813",
      "parents": [
        "5205df97fcb47015fac2feb06306c58ba80fd88f"
      ],
      "author": {
        "name": "jjuang-apple",
        "email": "jjuang@apple.com",
        "time": "Sun May 24 11:28:53 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun May 24 11:28:53 2026 -0700"
      },
      "message": "Apply -undefined dynamic_lookup to all Apple platforms (#6075)\n\n* Apply -undefined dynamic_lookup to all Apple platforms\n\n* style: pre-commit fixes\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "5205df97fcb47015fac2feb06306c58ba80fd88f",
      "tree": "48d391226718c80a5c70e072d6f43d44ef48d7cb",
      "parents": [
        "28bbda9ddf974f5f077059716bfbd3a3d77738bc"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Wed May 20 15:23:32 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 20 15:23:32 2026 -0700"
      },
      "message": "chore(deps): bump idna from 3.7 to 3.15 in /docs (#6074)\n\nBumps [idna](https://github.com/kjd/idna) from 3.7 to 3.15.\n- [Release notes](https://github.com/kjd/idna/releases)\n- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md)\n- [Commits](https://github.com/kjd/idna/compare/v3.7...v3.15)\n\n---\nupdated-dependencies:\n- dependency-name: idna\n  dependency-version: \u00273.15\u0027\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "28bbda9ddf974f5f077059716bfbd3a3d77738bc",
      "tree": "ac17c0136f138a8f3bab888cb4ea8544467e70e2",
      "parents": [
        "3160c82392900f824deeb875e903f84679c1c64d"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Mon May 18 21:36:16 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 18 21:36:16 2026 -0700"
      },
      "message": "[skip ci] test: reject shared_ptr casts for custom holders (#6069)\n\nLock down the current behavior discussed in issue #6064: py::cast() from std::shared_ptr\u003cT\u003e remains rejected for custom holder bindings that are not std::shared_ptr or py::smart_holder.\n\nThis 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."
    },
    {
      "commit": "3160c82392900f824deeb875e903f84679c1c64d",
      "tree": "5b2b2802b2a05cff4dc60218e4d9bf9b2154ee76",
      "parents": [
        "5a5f21deb6c1dbfe8fc36547419d188ce7ab30cc"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Mon May 18 11:31:19 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 18 11:31:19 2026 -0700"
      },
      "message": "ci: pin Ubuntu PyPy 3.11 to 7.3.21 (#6070)"
    },
    {
      "commit": "5a5f21deb6c1dbfe8fc36547419d188ce7ab30cc",
      "tree": "9e6e01e69e8a937dfdda21fa935b2e76d689ebbc",
      "parents": [
        "00a9c6244ca6213cf47ba4dd74654ca93fdfedbb"
      ],
      "author": {
        "name": "Matthias Klumpp",
        "email": "matthias@tenstral.net",
        "time": "Sat May 16 20:28:05 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 16 11:28:05 2026 -0700"
      },
      "message": "fix: Invert input/output context if a Python function is called from C++ (#6055)\n\nWhen the Callable itself is an input (parameter) to a C++ function, its\narguments are outputs (C++ passes them to the Python callback), and vice\nversa.\nTherefore, we must invert them if C++ calls a Python function, but keep\nthem the same in the other direction."
    },
    {
      "commit": "00a9c6244ca6213cf47ba4dd74654ca93fdfedbb",
      "tree": "4027d40d222e8bd27bcf457e2025c9a7da92fede",
      "parents": [
        "59a917db6b6664b390e52573fa6aa263856b1195"
      ],
      "author": {
        "name": "pre-commit-ci[bot]",
        "email": "66853113+pre-commit-ci[bot]@users.noreply.github.com",
        "time": "Wed May 13 19:03:57 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 13 19:03:57 2026 -0700"
      },
      "message": "chore(deps): update pre-commit hooks (#6054)\n\n* chore(deps): update pre-commit hooks\n\nupdates:\n- [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)\n- [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)\n- [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)\n- [github.com/adhtruong/mirrors-typos: v1.45.0 → v1.46.0](https://github.com/adhtruong/mirrors-typos/compare/v1.45.0...v1.46.0)\n- [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)\n\n* fix: correct detailed error message comment wording\n\nClarify when detailed error messages are enabled and remove the typo caught by typos.\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] \u003c66853113+pre-commit-ci[bot]@users.noreply.github.com\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "59a917db6b6664b390e52573fa6aa263856b1195",
      "tree": "91167e94f40cf5885783b908d176d913f9940102",
      "parents": [
        "81817aed7ebf4f93ae803a66faf8c7e97f069073"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Wed May 13 17:16:53 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 13 17:16:53 2026 -0700"
      },
      "message": "chore(deps): bump urllib3 from 2.6.3 to 2.7.0 in /docs (#6058)\n\nBumps [urllib3](https://github.com/urllib3/urllib3) from 2.6.3 to 2.7.0.\n- [Release notes](https://github.com/urllib3/urllib3/releases)\n- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)\n- [Commits](https://github.com/urllib3/urllib3/compare/2.6.3...2.7.0)\n\n---\nupdated-dependencies:\n- dependency-name: urllib3\n  dependency-version: 2.7.0\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "81817aed7ebf4f93ae803a66faf8c7e97f069073",
      "tree": "c8bb490cf1621154b89e06f89557df1a1f0d5368",
      "parents": [
        "9cc298a48157dc988f632503f252e52baa2ab97e"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Sat May 02 19:02:46 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 02 19:02:46 2026 -0700"
      },
      "message": "ci: remove the deadsnakes job (#6052)\n\nDrop 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.\n\nCo-authored-by: Cursor \u003ccursoragent@cursor.com\u003e"
    },
    {
      "commit": "9cc298a48157dc988f632503f252e52baa2ab97e",
      "tree": "5a95d23ac8782d17a36c1bd36a95e6b662e0a022",
      "parents": [
        "c5b3ae8168b887c0beb1d2b387a7c082b8ccc39d"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Sat May 02 17:49:31 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 02 17:49:31 2026 -0700"
      },
      "message": "ci: pass explicit ARM64 Python artifacts on windows-11-arm (#6051)\n\nAvoid 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.\n\nCo-authored-by: Cursor \u003ccursoragent@cursor.com\u003e"
    },
    {
      "commit": "c5b3ae8168b887c0beb1d2b387a7c082b8ccc39d",
      "tree": "9e2e5add7ca0556b329275c0214f54cf266982a6",
      "parents": [
        "ee1d83f6c134609df8d177b239115c034e5f9e6c"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Sat May 02 16:03:42 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 02 16:03:42 2026 -0700"
      },
      "message": "ci: pin PyPy 3.11 to 7.3.21 on macOS and Windows (#6050)\n\nTemporarily pin the two failing PyPy 3.11 jobs while investigating the PyPy 7.3.22 import regression.\n\nRefs #6049.\n\nCo-authored-by: Cursor \u003ccursoragent@cursor.com\u003e"
    },
    {
      "commit": "ee1d83f6c134609df8d177b239115c034e5f9e6c",
      "tree": "51d5edc4c8c6f417066eacebdf82ac8f826abadb",
      "parents": [
        "0f8396e4fff99814a3b3f96cf30e1832c2d5f03a"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sat May 02 13:14:44 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 02 13:14:44 2026 -0700"
      },
      "message": "chore(deps): bump the actions group with 2 updates (#6047)\n\nBumps 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).\n\n\nUpdates `astral-sh/setup-uv` from 8.0.0 to 8.1.0\n- [Release notes](https://github.com/astral-sh/setup-uv/releases)\n- [Commits](https://github.com/astral-sh/setup-uv/compare/v8.0.0...v8.1.0)\n\nUpdates `scientific-python/upload-nightly-action` from 0.6.3 to 0.6.4\n- [Release notes](https://github.com/scientific-python/upload-nightly-action/releases)\n- [Commits](https://github.com/scientific-python/upload-nightly-action/compare/5748273c71e2d8d3a61f3a11a16421c8954f9ecf...e76cfec8a4611fd02808a801b0ff5a7d7c1b2d99)\n\n---\nupdated-dependencies:\n- dependency-name: astral-sh/setup-uv\n  dependency-version: 8.1.0\n  dependency-type: direct:production\n  update-type: version-update:semver-minor\n  dependency-group: actions\n- dependency-name: scientific-python/upload-nightly-action\n  dependency-version: 0.6.4\n  dependency-type: direct:production\n  update-type: version-update:semver-patch\n  dependency-group: actions\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "0f8396e4fff99814a3b3f96cf30e1832c2d5f03a",
      "tree": "0445bb29d1ceeebe4f88df44e775454de7bad8e2",
      "parents": [
        "d4336108df0171e23774def1ff007c259a254d09"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Sat May 02 11:47:01 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 02 11:47:01 2026 -0700"
      },
      "message": "[skip ci] ci: schedule recurring CI and CIBW runs (#6048)\n\nRun ci.yml and tests-cibw.yml twice weekly so master bitrot is easier to spot and root-cause before weekend maintenance.\n\nCo-authored-by: Cursor \u003ccursoragent@cursor.com\u003e"
    },
    {
      "commit": "d4336108df0171e23774def1ff007c259a254d09",
      "tree": "bb0bed87e1ff612a628479cc02e023d1f5f8cc90",
      "parents": [
        "678b6735e44fe9d7feac7ff31bc9c86d42c04613"
      ],
      "author": {
        "name": "Christoph Grüninger",
        "email": "foss@grueninger.de",
        "time": "Mon Apr 27 02:06:06 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Apr 26 17:06:06 2026 -0700"
      },
      "message": "[ci] Drop GitHub Action seanmiddleditch/gha-setup-ninja (#6044)\n\nFrom the GitHub Action README: \"This action is no longer\nnecessary, as ninja is now included on all default\nGitHub runner instances.\""
    },
    {
      "commit": "678b6735e44fe9d7feac7ff31bc9c86d42c04613",
      "tree": "bf725482c6e6681cf385a4c324908c191e1b2b20",
      "parents": [
        "ae05b1556632cf1469ee99a9d3836a8fb861da8d"
      ],
      "author": {
        "name": "Eisuke Kawashima",
        "email": "e.kawaschima+github@gmail.com",
        "time": "Sun Apr 19 07:10:30 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Apr 18 15:10:30 2026 -0700"
      },
      "message": "build: support Eigen 5 (#6036)\n\n* build: support Eigen 5\n\nfix #6034\n\n* build: probe Eigen 3 and 5 separately in CMake config mode\n\nAvoid relying on package-specific handling of a bounded version range when discovering Eigen through Eigen3Config.cmake.\n\nMade-with: Cursor\n\n* [skip ci] build: clarify Eigen 5 module fallback comment\n\nExplain 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.\n\nMade-with: Cursor\n\n* [skip ci] docs: add Eigen 5 entry to v3.0.4 changelog\n\nDocument the Eigen 5 CMake package detection fix in the 3.0.4 release notes before merging the PR.\n\nMade-with: Cursor\n\n---------\n\nCo-authored-by: Eisuke Kawashima \u003ce-kwsm@users.noreply.github.com\u003e\nCo-authored-by: Ralf W. Grosse-Kunstleve \u003crgrossekunst@nvidia.com\u003e"
    },
    {
      "commit": "ae05b1556632cf1469ee99a9d3836a8fb861da8d",
      "tree": "60ab6babceac79fc1b59658c5550dc8abc12f3b7",
      "parents": [
        "7029f99cc62beb9f8c2b13dfaaa1ef04e040cb60"
      ],
      "author": {
        "name": "Ralf W. Grosse-Kunstleve",
        "email": "rwgkio@gmail.com",
        "time": "Sun Apr 19 01:47:16 2026 +0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Apr 18 11:47:16 2026 -0700"
      },
      "message": "[skip ci] docs: add v3.0.4 changelog updates. (#6041)\n\nDocument 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.\n\nMade-with: Cursor"
    }
  ],
  "next": "7029f99cc62beb9f8c2b13dfaaa1ef04e040cb60"
}
