Open
Conversation
…5986) Replace the fixed sleep in test_async_callbacks with a bounded wait for all expected callback results, so detached worker scheduling no longer causes sporadic CI failures. Co-authored-by: Cursor <cursoragent@cursor.com>
tomlkit is used only in the packaging tests which are not ordinarily run as part of the normal workflow of a user or downstream packager. Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
* Re-enable Android tests in CIBW workflow * Skip subprocess tests on Android * Remove Android workarounds no longer necessary with current cibuildwheel version * Skip more subprocess tests on Android
* chore: use PyType_GetFlags Signed-off-by: Henry Schreiner <henryfs@princeton.edu> * chore: use public VectorCall in 3.9+ Signed-off-by: Henry Schreiner <henryfs@princeton.edu> --------- Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
…ecord (pybind#6010) * pybindgh-5991: Fix segfault during finalization related to function_record This patch was developed with assistance from Claude Code Opus 4.6 Here's Claude's explanation of the crash mechanism and some reasoning for the difficulty to repro: `tp_dealloc_impl` calls `cpp_function::destruct` which: 1. Calls `std::free()` on function_record string members (`name`, `doc`, `signature`) 2. Calls `arg.value.dec_ref()` on default argument values 3. Calls `delete rec` on the function_record But it never calls `PyObject_Free(self)` or `Py_DECREF(Py_TYPE(self))`, which are required for heap types. During `_Py_Finalize`, final GC collects the heap types (which survive module dict clearing via `tp_mro` self-references). This triggers a massive cascade: `type_dealloc → property_dealloc → meth_dealloc → tp_dealloc_impl → destruct`. At scale (~1,200+ function_records), the volume of `delete`/`free` calls corrupts heap metadata, causing subsequent `std::free()` to receive garbage pointers → SEGV. * Add detail::py_is_finalizing() wrapper to deduplicate version-guarded #ifdef blocks Also fixes clang-tidy readability-implicit-bool-conversion warnings. Made-with: Cursor --------- Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
…hon 3.13+ (pybind#5999) * fix: clear managed dict in pybind11_object_dealloc on Python 3.13+ On Python 3.14, PyObject_GC_Del (tp_free) no longer implicitly clears the managed dict of objects with Py_TPFLAGS_MANAGED_DICT. Without an explicit PyObject_ClearManagedDict() call before tp_free(), objects stored in the __dict__ of py::dynamic_attr() instances have their refcounts permanently abandoned, causing memory leaks — capsule destructors for numpy arrays (and other objects) never run. Adds a regression test: stores a py::capsule in the __dict__ of a DynamicClass instance and asserts the capsule destructor is called when the instance is deleted. * [tests]: mark test_dynamic_attr_dealloc_frees_dict_contents to be strict=False xfail on PYPY * [docs]: clarify Python version comments in pybind11_object_dealloc Distinguish between when the API is available (3.13+, where PyObject_ClearManagedDict was introduced) and when the leak actually manifests (3.14+, where tp_free stopped implicitly clearing the managed dict). --------- Co-authored-by: Yury Matveev <yury.matveev@desy.de>
Explicitly specify the 4th template parameter in the single-factory partial specialization of `factory` to disambiguate it from the dual-factory specialization when compiled with nvcc + GCC 14. Fixes pybind#5565. Co-authored-by: Oz <oz-agent@warp.dev>
…older classes (v2) (pybind#6008) * Add tests that cause crash in def_readwrite - Occurs with non-smart-holder property of smart-holder class * Fix crash in def_readwrite for non-smart-holder properties of smart-holder classes * Use default policy * Address PR comments * Add test for cast error path * style: pre-commit fixes * Revert "Use default policy" This reverts commit b299f32. * Disable test_shared_ptr_return_for_unique_ptr_holder when PYBIND11_TEST_SMART_HOLDER=ON * Add counterexample --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
…lasses (pybind#5992) * Strip noexcept from cpp17 function type bindings * Fix a bug and increase test coverage * Does this fix it? * Silence clang-tidy issue * Simplify method adapter with macro and add missing rvalue adaptors + tests * Supress clang-tidy errors * Improve test coverage * Add additional static assert * Try to resolve MSVC C4003 warning * Simplify method adaptor into 2 template instatiations with enable_if_t * Fix ambiguous STL template * Close remaining qualifier consistency gaps for member pointer bindings. A production-code review after pybind#2234 showed that ref-qualified member pointers were still inconsistently handled across def_buffer, vectorize, and overload_cast, so this adds the missing overloads with focused tests for each newly-supported signature. Co-authored-by: Cursor <cursoragent@cursor.com> * Clarify why def_buffer/vectorize omit rvalue-qualified overloads. These comments were added while reviewing the qualifier coverage follow-up, to document that buffer/vectorized calls operate on existing Python-owned instances and should not move-from self. Co-authored-by: Cursor <cursoragent@cursor.com> * Add compile-only overload_cast guard for ref-qualified methods. This was added as a maintenance follow-up to the qualifier-consistency work, so future changes that introduce overload_cast ambiguity or wrong ref/noexcept resolution fail at compile time. Co-authored-by: Cursor <cursoragent@cursor.com> * Refactor overload_cast_impl qualifier overloads with a macro. As part of the qualifier-consistency maintenance follow-up, this reduces duplication in overload_cast_impl while preserving the same ref/noexcept coverage and keeping pedantic-clean macro expansion. Co-authored-by: Cursor <cursoragent@cursor.com> * Expose __cpp_noexcept_function_type to Python tests and use explicit skip guards. This replaces hasattr-based optional assertions with skipif-gated noexcept-only tests so skipped coverage is visible in pytest output while keeping non-noexcept checks always active. Co-authored-by: Cursor <cursoragent@cursor.com> * Add static_assert in method_adaptor to guard that T is a member function pointer. Suggested by @Skylion007 in PR pybind#5992 review comment [T007]. Made-with: Cursor * automatic clang-format change (because of pybind#6002) --------- Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com> Co-authored-by: Cursor <cursoragent@cursor.com>
…holder_caster_foreign_helpers.h` (pybind#6014) * Add regression test for pybind#5989: static_pointer_cast fails with virtual inheritance When a class uses virtual inheritance and its holder type is shared_ptr, passing a shared_ptr of the derived type as a method argument triggers a compilation error because static_pointer_cast cannot downcast through a virtual base (dynamic_pointer_cast is needed instead). Made-with: Cursor * Fix pybind#5989: use dynamic_pointer_cast for virtual inheritance in esft downcast Replace the unconditional static_pointer_cast in set_via_shared_from_this with a SFINAE-dispatched esft_downcast helper that falls back to dynamic_pointer_cast when static_cast through a virtual base is ill-formed. Also add a workaround in the test binding (.def("name") on SftVirtDerived2) for a separate pre-existing issue with inherited method dispatch through virtual bases. Made-with: Cursor
…ybind#6020) Replace `static thread_specific_storage<int>` with `thread_local bool` in the implicit conversion reentrancy guard. Since implicitly_convertible is a template function, each unique <InputType, OutputType> pair created its own TSS key via PyThread_tss_create(). Projects with hundreds of modules and many implicit conversions could exhaust PTHREAD_KEYS_MAX (1024 on Linux, 512 on macOS), especially on Python 3.12+ where CPython itself consumes more TSS keys for subinterpreter support. thread_local bool is safe here because: - bool is trivially destructible, so it works on all C++11 platforms including older macOS (the concern that motivated the TSS approach in PR pybind#5777 applied only to types with non-trivial destructors needing __cxa_thread_atexit runtime support) - Each thread gets its own copy, so it is thread-safe for free-threading - Subinterpreter sharing is benign: the guard prevents recursive implicit conversions on the same thread regardless of which interpreter is active - The v3.0.0 code already used thread_local bool under Py_GIL_DISABLED This effectively reverts the core change from PR pybind#5777 while keeping the non-copyable/non-movable set_flag guard. Made-with: Cursor
… during module init (pybind#6018) * Wrap ensure_internals() in try-catch in PYBIND11_MODULE_PYINIT Previously, ensure_internals() was called without exception handling in the PyInit_* function (PYBIND11_MODULE_PYINIT), while the same call in PYBIND11_MODULE_EXEC was already wrapped in try-catch. On MSVC, a C++ exception propagating through the extern "C" PyInit_* boundary is undefined behavior, which can manifest as an access violation instead of a clean error message. This is a potential contributor to crashes like pybindgh-5993. Wrap the entire PyInit body in try/catch using the existing PYBIND11_CATCH_INIT_EXCEPTIONS pattern. Made-with: Cursor * Add nullptr guards in get_internals() for better crash diagnostics Add explicit null checks after get_pp() and create_pp_content_once() in get_internals(), calling pybind11_fail() with descriptive messages. These guards convert potential null-pointer dereferences (which produce unhelpful access-violation crashes, especially on Windows) into clear runtime_error messages that can be caught and reported as ImportError by the try-catch added in the previous commit. Made-with: Cursor
…ybind#6010 (pybindgh-5976) (pybind#6015) * fix: strdup args added after initialize_generic in def_property_static (pybindgh-5976) `def_property_static` calls `process_attributes::init` on already-initialized function records (after `initialize_generic`'s strdup loop has run). Args added at this stage (e.g. "self" via `append_self_arg_if_needed`) remain as string literals, so `destruct()` would call `free()` on them. Fix by strdup'ing name/descr of any args appended by the late `process_attributes::init` call. Root cause introduced by pybindgh-5486. Made-with: Cursor * Partially revert pybindgh-6010: remove py_is_finalizing() workarounds Now that the root cause (free of string literals in def_property_static, pybindgh-5976) is fixed in the previous commit, the py_is_finalizing() guards introduced in pybindgh-6010 are no longer needed: - tp_dealloc_impl: remove early return during finalization (was leaking all function records instead of properly destroying them) - destruct(): remove guard around arg.value.dec_ref() - common.h: remove py_is_finalizing() helper (no remaining callers) The genuine fix from pybindgh-6010 (PyObject_Free + Py_DECREF ordering in tp_dealloc_impl) is retained. Made-with: Cursor * test: add embedding test for py::enum_ across interpreter restart (pybindgh-5976) py::enum_ is the primary trigger for pybindgh-5976 because its constructor creates properties via def_property_static / def_property_readonly_static, which call process_attributes::init on already-initialized function records. Yet none of the existing embedding tests used py::enum_ at all. Add an PYBIND11_EMBEDDED_MODULE with py::enum_ and a test case that imports it, finalize/reinitializes the interpreter, and re-imports it. This exercises the def_property_static code path that was fixed in the preceding commit. Note: on Python 3.14.2 (and likely 3.12+), tp_dealloc_impl is not called during Py_FinalizeEx for function record PyObjects — they simply leak because types are effectively immortalized. As a result, this test cannot trigger the original free()-on-string-literal crash on this Python version. However, it remains valuable as a regression guard: on Python builds where finalization does clean up function records (or if CPython changes this behavior), the test would catch the crash. It also verifies that py::enum_ survives interpreter restart correctly, which was previously untested. Made-with: Cursor * test: skip enum restart test on Python 3.12 (pre-existing crash) Made-with: Cursor * Add test_standalone_enum_module.py, standalone_enum_module.cpp * Make standalone_enum_module.cpp more similar to pybind#5976 reproducer. Also fix clang-tidy error. * This crashes when testing locally: ( cd /wrk/forked/pybind11/tests && PYTHONPATH=/wrk/bld/pybind11_gcc_v3.14.2_df793163d58_default/lib /wrk/bld/pybind11_gcc_v3.14.2_df793163d58_default/TestVenv/bin/python3 -m pytest test_standalone_enum_module.py ) ============================= test session starts ============================== platform linux -- Python 3.14.2, pytest-9.0.2, pluggy-1.6.0 installed packages of interest: build==1.4.2 numpy==2.4.3 scipy==1.17.1 C++ Info: 13.3.0 C++20 __pybind11_internals_v12_system_libstdcpp_gxx_abi_1xxx_use_cxx11_abi_1__ PYBIND11_SIMPLE_GIL_MANAGEMENT=False rootdir: /wrk/forked/pybind11/tests configfile: pytest.ini plugins: timeout-2.4.0, xdist-3.8.0 collected 1 item test_standalone_enum_module.py F [100%] =================================== FAILURES =================================== ________________________ test_enum_import_exit_no_crash ________________________ def test_enum_import_exit_no_crash(): # Modeled after reproducer under issue pybind#5976 > env.check_script_success_in_subprocess( f""" import sys sys.path.insert(0, {os.path.dirname(env.__file__)!r}) import standalone_enum_module as m assert m.SomeEnum.__class__.__name__ == "pybind11_type" """, rerun=1, ) test_standalone_enum_module.py:10: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ code = 'import sys\nsys.path.insert(0, \'/wrk/forked/pybind11/tests\')\nimport standalone_enum_module as m\nassert m.SomeEnum.__class__.__name__ == "pybind11_type"' def check_script_success_in_subprocess(code: str, *, rerun: int = 8) -> None: """Runs the given code in a subprocess.""" import os import subprocess import sys import textwrap if ANDROID or IOS or sys.platform.startswith("emscripten"): pytest.skip("Requires subprocess support") code = textwrap.dedent(code).strip() try: for _ in range(rerun): # run flakily failing test multiple times subprocess.check_output( [sys.executable, "-c", code], cwd=os.getcwd(), stderr=subprocess.STDOUT, text=True, ) except subprocess.CalledProcessError as ex: > raise RuntimeError( f"Subprocess failed with exit code {ex.returncode}.\n\n" f"Code:\n" f"```python\n" f"{code}\n" f"```\n\n" f"Output:\n" f"{ex.output}" ) from None E RuntimeError: Subprocess failed with exit code -6. E E Code: E ```python E import sys E sys.path.insert(0, '/wrk/forked/pybind11/tests') E import standalone_enum_module as m E assert m.SomeEnum.__class__.__name__ == "pybind11_type" E ``` E E Output: E munmap_chunk(): invalid pointer _ = 0 code = 'import sys\nsys.path.insert(0, \'/wrk/forked/pybind11/tests\')\nimport standalone_enum_module as m\nassert m.SomeEnum.__class__.__name__ == "pybind11_type"' os = <module 'os' (frozen)> rerun = 1 subprocess = <module 'subprocess' from '/wrk/cpython_installs/v3.14.2_df793163d58_default/lib/python3.14/subprocess.py'> sys = <module 'sys' (built-in)> textwrap = <module 'textwrap' from '/wrk/cpython_installs/v3.14.2_df793163d58_default/lib/python3.14/textwrap.py'> env.py:68: RuntimeError =========================== short test summary info ============================ FAILED test_standalone_enum_module.py::test_enum_import_exit_no_crash - Runti... ============================== 1 failed in 0.23s =============================== ERROR: completed_process.returncode=1 * Add "Added in PR pybind#6015" comments, for easy reference back to this PR * test: use PYBIND11_CATCH2_SKIP_IF for Python 3.12 enum restart skip Replace #if/#else/#endif preprocessor guard with runtime PYBIND11_CATCH2_SKIP_IF so the test is always compiled and shows [ SKIPPED ] in output on Python 3.12. Made-with: Cursor * fix: suppress MSVC C4127 in PYBIND11_CATCH2_SKIP_IF macro The constant condition in PYBIND11_CATCH2_SKIP_IF triggers MSVC warning C4127 (conditional expression is constant), which becomes a build error under /WX. Made-with: Cursor
… crash (pybind#6017) Virtual inheritance places the base subobject at a dynamic offset, but load_impl Case 2a uses reinterpret_cast which assumes a fixed offset. This caused segfaults when dispatching inherited methods through virtual bases (e.g. SftVirtDerived2::name()). Add an is_static_downcastable SFINAE trait that detects whether static_cast<Derived*>(Base*) is valid. When it is not (virtual inheritance), set multiple_inheritance = true in add_base to force the implicit_casts path, which correctly adjusts pointers at runtime. Remove the workaround .def("name", &SftVirtDerived2::name) from test_smart_ptr.cpp that was papering over the issue. Made-with: Cursor
…nd#6019) * Fix heap-buffer-overflow in pythonbuf with undersized buffers (pybindgh-5886) The _sync() UTF-8 remainder logic can leave pptr() past the end of the allocated buffer when buf_size < 4: after moving up to 3 bytes of an incomplete UTF-8 sequence to the front, pbump(remainder) pushes pptr() beyond epptr() and the buffer boundary. The next overflow() then writes out of bounds. Fix by clamping the buffer size to a minimum of 4 in the constructor, ensuring the maximum UTF-8 remainder (3 bytes) plus the overflow slot (1 byte) always fits within the allocated buffer. Made-with: Cursor * Avoid C++14 ODR-use linker error for minimum_buffer_size std::max takes arguments by const&, which ODR-uses the static constexpr member and requires an out-of-line definition in C++14. Replace with a ternary expression that uses the value without taking its address. Made-with: Cursor
* chore(deps): update pre-commit hooks updates: - [github.com/pre-commit/mirrors-clang-format: v21.1.8 → v22.1.0](pre-commit/mirrors-clang-format@v21.1.8...v22.1.0) - [github.com/astral-sh/ruff-pre-commit: v0.14.14 → v0.15.4](astral-sh/ruff-pre-commit@v0.14.14...v0.15.4) - [github.com/adhtruong/mirrors-typos: v1.42.3 → v1.44.0](adhtruong/mirrors-typos@v1.42.3...v1.44.0) - [github.com/PyCQA/pylint: v4.0.4 → v4.0.5](pylint-dev/pylint@v4.0.4...v4.0.5) - [github.com/python-jsonschema/check-jsonschema: 0.36.1 → 0.37.0](python-jsonschema/check-jsonschema@0.36.1...0.37.0) * style: pre-commit fixes --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Bumps [requests](https://github.com/psf/requests) from 2.32.4 to 2.33.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](psf/requests@v2.32.4...v2.33.0) --- updated-dependencies: - dependency-name: requests dependency-version: 2.33.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Cherry-picked PRs from master, for v3.0.3 release.
TODO: changelog update, version number update
📚 Documentation preview 📚: https://pybind11--6022.org.readthedocs.build/