diff --git a/CHANGELOG.md b/CHANGELOG.md index 920bd4882..e6f2f3023 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Add support for free-threaded stable abi (abi3t) from Python 3.15t+ ([#556](https://github.com/PyO3/rust-numpy/pull/556)) - fixed free-threaded builds for 32 bit platforms from Python 3.15+ ([#556](https://github.com/PyO3/rust-numpy/pull/556)) - Drop support for Python 3.8 ([#567](https://github.com/PyO3/rust-numpy/pull/567)) + - fix accidental removal of singleton dimensions when extracting `PyArrayLikeDyn<'_, T, AllowTypeChange>` ([#496](https://github.com/PyO3/rust-numpy/pull/496)) - v0.29.0 - Fix PyArray_DTypeMeta definition when Py_LIMITED_API is disabled ([#532](https://github.com/PyO3/rust-numpy/pull/532)) diff --git a/src/array_like.rs b/src/array_like.rs index 40a60802a..47032f087 100644 --- a/src/array_like.rs +++ b/src/array_like.rs @@ -87,7 +87,7 @@ impl Coerce for AllowTypeChange { /// let np = get_array_module(py).unwrap(); /// let sum_up = wrap_pyfunction!(sum_up)(py).unwrap(); /// -/// py_run!(py, np sum_up, r"assert sum_up((1., 2., 3.)) == 6"); +/// py_run!(py, np sum_up, r"assert sum_up(np.array([1., 2., 3.])) == 6"); /// }); /// ``` /// @@ -107,6 +107,7 @@ impl Coerce for AllowTypeChange { /// let np = get_array_module(py).unwrap(); /// let sum_up = wrap_pyfunction!(sum_up)(py).unwrap(); /// +/// py_run!(py, np sum_up, r"assert sum_up(np.array([1.5, 2.5])) == 3"); /// py_run!(py, np sum_up, r"assert sum_up((1.5, 2.5)) == 3"); /// }); /// ``` @@ -150,7 +151,7 @@ where // If the input is already an ndarray and `TypeMustMatch` is used then no type conversion // should be performed. if (C::ALLOW_TYPE_CHANGE || ob.cast::().is_err()) - && matches!(D::NDIM, None | Some(1)) + && matches!(D::NDIM, Some(1)) { if let Ok(vec) = ob.extract::>() { let array = Array1::from(vec) @@ -162,7 +163,7 @@ where } } - let (dtype, flags) = if C::ALLOW_TYPE_CHANGE { + let (dtype, flags) = if C::ALLOW_TYPE_CHANGE || ob.cast::().is_err() { (Some(T::get_dtype(py)), NPY_ARRAY_FORCECAST) } else { (None, 0) diff --git a/tests/array_like.rs b/tests/array_like.rs index d08e98abf..fdb180290 100644 --- a/tests/array_like.rs +++ b/tests/array_like.rs @@ -1,5 +1,8 @@ use ndarray::array; -use numpy::{get_array_module, AllowTypeChange, PyArrayLike1, PyArrayLike2, PyArrayLikeDyn}; +use numpy::{ + get_array_module, AllowTypeChange, PyArrayLike1, PyArrayLike2, PyArrayLikeDyn, + PyUntypedArrayMethods as _, +}; use pyo3::{ ffi::c_str, types::{IntoPyDict, PyAnyMethods, PyDict}, @@ -115,6 +118,25 @@ fn convert_1d_list_on_extract() { }); } +#[test] +fn preserve_trailing_singleton_dims() { + Python::attach(|py| { + let locals = get_np_locals(py); + let py_array = py + .eval( + c_str!("np.array([[1], [2], [3]], dtype='int32')"), + Some(&locals), + None, + ) + .unwrap(); + let extracted_array = py_array + .extract::>() + .unwrap(); + + assert_eq!(extracted_array.shape(), &[3, 1]); + }) +} + #[test] fn unsafe_cast_shall_fail() { Python::attach(|py| {