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

Reply via email to