diff --git a/include/pybind11/eigen.h b/include/pybind11/eigen.h index 98f3bd63906..ff88fddf420 100644 --- a/include/pybind11/eigen.h +++ b/include/pybind11/eigen.h @@ -97,13 +97,17 @@ template struct EigenConformable { template bool stride_compatible() const { // To have compatible strides, we need (on both dimensions) one of fully dynamic strides, - // matching strides, or a dimension size of 1 (in which case the stride value is irrelevant) + // matching strides, or a dimension size of 1 (in which case the stride value is + // irrelevant). Alternatively, if any dimension size is 0, the strides are not relevant + // (and numpy ≥ 1.23 sets the strides to 0 in that case, so we need to check explicitly). + if (rows == 0 || cols == 0) + return !negativestrides; return !negativestrides && (props::inner_stride == Eigen::Dynamic || props::inner_stride == stride.inner() || - (EigenRowMajor ? cols : rows) <= 1) && + (EigenRowMajor ? cols : rows) == 1) && (props::outer_stride == Eigen::Dynamic || props::outer_stride == stride.outer() || - (EigenRowMajor ? rows : cols) <= 1); + (EigenRowMajor ? rows : cols) == 1); } // NOLINTNEXTLINE(google-explicit-constructor) operator bool() const { return conformable; } diff --git a/tests/test_eigen.py b/tests/test_eigen.py index 6464dadcbb4..ea846c3fc10 100644 --- a/tests/test_eigen.py +++ b/tests/test_eigen.py @@ -840,6 +840,8 @@ def test_issue738_issue2038(): ) assert np.all(m.iss738_f1(np.zeros((0, 2))) == np.zeros((0, 2))) + assert np.all(m.iss738_f1(np.zeros((2, 0))) == np.zeros((2, 0))) + assert np.all(m.iss738_f2(np.zeros((0, 2))) == np.zeros((0, 2))) assert np.all(m.iss738_f2(np.zeros((2, 0))) == np.zeros((2, 0)))