Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pybind11 for openSUSE:Factory
checked in at 2026-05-12 19:26:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pybind11 (Old)
and /work/SRC/openSUSE:Factory/.python-pybind11.new.1966 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pybind11"
Tue May 12 19:26:13 2026 rev:28 rq:1352321 version:3.0.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pybind11/python-pybind11.changes
2026-04-13 23:18:01.810004561 +0200
+++
/work/SRC/openSUSE:Factory/.python-pybind11.new.1966/python-pybind11.changes
2026-05-12 19:26:33.402809690 +0200
@@ -1,0 +2,15 @@
+Sun May 10 11:21:16 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 3.0.4:
+ * Fixed test builds with installed Eigen 5 by improving
+ `Eigen3` CMake package detection.
+ * Fixed move semantics of `scoped_ostream_redirect` to preserve
+ buffered output and avoid crashes when moved redirects
+ restore stream buffers.
+ * Fixed `py::dynamic_attr()` traversal on Python 3.13+ to
+ correctly propagate `PyObject_VisitManagedDict()` results.
+ * Fixed `std::shared_ptr<T>` fallback casting to avoid
+ unnecessary copy-constructor instantiation in
+ `reference_internal` paths.
+
+-------------------------------------------------------------------
Old:
----
pybind11-3.0.3.tar.gz
New:
----
pybind11-3.0.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pybind11.spec ++++++
--- /var/tmp/diff_new_pack.6w9xW5/_old 2026-05-12 19:26:34.058836879 +0200
+++ /var/tmp/diff_new_pack.6w9xW5/_new 2026-05-12 19:26:34.058836879 +0200
@@ -18,23 +18,21 @@
%global flavor @BUILD_FLAVOR@%{nil}
%if "%{flavor}" == "test"
-%bcond_without test
%define psuffix -test
+%bcond_without test
%else
-%bcond_with test
%define psuffix %{nil}
+%bcond_with test
%endif
-
%if 0%{?suse_version} > 1500
%bcond_without libalternatives
%else
%bcond_with libalternatives
%endif
-
%define plainpython python
%{?sle15_python_module_pythons}
Name: python-pybind11%{psuffix}
-Version: 3.0.3
+Version: 3.0.4
Release: 0
Summary: Module for operability between C++11 and Python
License: BSD-3-Clause
@@ -49,9 +47,10 @@
BuildRequires: fdupes
BuildRequires: gcc-c++
BuildRequires: python-rpm-macros >= 20220912
+BuildArch: noarch
%if %{with libalternatives}
-Requires: alts
BuildRequires: alts
+Requires: alts
%else
Requires(post): update-alternatives
Requires(postun): update-alternatives
@@ -62,7 +61,6 @@
BuildRequires: %{python_module pytest-timeout}
BuildRequires: %{python_module pytest}
%endif
-BuildArch: noarch
%python_subpackages
%description
@@ -89,7 +87,7 @@
This package contains files for developing applications using pybind11.
%prep
-%setup -q -n pybind11-%{version}
+%autosetup -p1 -n pybind11-%{version}
%build
%if !%{with test}
++++++ pybind11-3.0.3.tar.gz -> pybind11-3.0.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/.github/workflows/ci.yml
new/pybind11-3.0.4/.github/workflows/ci.yml
--- old/pybind11-3.0.3/.github/workflows/ci.yml 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/.github/workflows/ci.yml 2026-04-19 05:01:51.000000000
+0200
@@ -188,7 +188,7 @@
allow-prereleases: true
- name: Install uv
- uses: astral-sh/setup-uv@v7
+ uses: astral-sh/[email protected]
with:
enable-cache: true
@@ -302,7 +302,7 @@
debug: ${{ matrix.python-debug }}
- name: Update CMake
- uses: jwlawson/[email protected]
+ uses: jwlawson/[email protected]
- name: Valgrind cache
if: matrix.valgrind
@@ -570,7 +570,7 @@
run: python3 -m pip install --upgrade pip
- name: Update CMake
- uses: jwlawson/[email protected]
+ uses: jwlawson/[email protected]
- name: Configure
shell: bash
@@ -906,7 +906,7 @@
${{ matrix.python == '3.13' && runner.os == 'Windows' }}
- name: Update CMake
- uses: jwlawson/[email protected]
+ uses: jwlawson/[email protected]
- name: Prepare MSVC
uses: ilammy/[email protected]
@@ -956,7 +956,7 @@
architecture: x86
- name: Update CMake
- uses: jwlawson/[email protected]
+ uses: jwlawson/[email protected]
- name: Prepare MSVC
uses: ilammy/[email protected]
@@ -1007,7 +1007,7 @@
run: python3 -m pip install -r tests/requirements.txt
- name: Update CMake
- uses: jwlawson/[email protected]
+ uses: jwlawson/[email protected]
- name: Configure C++20
run: >
@@ -1189,7 +1189,7 @@
python-version: ${{ matrix.python }}
- name: Update CMake
- uses: jwlawson/[email protected]
+ uses: jwlawson/[email protected]
- name: Install ninja-build tool
uses: seanmiddleditch/gha-setup-ninja@v6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/.github/workflows/configure.yml
new/pybind11-3.0.4/.github/workflows/configure.yml
--- old/pybind11-3.0.3/.github/workflows/configure.yml 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/.github/workflows/configure.yml 2026-04-19
05:01:51.000000000 +0200
@@ -56,7 +56,7 @@
python-version: 3.11
- name: Install uv
- uses: astral-sh/setup-uv@v7
+ uses: astral-sh/[email protected]
- name: Prepare env
run: uv pip install --python=python --system -r tests/requirements.txt
@@ -64,7 +64,7 @@
# An action for adding a specific version of CMake:
# https://github.com/jwlawson/actions-setup-cmake
- name: Setup CMake ${{ matrix.cmake }}
- uses: jwlawson/[email protected]
+ uses: jwlawson/[email protected]
with:
cmake-version: ${{ matrix.cmake }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/.github/workflows/nightlies.yml
new/pybind11-3.0.4/.github/workflows/nightlies.yml
--- old/pybind11-3.0.3/.github/workflows/nightlies.yml 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/.github/workflows/nightlies.yml 2026-04-19
05:01:51.000000000 +0200
@@ -25,7 +25,7 @@
fetch-depth: 0
- name: Install uv
- uses: astral-sh/setup-uv@v7
+ uses: astral-sh/[email protected]
- name: Build SDist and wheels
run: |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/.github/workflows/pip.yml
new/pybind11-3.0.4/.github/workflows/pip.yml
--- old/pybind11-3.0.3/.github/workflows/pip.yml 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/.github/workflows/pip.yml 2026-04-19
05:01:51.000000000 +0200
@@ -31,7 +31,7 @@
python-version: 3.8
- name: Install uv
- uses: astral-sh/setup-uv@v7
+ uses: astral-sh/[email protected]
- name: Prepare env
run: uv pip install --system -r tests/requirements.txt
@@ -55,7 +55,7 @@
python-version: 3.8
- name: Install uv
- uses: astral-sh/setup-uv@v7
+ uses: astral-sh/[email protected]
- name: Prepare env
run: uv pip install --system -r tests/requirements.txt twine nox
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pybind11-3.0.3/.github/workflows/reusable-standard.yml
new/pybind11-3.0.4/.github/workflows/reusable-standard.yml
--- old/pybind11-3.0.3/.github/workflows/reusable-standard.yml 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/.github/workflows/reusable-standard.yml 2026-04-19
05:01:51.000000000 +0200
@@ -51,7 +51,7 @@
run: brew install boost
- name: Install uv
- uses: astral-sh/setup-uv@v7
+ uses: astral-sh/[email protected]
with:
enable-cache: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/.github/workflows/tests-cibw.yml
new/pybind11-3.0.4/.github/workflows/tests-cibw.yml
--- old/pybind11-3.0.3/.github/workflows/tests-cibw.yml 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/.github/workflows/tests-cibw.yml 2026-04-19
05:01:51.000000000 +0200
@@ -22,7 +22,7 @@
submodules: true
fetch-depth: 0
- - uses: pypa/[email protected]
+ - uses: pypa/[email protected]
env:
PYODIDE_BUILD_EXPORTS: whole_archive
with:
@@ -45,7 +45,7 @@
# We have to uninstall first because GH is now using a local tap to build
cmake<4, iOS needs cmake>=4
- run: brew uninstall cmake && brew install cmake
- - uses: pypa/[email protected]
+ - uses: pypa/[email protected]
env:
CIBW_PLATFORM: ios
CIBW_SKIP: cp314-* # https://github.com/pypa/cibuildwheel/issues/2494
@@ -70,7 +70,7 @@
if: contains(matrix.runs-on, 'macos')
run: echo "CIBW_TEST_COMMAND=" >> "$GITHUB_ENV"
- - uses: pypa/[email protected]
+ - uses: pypa/[email protected]
env:
CIBW_PLATFORM: android
with:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/.github/workflows/upstream.yml
new/pybind11-3.0.4/.github/workflows/upstream.yml
--- old/pybind11-3.0.3/.github/workflows/upstream.yml 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/.github/workflows/upstream.yml 2026-04-19
05:01:51.000000000 +0200
@@ -36,7 +36,7 @@
run: sudo apt-get install libboost-dev
- name: Update CMake
- uses: jwlawson/[email protected]
+ uses: jwlawson/[email protected]
- name: Run pip installs
run: |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/.pre-commit-config.yaml
new/pybind11-3.0.4/.pre-commit-config.yaml
--- old/pybind11-3.0.3/.pre-commit-config.yaml 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/.pre-commit-config.yaml 2026-04-19 05:01:51.000000000
+0200
@@ -25,14 +25,14 @@
# Clang format the codebase automatically
- repo: https://github.com/pre-commit/mirrors-clang-format
- rev: "v22.1.0"
+ rev: "v22.1.2"
hooks:
- id: clang-format
types_or: [c++, c, cuda]
# Ruff, the Python auto-correcting linter/formatter written in Rust
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.15.4
+ rev: v0.15.9
hooks:
- id: ruff-check
args: ["--fix", "--show-fixes"]
@@ -40,7 +40,7 @@
# Check static types with mypy
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: "v1.19.1"
+ rev: "v1.20.0"
hooks:
- id: mypy
args: []
@@ -112,7 +112,7 @@
# Use tools/codespell_ignore_lines_from_errors.py
# to rebuild .codespell-ignore-lines
- repo: https://github.com/codespell-project/codespell
- rev: "v2.4.1"
+ rev: "v2.4.2"
hooks:
- id: codespell
exclude: "(.supp|^pyproject.toml)$"
@@ -122,7 +122,7 @@
# Use mirror because pre-commit autoupdate confuses tags in the upstream repo.
# See https://github.com/crate-ci/typos/issues/390
- repo: https://github.com/adhtruong/mirrors-typos
- rev: "v1.44.0"
+ rev: "v1.45.0"
hooks:
- id: typos
args: []
@@ -151,7 +151,7 @@
# Check schemas on some of our YAML files
- repo: https://github.com/python-jsonschema/check-jsonschema
- rev: 0.37.0
+ rev: 0.37.1
hooks:
- id: check-readthedocs
- id: check-github-workflows
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/docs/changelog.md
new/pybind11-3.0.4/docs/changelog.md
--- old/pybind11-3.0.3/docs/changelog.md 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/docs/changelog.md 2026-04-19 05:01:51.000000000
+0200
@@ -13,6 +13,34 @@
entry" block in pull request descriptions.
+## Version 3.0.4 (April 18, 2026)
+
+Bug fixes:
+
+- Fixed test builds with installed Eigen 5 by improving `Eigen3` CMake package
detection.
+ [#6036](https://github.com/pybind/pybind11/pull/6036)
+
+- Fixed move semantics of `scoped_ostream_redirect` to preserve buffered
output and avoid crashes when moved redirects restore stream buffers.
+ [#6033](https://github.com/pybind/pybind11/pull/6033)
+
+- Fixed `py::dynamic_attr()` traversal on Python 3.13+ to correctly propagate
`PyObject_VisitManagedDict()` results.
+ [#6032](https://github.com/pybind/pybind11/pull/6032)
+
+- Fixed `std::shared_ptr<T>` fallback casting to avoid unnecessary
copy-constructor instantiation in `reference_internal` paths.
+ [#6028](https://github.com/pybind/pybind11/pull/6028)
+
+CI:
+
+- Updated `setup-uv` to the maintained GitHub Action tag scheme.
+ [#6035](https://github.com/pybind/pybind11/pull/6035)
+
+- Updated pre-commit hooks.
+ [#6029](https://github.com/pybind/pybind11/pull/6029)
+
+- Updated GitHub Actions dependencies, including `actions-setup-cmake` and
`cibuildwheel`.
+ [#6027](https://github.com/pybind/pybind11/pull/6027)
+
+
## Version 3.0.3 (March 31, 2026)
Bug fixes:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/include/pybind11/cast.h
new/pybind11-3.0.4/include/pybind11/cast.h
--- old/pybind11-3.0.3/include/pybind11/cast.h 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/include/pybind11/cast.h 2026-04-19 05:01:51.000000000
+0200
@@ -1026,7 +1026,7 @@
}
if (parent) {
- return type_caster_base<type>::cast(
+ return type_caster_generic::cast_non_owning(
srcs, return_value_policy::reference_internal, parent);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/include/pybind11/detail/class.h
new/pybind11-3.0.4/include/pybind11/detail/class.h
--- old/pybind11-3.0.3/include/pybind11/detail/class.h 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/include/pybind11/detail/class.h 2026-04-19
05:01:51.000000000 +0200
@@ -578,7 +578,10 @@
/// dynamic_attr: Allow the garbage collector to traverse the internal
instance `__dict__`.
extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void
*arg) {
#if PY_VERSION_HEX >= 0x030D0000
- PyObject_VisitManagedDict(self, visit, arg);
+ int ret = PyObject_VisitManagedDict(self, visit, arg);
+ if (ret) {
+ return ret;
+ }
#else
PyObject *&dict = *_PyObject_GetDictPtr(self);
Py_VISIT(dict);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/include/pybind11/detail/common.h
new/pybind11-3.0.4/include/pybind11/detail/common.h
--- old/pybind11-3.0.3/include/pybind11/detail/common.h 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/include/pybind11/detail/common.h 2026-04-19
05:01:51.000000000 +0200
@@ -19,7 +19,7 @@
/* -- start version constants -- */
#define PYBIND11_VERSION_MAJOR 3
#define PYBIND11_VERSION_MINOR 0
-#define PYBIND11_VERSION_MICRO 3
+#define PYBIND11_VERSION_MICRO 4
// ALPHA = 0xA, BETA = 0xB, GAMMA = 0xC (release candidate), FINAL = 0xF
(stable release)
// - The release level is set to "alpha" for development versions.
// Use 0xA0 (LEVEL=0xA, SERIAL=0) for development versions.
@@ -27,7 +27,7 @@
#define PYBIND11_VERSION_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
#define PYBIND11_VERSION_RELEASE_SERIAL 0
// String version of (micro, release level, release serial), e.g.: 0a0, 0b1,
0rc1, 0
-#define PYBIND11_VERSION_PATCH 3
+#define PYBIND11_VERSION_PATCH 4
/* -- end version constants -- */
#if !defined(Py_PACK_FULL_VERSION)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pybind11-3.0.3/include/pybind11/detail/type_caster_base.h
new/pybind11-3.0.4/include/pybind11/detail/type_caster_base.h
--- old/pybind11-3.0.3/include/pybind11/detail/type_caster_base.h
2026-03-31 05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/include/pybind11/detail/type_caster_base.h
2026-04-19 05:01:51.000000000 +0200
@@ -1004,6 +1004,18 @@
return cast(srcs, policy, parent, copy_constructor, move_constructor,
existing_holder);
}
+ static handle cast_non_owning(const cast_sources &srcs,
+ return_value_policy policy,
+ handle parent,
+ const void *existing_holder = nullptr) {
+ // Reference-like policies alias an existing C++ object instead of
creating
+ // a new one, so copy/move constructor callbacks must remain null here.
+ assert(policy == return_value_policy::reference
+ || policy == return_value_policy::reference_internal
+ || policy == return_value_policy::automatic_reference);
+ return cast(srcs, policy, parent, nullptr, nullptr, existing_holder);
+ }
+
PYBIND11_NOINLINE static handle cast(const cast_sources &srcs,
return_value_policy policy,
handle parent,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/include/pybind11/iostream.h
new/pybind11-3.0.4/include/pybind11/iostream.h
--- old/pybind11-3.0.3/include/pybind11/iostream.h 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/include/pybind11/iostream.h 2026-04-19
05:01:51.000000000 +0200
@@ -131,7 +131,22 @@
setp(d_buffer.get(), d_buffer.get() + buf_size - 1);
}
- pythonbuf(pythonbuf &&) = default;
+ pythonbuf(pythonbuf &&other) noexcept
+ : buf_size(other.buf_size), d_buffer(std::move(other.d_buffer)),
+ pywrite(std::move(other.pywrite)), pyflush(std::move(other.pyflush))
{
+ const auto pending = (other.pbase() != nullptr && other.pptr() !=
nullptr)
+ ? static_cast<int>(other.pptr() -
other.pbase())
+ : 0;
+ if (d_buffer != nullptr) {
+ // Rebuild the put area from the transferred storage.
+ setp(d_buffer.get(), d_buffer.get() + buf_size - 1);
+ pbump(pending);
+ } else {
+ setp(nullptr, nullptr);
+ }
+ // Prevent the moved-from destructor from flushing through moved-out
handles.
+ other.setp(nullptr, nullptr);
+ }
/// Sync before destroy
~pythonbuf() override { _sync(); }
@@ -169,6 +184,7 @@
std::streambuf *old;
std::ostream &costream;
detail::pythonbuf buffer;
+ bool active = true;
public:
explicit scoped_ostream_redirect(std::ostream &costream = std::cout,
@@ -178,10 +194,22 @@
old = costream.rdbuf(&buffer);
}
- ~scoped_ostream_redirect() { costream.rdbuf(old); }
+ ~scoped_ostream_redirect() {
+ if (active) {
+ costream.rdbuf(old);
+ }
+ }
scoped_ostream_redirect(const scoped_ostream_redirect &) = delete;
- scoped_ostream_redirect(scoped_ostream_redirect &&other) = default;
+ // NOLINTNEXTLINE(performance-noexcept-move-constructor)
+ scoped_ostream_redirect(scoped_ostream_redirect &&other)
+ : old(other.old), costream(other.costream),
buffer(std::move(other.buffer)),
+ active(other.active) {
+ if (active) {
+ costream.rdbuf(&buffer); // Re-point stream to our buffer
+ other.active = false;
+ }
+ }
scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) =
delete;
scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete;
};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/pyproject.toml
new/pybind11-3.0.4/pyproject.toml
--- old/pybind11-3.0.3/pyproject.toml 2026-03-31 05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/pyproject.toml 2026-04-19 05:01:51.000000000 +0200
@@ -202,6 +202,10 @@
quater = "quater"
optin = "optin"
othr = "othr"
+# NumPy uses "writeable" in public API names and flags.
+writeable = "writeable"
+Writeable = "Writeable"
+WRITEABLE = "WRITEABLE"
#[tool.typos.type.cpp.extend-words]
setp = "setp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/tests/CMakeLists.txt
new/pybind11-3.0.4/tests/CMakeLists.txt
--- old/pybind11-3.0.3/tests/CMakeLists.txt 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/tests/CMakeLists.txt 2026-04-19 05:01:51.000000000
+0200
@@ -167,6 +167,7 @@
test_operator_overloading
test_pickling
test_potentially_slicing_weak_ptr
+ test_pytorch_shared_ptr_cast_regression
test_python_multiple_inheritance
test_pytypes
test_scoped_critical_section
@@ -299,10 +300,17 @@
else()
find_package(Eigen3 3.2.7 QUIET CONFIG)
+ if(NOT Eigen3_FOUND)
+ find_package(Eigen3 5 QUIET CONFIG)
+ endif()
+ set(EIGEN3_FOUND ${Eigen3_FOUND})
+ set(EIGEN3_VERSION ${Eigen3_VERSION})
if(NOT EIGEN3_FOUND)
# Couldn't load via target, so fall back to allowing module mode
finding, which will pick up
# tools/FindEigen3.cmake
+ # This MODULE-mode fallback is for older Eigen 3 setups; Eigen 5 is
expected to be found
+ # via the CONFIG-mode probes above.
find_package(Eigen3 3.2.7 QUIET)
endif()
endif()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/tests/test_class.cpp
new/pybind11-3.0.4/tests/test_class.cpp
--- old/pybind11-3.0.3/tests/test_class.cpp 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/tests/test_class.cpp 2026-04-19 05:01:51.000000000
+0200
@@ -104,6 +104,10 @@
~NoConstructorNew() { print_destroyed(this); }
};
+ struct DynamicAttr {
+ DynamicAttr() = default;
+ };
+
py::class_<NoConstructor>(m, "NoConstructor")
.def_static("new_instance", &NoConstructor::new_instance, "Return an
instance");
@@ -112,6 +116,8 @@
.def_static("__new__",
[](const py::object &) { return
NoConstructorNew::new_instance(); });
+ py::class_<DynamicAttr>(m, "DynamicAttr",
py::dynamic_attr()).def(py::init<>());
+
// test_pass_unique_ptr
struct ToBeHeldByUniquePtr {};
py::class_<ToBeHeldByUniquePtr, std::unique_ptr<ToBeHeldByUniquePtr>>(m,
"ToBeHeldByUniquePtr")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/tests/test_class.py
new/pybind11-3.0.4/tests/test_class.py
--- old/pybind11-3.0.3/tests/test_class.py 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/tests/test_class.py 2026-04-19 05:01:51.000000000
+0200
@@ -1,5 +1,6 @@
from __future__ import annotations
+import gc
import sys
from unittest import mock
@@ -18,6 +19,13 @@
return sys.getrefcount(ob)
+MANAGED_DICT_GET_REFERRERS_SUPPORTED = (
+ env.CPYTHON
+ and sys.version_info >= (3, 13, 13)
+ and (sys.version_info < (3, 14) or sys.version_info >= (3, 14, 4))
+)
+
+
def test_obj_class_name():
expected_name = "UserType" if env.PYPY else "pybind11_tests.UserType"
assert m.obj_class_name(UserType(1)) == expected_name
@@ -45,6 +53,16 @@
assert cstats.alive() == 0
[email protected](
+ not MANAGED_DICT_GET_REFERRERS_SUPPORTED,
+ reason="Requires CPython 3.13.13+ or 3.14.4+ managed dict traversal
support",
+)
+def test_get_referrers():
+ instance = m.DynamicAttr()
+ instance.a = "test"
+ assert instance in gc.get_referrers(instance.__dict__)
+
+
def test_instance_new():
instance = m.NoConstructorNew() # .__new__(m.NoConstructor.__class__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/tests/test_class_sh_property.py
new/pybind11-3.0.4/tests/test_class_sh_property.py
--- old/pybind11-3.0.3/tests/test_class_sh_property.py 2026-03-31
05:38:29.000000000 +0200
+++ new/pybind11-3.0.4/tests/test_class_sh_property.py 2026-04-19
05:01:51.000000000 +0200
@@ -204,3 +204,15 @@
legacy = obj.legacy
legacy.value = 13
assert obj.legacy.value == 13
+
+
+def
test_non_smart_holder_member_type_with_smart_holder_owner_aliases_member_multiple_reads():
+ obj = m.ShWithSimpleStructMember()
+
+ a = obj.legacy
+ b = obj.legacy
+
+ a.value = 13
+
+ assert b.value == 13
+ assert obj.legacy.value == 13
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/tests/test_iostream.cpp
new/pybind11-3.0.4/tests/test_iostream.cpp
--- old/pybind11-3.0.3/tests/test_iostream.cpp 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/tests/test_iostream.cpp 2026-04-19 05:01:51.000000000
+0200
@@ -123,4 +123,40 @@
.def("stop", &TestThread::stop)
.def("join", &TestThread::join)
.def("sleep", &TestThread::sleep);
+
+ m.def("move_redirect_output", [](const std::string &msg_before, const
std::string &msg_after) {
+ py::scoped_ostream_redirect redir1(std::cout,
py::module_::import("sys").attr("stdout"));
+ std::cout << msg_before << std::flush;
+ py::scoped_ostream_redirect redir2(std::move(redir1));
+ std::cout << msg_after << std::flush;
+ });
+
+ m.def("move_redirect_output_unflushed",
+ [](const std::string &msg_before, const std::string &msg_after) {
+ py::scoped_ostream_redirect redir1(std::cout,
+
py::module_::import("sys").attr("stdout"));
+ std::cout << msg_before;
+ py::scoped_ostream_redirect redir2(std::move(redir1));
+ std::cout << msg_after << std::flush;
+ });
+
+ // Redirect a stream whose original rdbuf is nullptr, then move the
redirect.
+ // Verifies that nullptr is correctly restored (not confused with a
moved-from sentinel).
+ m.def("move_redirect_null_rdbuf", [](const std::string &msg) {
+ std::ostream os(nullptr);
+ py::scoped_ostream_redirect redir1(os,
py::module_::import("sys").attr("stdout"));
+ os << msg << std::flush;
+ py::scoped_ostream_redirect redir2(std::move(redir1));
+ os << msg << std::flush;
+ // After redir2 goes out of scope, os.rdbuf() should be restored to
nullptr.
+ });
+
+ m.def("get_null_rdbuf_restored", [](const std::string &msg) -> bool {
+ std::ostream os(nullptr);
+ {
+ py::scoped_ostream_redirect redir(os,
py::module_::import("sys").attr("stdout"));
+ os << msg << std::flush;
+ }
+ return os.rdbuf() == nullptr;
+ });
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pybind11-3.0.3/tests/test_iostream.py
new/pybind11-3.0.4/tests/test_iostream.py
--- old/pybind11-3.0.3/tests/test_iostream.py 2026-03-31 05:38:29.000000000
+0200
+++ new/pybind11-3.0.4/tests/test_iostream.py 2026-04-19 05:01:51.000000000
+0200
@@ -284,6 +284,31 @@
assert stream2.getvalue() == msg2
+def test_move_redirect(capsys):
+ m.move_redirect_output("before_move", "after_move")
+ stdout, stderr = capsys.readouterr()
+ assert stdout == "before_moveafter_move"
+ assert not stderr
+
+
+def test_move_redirect_unflushed(capsys):
+ m.move_redirect_output_unflushed("before_move", "after_move")
+ stdout, stderr = capsys.readouterr()
+ assert stdout == "before_moveafter_move"
+ assert not stderr
+
+
+def test_move_redirect_null_rdbuf(capsys):
+ m.move_redirect_null_rdbuf("hello")
+ stdout, stderr = capsys.readouterr()
+ assert stdout == "hellohello"
+ assert not stderr
+
+
+def test_null_rdbuf_restored():
+ assert m.get_null_rdbuf_restored("test")
+
+
@pytest.mark.skipif(sys.platform.startswith("emscripten"), reason="Requires
threads")
def test_threading():
with m.ostream_redirect(stdout=True, stderr=False):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pybind11-3.0.3/tests/test_pytorch_shared_ptr_cast_regression.cpp
new/pybind11-3.0.4/tests/test_pytorch_shared_ptr_cast_regression.cpp
--- old/pybind11-3.0.3/tests/test_pytorch_shared_ptr_cast_regression.cpp
1970-01-01 01:00:00.000000000 +0100
+++ new/pybind11-3.0.4/tests/test_pytorch_shared_ptr_cast_regression.cpp
2026-04-19 05:01:51.000000000 +0200
@@ -0,0 +1,62 @@
+#include "pybind11_tests.h"
+
+#include <memory>
+#include <string>
+
+#if defined(__clang__)
+# if __has_warning("-Wdeprecated-copy-with-user-provided-dtor")
+# pragma clang diagnostic error
"-Wdeprecated-copy-with-user-provided-dtor"
+# endif
+# if __has_warning("-Wdeprecated-copy-with-dtor")
+# pragma clang diagnostic error "-Wdeprecated-copy-with-dtor"
+# endif
+#endif
+
+namespace test_pytorch_regressions {
+
+// Directly extracted from PyTorch patterns that regressed in CI.
+struct TracingState : std::enable_shared_from_this<TracingState> {
+ TracingState() = default;
+ ~TracingState() = default;
+ int value = 0;
+};
+
+const std::shared_ptr<TracingState> &get_tracing_state() {
+ static std::shared_ptr<TracingState> state =
std::make_shared<TracingState>();
+ return state;
+}
+
+struct InterfaceType {
+ ~InterfaceType() = default;
+ int value = 0;
+};
+using InterfaceTypePtr = std::shared_ptr<InterfaceType>;
+
+struct CompilationUnit {
+ InterfaceTypePtr iface = std::make_shared<InterfaceType>();
+
+ InterfaceTypePtr get_interface(const std::string &) const { return iface; }
+};
+
+} // namespace test_pytorch_regressions
+
+TEST_SUBMODULE(pybind11_pytorch_regressions, m) {
+ using namespace test_pytorch_regressions;
+
+ py::class_<TracingState, std::shared_ptr<TracingState>>(m, "TracingState")
+ .def(py::init<>())
+ .def_readwrite("value", &TracingState::value);
+
+ m.def("_get_tracing_state", []() { return get_tracing_state(); });
+
+ py::class_<InterfaceType, InterfaceTypePtr>(m, "InterfaceType")
+ .def(py::init<>())
+ .def_readwrite("value", &InterfaceType::value);
+
+ py::class_<CompilationUnit, std::shared_ptr<CompilationUnit>>(m,
"CompilationUnit")
+ .def(py::init<>())
+ .def("get_interface",
+ [](const std::shared_ptr<CompilationUnit> &self, const
std::string &name) {
+ return self->get_interface(name);
+ });
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pybind11-3.0.3/tests/test_pytorch_shared_ptr_cast_regression.py
new/pybind11-3.0.4/tests/test_pytorch_shared_ptr_cast_regression.py
--- old/pybind11-3.0.3/tests/test_pytorch_shared_ptr_cast_regression.py
1970-01-01 01:00:00.000000000 +0100
+++ new/pybind11-3.0.4/tests/test_pytorch_shared_ptr_cast_regression.py
2026-04-19 05:01:51.000000000 +0200
@@ -0,0 +1,25 @@
+from __future__ import annotations
+
+from pybind11_tests import pybind11_pytorch_regressions as m
+
+
+def test_pytorch_like_get_tracing_state_aliases_singleton_shared_ptr():
+ a = m._get_tracing_state()
+ b = m._get_tracing_state()
+
+ a.value = 17
+
+ assert b.value == 17
+ assert m._get_tracing_state().value == 17
+
+
+def
test_pytorch_like_compilation_unit_get_interface_aliases_member_shared_ptr():
+ cu = m.CompilationUnit()
+
+ a = cu.get_interface("iface")
+ b = cu.get_interface("iface")
+
+ a.value = 23
+
+ assert b.value == 23
+ assert cu.get_interface("iface").value == 23