diff --git a/Cargo.toml b/Cargo.toml index 99cfe4871..28b5b335f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,11 +22,11 @@ num-complex = ">= 0.2, < 0.5" num-integer = "0.1" num-traits = "0.2" ndarray = ">= 0.13, < 0.16" -pyo3 = { version = "0.21.0-beta", default-features = false, features = ["gil-refs", "macros"] } +pyo3 = { version = "0.21.0", default-features = false, features = ["gil-refs", "macros"] } rustc-hash = "1.1" [dev-dependencies] -pyo3 = { version = "0.21.0-beta", default-features = false, features = ["auto-initialize", "gil-refs"] } +pyo3 = { version = "0.21.0", default-features = false, features = ["auto-initialize", "gil-refs"] } nalgebra = { version = "0.32", default-features = false, features = ["std"] } [package.metadata.docs.rs] diff --git a/README.md b/README.md index c45899326..9ef05624e 100644 --- a/README.md +++ b/README.md @@ -44,11 +44,11 @@ numpy = "0.20" ```rust use numpy::ndarray::{ArrayD, ArrayViewD, ArrayViewMutD}; -use numpy::{IntoPyArray, PyArrayDyn, PyReadonlyArrayDyn}; -use pyo3::{pymodule, types::PyModule, PyResult, Python}; +use numpy::{IntoPyArray, PyArrayDyn, PyReadonlyArrayDyn, PyArrayMethods}; +use pyo3::{pymodule, types::PyModule, PyResult, Python, Bound}; #[pymodule] -fn rust_ext<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { +fn rust_ext<'py>(_py: Python<'py>, m: &Bound<'py, PyModule>) -> PyResult<()> { // example using immutable borrows producing a new array fn axpy(a: f64, x: ArrayViewD<'_, f64>, y: ArrayViewD<'_, f64>) -> ArrayD { a * &x + &y @@ -67,17 +67,17 @@ fn rust_ext<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { a: f64, x: PyReadonlyArrayDyn<'py, f64>, y: PyReadonlyArrayDyn<'py, f64>, - ) -> &'py PyArrayDyn { + ) -> Bound<'py, PyArrayDyn> { let x = x.as_array(); let y = y.as_array(); let z = axpy(a, x, y); - z.into_pyarray(py) + z.into_pyarray_bound(py) } // wrapper of `mult` #[pyfn(m)] #[pyo3(name = "mult")] - fn mult_py<'py>(a: f64, x: &'py PyArrayDyn) { + fn mult_py<'py>(a: f64, x: &Bound<'py, PyArrayDyn>) { let x = unsafe { x.as_array_mut() }; mult(a, x); } diff --git a/benches/array.rs b/benches/array.rs index 27ebe9e0b..7b7ed21d1 100644 --- a/benches/array.rs +++ b/benches/array.rs @@ -66,7 +66,7 @@ fn from_iter(bencher: &mut Bencher, size: usize) { iter_with_gil(bencher, |py| { let iter = black_box(Iter(0..size)); - PyArray1::from_iter(py, iter); + PyArray1::from_iter_bound(py, iter); }); } @@ -141,7 +141,7 @@ fn from_vec2(bencher: &mut Bencher, size: usize) { iter_with_gil(bencher, |py| { let vec2 = black_box(&vec2); - PyArray2::from_vec2(py, vec2).unwrap(); + PyArray2::from_vec2_bound(py, vec2).unwrap(); }); } @@ -166,7 +166,7 @@ fn from_vec3(bencher: &mut Bencher, size: usize) { iter_with_gil(bencher, |py| { let vec3 = black_box(&vec3); - PyArray3::from_vec3(py, vec3).unwrap(); + PyArray3::from_vec3_bound(py, vec3).unwrap(); }); } diff --git a/examples/linalg/Cargo.toml b/examples/linalg/Cargo.toml index d2903414e..3d855801f 100644 --- a/examples/linalg/Cargo.toml +++ b/examples/linalg/Cargo.toml @@ -9,7 +9,7 @@ name = "rust_linalg" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.21.0-beta", features = ["extension-module"] } +pyo3 = { version = "0.21.0", features = ["extension-module"] } numpy = { path = "../.." } ndarray-linalg = { version = "0.14.1", features = ["openblas-system"] } diff --git a/examples/linalg/src/lib.rs b/examples/linalg/src/lib.rs index 4a904718a..729c965e7 100755 --- a/examples/linalg/src/lib.rs +++ b/examples/linalg/src/lib.rs @@ -1,16 +1,19 @@ use ndarray_linalg::solve::Inverse; use numpy::{IntoPyArray, PyArray2, PyReadonlyArray2}; -use pyo3::{exceptions::PyRuntimeError, pymodule, types::PyModule, PyResult, Python}; +use pyo3::{exceptions::PyRuntimeError, pymodule, types::PyModule, Bound, PyResult, Python}; #[pymodule] -fn rust_linalg<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { +fn rust_linalg<'py>(m: &Bound<'py, PyModule>) -> PyResult<()> { #[pyfn(m)] - fn inv<'py>(py: Python<'py>, x: PyReadonlyArray2<'py, f64>) -> PyResult<&'py PyArray2> { + fn inv<'py>( + py: Python<'py>, + x: PyReadonlyArray2<'py, f64>, + ) -> PyResult>> { let x = x.as_array(); let y = x .inv() .map_err(|e| PyRuntimeError::new_err(e.to_string()))?; - Ok(y.into_pyarray(py)) + Ok(y.into_pyarray_bound(py)) } Ok(()) } diff --git a/examples/parallel/Cargo.toml b/examples/parallel/Cargo.toml index cbbba4da1..e05f2e6b3 100644 --- a/examples/parallel/Cargo.toml +++ b/examples/parallel/Cargo.toml @@ -9,7 +9,7 @@ name = "rust_parallel" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.21.0-beta", features = ["extension-module", "multiple-pymethods"] } +pyo3 = { version = "0.21.0", features = ["extension-module", "multiple-pymethods"] } numpy = { path = "../.." } ndarray = { version = "0.15", features = ["rayon", "blas"] } blas-src = { version = "0.8", features = ["openblas"] } diff --git a/examples/parallel/src/lib.rs b/examples/parallel/src/lib.rs index 2a12d406f..20a04d331 100755 --- a/examples/parallel/src/lib.rs +++ b/examples/parallel/src/lib.rs @@ -3,20 +3,20 @@ extern crate blas_src; use numpy::ndarray::Zip; use numpy::{IntoPyArray, PyArray1, PyReadonlyArray1, PyReadonlyArray2}; -use pyo3::{pymodule, types::PyModule, PyResult, Python}; +use pyo3::{pymodule, types::PyModule, Bound, PyResult, Python}; #[pymodule] -fn rust_parallel<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { +fn rust_parallel<'py>(m: &Bound<'py, PyModule>) -> PyResult<()> { #[pyfn(m)] fn rows_dot<'py>( py: Python<'py>, x: PyReadonlyArray2<'py, f64>, y: PyReadonlyArray1<'py, f64>, - ) -> &'py PyArray1 { + ) -> Bound<'py, PyArray1> { let x = x.as_array(); let y = y.as_array(); let z = Zip::from(x.rows()).par_map_collect(|row| row.dot(&y)); - z.into_pyarray(py) + z.into_pyarray_bound(py) } Ok(()) } diff --git a/examples/simple/Cargo.toml b/examples/simple/Cargo.toml index 147dd8f06..caba4c2ce 100644 --- a/examples/simple/Cargo.toml +++ b/examples/simple/Cargo.toml @@ -9,7 +9,7 @@ name = "rust_ext" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.21.0-beta", features = ["extension-module", "abi3-py37"] } +pyo3 = { version = "0.21.0", features = ["extension-module", "abi3-py37"] } numpy = { path = "../.." } [workspace] diff --git a/examples/simple/src/lib.rs b/examples/simple/src/lib.rs index e3c0e8e63..a1d22bc1f 100644 --- a/examples/simple/src/lib.rs +++ b/examples/simple/src/lib.rs @@ -10,11 +10,11 @@ use pyo3::{ exceptions::PyIndexError, pymodule, types::{PyDict, PyModule}, - FromPyObject, PyAny, PyObject, PyResult, Python, + Bound, FromPyObject, PyAny, PyObject, PyResult, Python, }; #[pymodule] -fn rust_ext<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { +fn rust_ext<'py>(m: &Bound<'py, PyModule>) -> PyResult<()> { // example using generic PyObject fn head(x: ArrayViewD<'_, PyObject>) -> PyResult { x.get(0) @@ -60,11 +60,11 @@ fn rust_ext<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { a: f64, x: PyReadonlyArrayDyn<'py, f64>, y: PyReadonlyArrayDyn<'py, f64>, - ) -> &'py PyArrayDyn { + ) -> Bound<'py, PyArrayDyn> { let x = x.as_array(); let y = y.as_array(); let z = axpy(a, x, y); - z.into_pyarray(py) + z.into_pyarray_bound(py) } // wrapper of `mult` @@ -81,8 +81,8 @@ fn rust_ext<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { fn conj_py<'py>( py: Python<'py>, x: PyReadonlyArrayDyn<'py, Complex64>, - ) -> &'py PyArrayDyn { - conj(x.as_array()).into_pyarray(py) + ) -> Bound<'py, PyArrayDyn> { + conj(x.as_array()).into_pyarray_bound(py) } // example of how to extract an array from a dictionary @@ -125,28 +125,28 @@ fn rust_ext<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { fn polymorphic_add<'py>( x: SupportedArray<'py>, y: SupportedArray<'py>, - ) -> PyResult<&'py PyAny> { + ) -> PyResult> { match (x, y) { (SupportedArray::F64(x), SupportedArray::F64(y)) => Ok(generic_add( x.readonly().as_array(), y.readonly().as_array(), ) - .into_pyarray(x.py()) - .into()), + .into_pyarray_bound(x.py()) + .into_any()), (SupportedArray::I64(x), SupportedArray::I64(y)) => Ok(generic_add( x.readonly().as_array(), y.readonly().as_array(), ) - .into_pyarray(x.py()) - .into()), + .into_pyarray_bound(x.py()) + .into_any()), (SupportedArray::F64(x), SupportedArray::I64(y)) | (SupportedArray::I64(y), SupportedArray::F64(x)) => { let y = y.cast::(false)?; Ok( generic_add(x.readonly().as_array(), y.readonly().as_array()) - .into_pyarray(x.py()) - .into(), + .into_pyarray_bound(x.py()) + .into_any(), ) } } diff --git a/src/array.rs b/src/array.rs index f6d01a0c4..34863b13f 100644 --- a/src/array.rs +++ b/src/array.rs @@ -803,6 +803,18 @@ impl PyArray { self.as_borrowed().to_vec() } + /// Deprecated form of [`PyArray::from_array_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by PyArray::from_array_bound in the future" + )] + pub fn from_array<'py, S>(py: Python<'py>, arr: &ArrayBase) -> &'py Self + where + S: Data, + { + Self::from_array_bound(py, arr).into_gil_ref() + } + /// Construct a NumPy array from a [`ndarray::ArrayBase`]. /// /// This method allocates memory in Python's heap via the NumPy API, @@ -811,21 +823,21 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// use ndarray::array; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let pyarray = PyArray::from_array(py, &array![[1, 2], [3, 4]]); + /// let pyarray = PyArray::from_array_bound(py, &array![[1, 2], [3, 4]]); /// /// assert_eq!(pyarray.readonly().as_array(), array![[1, 2], [3, 4]]); /// }); /// ``` - pub fn from_array<'py, S>(py: Python<'py>, arr: &ArrayBase) -> &'py Self + pub fn from_array_bound<'py, S>(py: Python<'py>, arr: &ArrayBase) -> Bound<'py, Self> where S: Data, { - ToPyArray::to_pyarray(arr, py) + ToPyArray::to_pyarray_bound(arr, py) } /// Get an immutable borrow of the NumPy array @@ -1087,23 +1099,45 @@ impl PyArray { } } + /// Deprecated form of [`PyArray::from_vec_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by `PyArray::from_vec_bound` in the future" + )] + #[inline(always)] + pub fn from_vec<'py>(py: Python<'py>, vec: Vec) -> &'py Self { + Self::from_vec_bound(py, vec).into_gil_ref() + } + /// Construct a one-dimensional array from a [`Vec`][Vec]. /// /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { /// let vec = vec![1, 2, 3, 4, 5]; - /// let pyarray = PyArray::from_vec(py, vec); + /// let pyarray = PyArray::from_vec_bound(py, vec); /// assert_eq!(pyarray.readonly().as_slice().unwrap(), &[1, 2, 3, 4, 5]); /// }); /// ``` #[inline(always)] - pub fn from_vec<'py>(py: Python<'py>, vec: Vec) -> &'py Self { - vec.into_pyarray(py) + pub fn from_vec_bound<'py>(py: Python<'py>, vec: Vec) -> Bound<'py, Self> { + vec.into_pyarray_bound(py) + } + + /// Deprecated form of [`PyArray::from_iter_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by PyArray::from_iter_bound in the future" + )] + pub fn from_iter<'py, I>(py: Python<'py>, iter: I) -> &'py Self + where + I: IntoIterator, + { + Self::from_iter_bound(py, iter).into_gil_ref() } /// Construct a one-dimensional array from an [`Iterator`]. @@ -1114,24 +1148,33 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let pyarray = PyArray::from_iter(py, "abcde".chars().map(u32::from)); + /// let pyarray = PyArray::from_iter_bound(py, "abcde".chars().map(u32::from)); /// assert_eq!(pyarray.readonly().as_slice().unwrap(), &[97, 98, 99, 100, 101]); /// }); /// ``` - pub fn from_iter<'py, I>(py: Python<'py>, iter: I) -> &'py Self + pub fn from_iter_bound(py: Python<'_>, iter: I) -> Bound<'_, Self> where I: IntoIterator, { let data = iter.into_iter().collect::>(); - data.into_pyarray(py) + data.into_pyarray_bound(py) } } impl PyArray { + /// Deprecated form of [`PyArray::from_vec2_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by `PyArray::from_vec2_bound` in the future" + )] + pub fn from_vec2<'py>(py: Python<'py>, v: &[Vec]) -> Result<&'py Self, FromVecError> { + Self::from_vec2_bound(py, v).map(Bound::into_gil_ref) + } + /// Construct a two-dimension array from a [`Vec>`][Vec]. /// /// This function checks all dimensions of the inner vectors and returns @@ -1140,20 +1183,23 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// use ndarray::array; /// /// Python::with_gil(|py| { /// let vec2 = vec![vec![11, 12], vec![21, 22]]; - /// let pyarray = PyArray::from_vec2(py, &vec2).unwrap(); + /// let pyarray = PyArray::from_vec2_bound(py, &vec2).unwrap(); /// assert_eq!(pyarray.readonly().as_array(), array![[11, 12], [21, 22]]); /// /// let ragged_vec2 = vec![vec![11, 12], vec![21]]; - /// assert!(PyArray::from_vec2(py, &ragged_vec2).is_err()); + /// assert!(PyArray::from_vec2_bound(py, &ragged_vec2).is_err()); /// }); /// ``` - pub fn from_vec2<'py>(py: Python<'py>, v: &[Vec]) -> Result<&'py Self, FromVecError> { + pub fn from_vec2_bound<'py>( + py: Python<'py>, + v: &[Vec], + ) -> Result, FromVecError> { let len2 = v.first().map_or(0, |v| v.len()); let dims = [v.len(), len2]; // SAFETY: The result of `Self::new` is always safe to drop. @@ -1167,12 +1213,21 @@ impl PyArray { } clone_elements(v, &mut data_ptr); } - Ok(array.into_gil_ref()) + Ok(array) } } } impl PyArray { + /// Deprecated form of [`PyArray::from_vec3_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by `PyArray::from_vec3_bound` in the future" + )] + pub fn from_vec3<'py>(py: Python<'py>, v: &[Vec>]) -> Result<&'py Self, FromVecError> { + Self::from_vec3_bound(py, v).map(Bound::into_gil_ref) + } + /// Construct a three-dimensional array from a [`Vec>>`][Vec]. /// /// This function checks all dimensions of the inner vectors and returns @@ -1181,7 +1236,7 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// use ndarray::array; /// @@ -1190,7 +1245,7 @@ impl PyArray { /// vec![vec![111, 112], vec![121, 122]], /// vec![vec![211, 212], vec![221, 222]], /// ]; - /// let pyarray = PyArray::from_vec3(py, &vec3).unwrap(); + /// let pyarray = PyArray::from_vec3_bound(py, &vec3).unwrap(); /// assert_eq!( /// pyarray.readonly().as_array(), /// array![[[111, 112], [121, 122]], [[211, 212], [221, 222]]] @@ -1200,10 +1255,13 @@ impl PyArray { /// vec![vec![111, 112], vec![121, 122]], /// vec![vec![211], vec![221, 222]], /// ]; - /// assert!(PyArray::from_vec3(py, &ragged_vec3).is_err()); + /// assert!(PyArray::from_vec3_bound(py, &ragged_vec3).is_err()); /// }); /// ``` - pub fn from_vec3<'py>(py: Python<'py>, v: &[Vec>]) -> Result<&'py Self, FromVecError> { + pub fn from_vec3_bound<'py>( + py: Python<'py>, + v: &[Vec>], + ) -> Result, FromVecError> { let len2 = v.first().map_or(0, |v| v.len()); let len3 = v.first().map_or(0, |v| v.first().map_or(0, |v| v.len())); let dims = [v.len(), len2, len3]; @@ -1224,7 +1282,7 @@ impl PyArray { clone_elements(v, &mut data_ptr); } } - Ok(array.into_gil_ref()) + Ok(array) } } } @@ -1288,13 +1346,14 @@ impl PyArray { /// # Example /// /// ``` + /// use numpy::prelude::*; /// use numpy::{npyffi::NPY_ORDER, PyArray}; /// use pyo3::Python; /// use ndarray::array; /// /// Python::with_gil(|py| { /// let array = - /// PyArray::from_iter(py, 0..9).reshape_with_order([3, 3], NPY_ORDER::NPY_FORTRANORDER).unwrap(); + /// PyArray::from_iter_bound(py, 0..9).reshape_with_order([3, 3], NPY_ORDER::NPY_FORTRANORDER).unwrap(); /// /// assert_eq!(array.readonly().as_array(), array![[0, 3, 6], [1, 4, 7], [2, 5, 8]]); /// assert!(array.is_fortran_contiguous()); @@ -1830,13 +1889,14 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// # Example /// /// ``` + /// use numpy::prelude::*; /// use numpy::{npyffi::NPY_ORDER, PyArray}; /// use pyo3::Python; /// use ndarray::array; /// /// Python::with_gil(|py| { /// let array = - /// PyArray::from_iter(py, 0..9).reshape_with_order([3, 3], NPY_ORDER::NPY_FORTRANORDER).unwrap(); + /// PyArray::from_iter_bound(py, 0..9).reshape_with_order([3, 3], NPY_ORDER::NPY_FORTRANORDER).unwrap(); /// /// assert_eq!(array.readonly().as_array(), array![[0, 3, 6], [1, 4, 7], [2, 5, 8]]); /// assert!(array.is_fortran_contiguous()); @@ -2293,7 +2353,7 @@ mod tests { #[test] fn test_dyn_to_owned_array() { Python::with_gil(|py| { - let array = PyArray::from_vec2(py, &[vec![1, 2], vec![3, 4]]) + let array = PyArray::from_vec2_bound(py, &[vec![1, 2], vec![3, 4]]) .unwrap() .to_dyn() .to_owned_array(); diff --git a/src/array_like.rs b/src/array_like.rs index 8a1e3bc46..17ce47eb8 100644 --- a/src/array_like.rs +++ b/src/array_like.rs @@ -154,7 +154,7 @@ where let array = Array1::from(vec) .into_dimensionality() .expect("D being compatible to Ix1") - .into_pyarray(py) + .into_pyarray_bound(py) .readonly(); return Ok(Self(array, PhantomData)); } diff --git a/src/borrow/shared.rs b/src/borrow/shared.rs index a92e6d35d..e77c6b71b 100644 --- a/src/borrow/shared.rs +++ b/src/borrow/shared.rs @@ -477,18 +477,20 @@ mod tests { #[test] fn with_base_object() { Python::with_gil(|py| { - let array = Array::::zeros((1, 2, 3)).into_pyarray(py); + let array = Array::::zeros((1, 2, 3)).into_pyarray_bound(py); let base = unsafe { (*array.as_array_ptr()).base }; assert!(!base.is_null()); let base_address = base_address(py, array.as_array_ptr()); - assert_ne!(base_address, array as *const _ as *mut c_void); - assert_eq!(base_address, base as *mut c_void); + assert_ne!(base_address, array.as_ptr().cast()); + assert_eq!(base_address, base.cast::()); let data_range = data_range(array.as_array_ptr()); - assert_eq!(data_range.0, array.data() as *mut c_char); - assert_eq!(data_range.1, unsafe { array.data().add(6) } as *mut c_char); + assert_eq!(data_range.0, array.data().cast::()); + assert_eq!(data_range.1, unsafe { + array.data().add(6).cast::() + }); }); } @@ -524,33 +526,35 @@ mod tests { #[test] fn view_with_base_object() { Python::with_gil(|py| { - let array = Array::::zeros((1, 2, 3)).into_pyarray(py); + let array = Array::::zeros((1, 2, 3)).into_pyarray_bound(py); - let locals = [("array", array)].into_py_dict(py); + let locals = [("array", &array)].into_py_dict_bound(py); let view = py - .eval("array[:,:,0]", None, Some(locals)) + .eval_bound("array[:,:,0]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_ne!( - view as *const _ as *mut c_void, - array as *const _ as *mut c_void + view.as_ptr().cast::(), + array.as_ptr().cast::(), ); let base = unsafe { (*view.as_array_ptr()).base }; - assert_eq!(base as *mut c_void, array as *const _ as *mut c_void); + assert_eq!(base.cast::(), array.as_ptr().cast::()); let base = unsafe { (*array.as_array_ptr()).base }; assert!(!base.is_null()); let base_address = base_address(py, view.as_array_ptr()); - assert_ne!(base_address, view as *const _ as *mut c_void); - assert_ne!(base_address, array as *const _ as *mut c_void); - assert_eq!(base_address, base as *mut c_void); + assert_ne!(base_address, view.as_ptr().cast::()); + assert_ne!(base_address, array.as_ptr().cast::()); + assert_eq!(base_address, base.cast::()); let data_range = data_range(view.as_array_ptr()); - assert_eq!(data_range.0, array.data() as *mut c_char); - assert_eq!(data_range.1, unsafe { array.data().add(4) } as *mut c_char); + assert_eq!(data_range.0, array.data().cast::()); + assert_eq!(data_range.1, unsafe { + array.data().add(4).cast::() + }); }); } @@ -605,52 +609,54 @@ mod tests { #[test] fn view_of_view_with_base_object() { Python::with_gil(|py| { - let array = Array::::zeros((1, 2, 3)).into_pyarray(py); + let array = Array::::zeros((1, 2, 3)).into_pyarray_bound(py); - let locals = [("array", array)].into_py_dict(py); + let locals = [("array", &array)].into_py_dict_bound(py); let view1 = py - .eval("array[:,:,0]", None, Some(locals)) + .eval_bound("array[:,:,0]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_ne!( - view1 as *const _ as *mut c_void, - array as *const _ as *mut c_void + view1.as_ptr().cast::(), + array.as_ptr().cast::(), ); - let locals = [("view1", view1)].into_py_dict(py); + let locals = [("view1", &view1)].into_py_dict_bound(py); let view2 = py - .eval("view1[:,0]", None, Some(locals)) + .eval_bound("view1[:,0]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_ne!( - view2 as *const _ as *mut c_void, - array as *const _ as *mut c_void + view2.as_ptr().cast::(), + array.as_ptr().cast::(), ); assert_ne!( - view2 as *const _ as *mut c_void, - view1 as *const _ as *mut c_void + view2.as_ptr().cast::(), + view1.as_ptr().cast::(), ); let base = unsafe { (*view2.as_array_ptr()).base }; - assert_eq!(base as *mut c_void, array as *const _ as *mut c_void); + assert_eq!(base.cast::(), array.as_ptr().cast::()); let base = unsafe { (*view1.as_array_ptr()).base }; - assert_eq!(base as *mut c_void, array as *const _ as *mut c_void); + assert_eq!(base.cast::(), array.as_ptr().cast::()); let base = unsafe { (*array.as_array_ptr()).base }; assert!(!base.is_null()); let base_address = base_address(py, view2.as_array_ptr()); - assert_ne!(base_address, view2 as *const _ as *mut c_void); - assert_ne!(base_address, view1 as *const _ as *mut c_void); - assert_ne!(base_address, array as *const _ as *mut c_void); - assert_eq!(base_address, base as *mut c_void); + assert_ne!(base_address, view2.as_ptr().cast::()); + assert_ne!(base_address, view1.as_ptr().cast::()); + assert_ne!(base_address, array.as_ptr().cast::()); + assert_eq!(base_address, base.cast::()); let data_range = data_range(view2.as_array_ptr()); - assert_eq!(data_range.0, array.data() as *mut c_char); - assert_eq!(data_range.1, unsafe { array.data().add(1) } as *mut c_char); + assert_eq!(data_range.0, array.data().cast::()); + assert_eq!(data_range.1, unsafe { + array.data().add(1).cast::() + }); }); } diff --git a/src/convert.rs b/src/convert.rs index 6528e0b15..4e50c5126 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -3,7 +3,7 @@ use std::{mem, os::raw::c_int, ptr}; use ndarray::{ArrayBase, Data, Dim, Dimension, IntoDimension, Ix1, OwnedRepr}; -use pyo3::Python; +use pyo3::{Bound, Python}; use crate::array::{PyArray, PyArrayMethods}; use crate::dtype::Element; @@ -20,11 +20,11 @@ use crate::slice_container::PySliceContainer; /// # Example /// /// ``` -/// use numpy::{PyArray, IntoPyArray}; +/// use numpy::{PyArray, IntoPyArray, PyArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { -/// let py_array = vec![1, 2, 3].into_pyarray(py); +/// let py_array = vec![1, 2, 3].into_pyarray_bound(py); /// /// assert_eq!(py_array.readonly().as_slice().unwrap(), &[1, 2, 3]); /// @@ -34,21 +34,34 @@ use crate::slice_container::PySliceContainer; /// } /// }); /// ``` -pub trait IntoPyArray { +pub trait IntoPyArray: Sized { /// The element type of resulting array. type Item: Element; /// The dimension type of the resulting array. type Dim: Dimension; + /// Deprecated form of [`IntoPyArray::into_pyarray_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by `IntoPyArray::into_pyarray_bound` in the future" + )] + fn into_pyarray<'py>(self, py: Python<'py>) -> &'py PyArray { + Self::into_pyarray_bound(self, py).into_gil_ref() + } + /// Consumes `self` and moves its data into a NumPy array. - fn into_pyarray<'py>(self, py: Python<'py>) -> &'py PyArray; + fn into_pyarray_bound<'py>(self, py: Python<'py>) + -> Bound<'py, PyArray>; } impl IntoPyArray for Box<[T]> { type Item = T; type Dim = Ix1; - fn into_pyarray<'py>(self, py: Python<'py>) -> &'py PyArray { + fn into_pyarray_bound<'py>( + self, + py: Python<'py>, + ) -> Bound<'py, PyArray> { let container = PySliceContainer::from(self); let dims = Dim([container.len]); let strides = [mem::size_of::() as npy_intp]; @@ -56,9 +69,7 @@ impl IntoPyArray for Box<[T]> { // to avoid unsound aliasing of Box<[T]> which is currently noalias, // c.f. https://github.com/rust-lang/unsafe-code-guidelines/issues/326 let data_ptr = container.ptr as *mut T; - unsafe { - PyArray::from_raw_parts(py, dims, strides.as_ptr(), data_ptr, container).into_gil_ref() - } + unsafe { PyArray::from_raw_parts(py, dims, strides.as_ptr(), data_ptr, container) } } } @@ -66,7 +77,10 @@ impl IntoPyArray for Vec { type Item = T; type Dim = Ix1; - fn into_pyarray<'py>(mut self, py: Python<'py>) -> &'py PyArray { + fn into_pyarray_bound<'py>( + mut self, + py: Python<'py>, + ) -> Bound<'py, PyArray> { let dims = Dim([self.len()]); let strides = [mem::size_of::() as npy_intp]; let data_ptr = self.as_mut_ptr(); @@ -78,7 +92,6 @@ impl IntoPyArray for Vec { data_ptr, PySliceContainer::from(self), ) - .into_gil_ref() } } } @@ -91,8 +104,11 @@ where type Item = A; type Dim = D; - fn into_pyarray<'py>(self, py: Python<'py>) -> &'py PyArray { - PyArray::from_owned_array_bound(py, self).into_gil_ref() + fn into_pyarray_bound<'py>( + self, + py: Python<'py>, + ) -> Bound<'py, PyArray> { + PyArray::from_owned_array_bound(py, self) } } @@ -103,11 +119,11 @@ where /// # Examples /// /// ``` -/// use numpy::{PyArray, ToPyArray}; +/// use numpy::{PyArray, ToPyArray, PyArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { -/// let py_array = vec![1, 2, 3].to_pyarray(py); +/// let py_array = vec![1, 2, 3].to_pyarray_bound(py); /// /// assert_eq!(py_array.readonly().as_slice().unwrap(), &[1, 2, 3]); /// }); @@ -116,13 +132,14 @@ where /// Due to copying the elments, this method converts non-contiguous arrays to C-order contiguous arrays. /// /// ``` +/// use numpy::prelude::*; /// use numpy::{PyArray, ToPyArray}; /// use ndarray::{arr3, s}; /// use pyo3::Python; /// /// Python::with_gil(|py| { /// let array = arr3(&[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]); -/// let py_array = array.slice(s![.., 0..1, ..]).to_pyarray(py); +/// let py_array = array.slice(s![.., 0..1, ..]).to_pyarray_bound(py); /// /// assert_eq!(py_array.readonly().as_array(), arr3(&[[[1, 2, 3]], [[7, 8, 9]]])); /// assert!(py_array.is_c_contiguous()); @@ -134,16 +151,25 @@ pub trait ToPyArray { /// The dimension type of the resulting array. type Dim: Dimension; + /// Deprecated form of [`ToPyArray::to_pyarray_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by `ToPyArray::to_pyarray_bound` in the future" + )] + fn to_pyarray<'py>(&self, py: Python<'py>) -> &'py PyArray { + Self::to_pyarray_bound(self, py).into_gil_ref() + } + /// Copies the content pointed to by `&self` into a newly allocated NumPy array. - fn to_pyarray<'py>(&self, py: Python<'py>) -> &'py PyArray; + fn to_pyarray_bound<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray>; } impl ToPyArray for [T] { type Item = T; type Dim = Ix1; - fn to_pyarray<'py>(&self, py: Python<'py>) -> &'py PyArray { - PyArray::from_slice_bound(py, self).into_gil_ref() + fn to_pyarray_bound<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray> { + PyArray::from_slice_bound(py, self) } } @@ -156,7 +182,7 @@ where type Item = A; type Dim = D; - fn to_pyarray<'py>(&self, py: Python<'py>) -> &'py PyArray { + fn to_pyarray_bound<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray> { let len = self.len(); match self.order() { Some(flag) if A::IS_COPY => { @@ -165,7 +191,7 @@ where unsafe { let array = PyArray::new_uninit(py, self.raw_dim(), strides.as_ptr(), flag); ptr::copy_nonoverlapping(self.as_ptr(), array.data(), len); - array.into_gil_ref() + array } } _ => { @@ -178,7 +204,7 @@ where data_ptr.write(item.clone()); data_ptr = data_ptr.add(1); } - array.into_gil_ref() + array } } } @@ -200,7 +226,7 @@ where /// matching the [memory layout][memory-layout] used by [`nalgebra`]. /// /// [memory-layout]: https://nalgebra.org/docs/faq/#what-is-the-memory-layout-of-matrices - fn to_pyarray<'py>(&self, py: Python<'py>) -> &'py PyArray { + fn to_pyarray_bound<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray> { unsafe { let array = PyArray::::new_bound(py, (self.nrows(), self.ncols()), true); let mut data_ptr = array.data(); @@ -212,7 +238,7 @@ where data_ptr = data_ptr.add(1); } } - array.into_gil_ref() + array } } } diff --git a/src/lib.rs b/src/lib.rs index 095cb01e0..79dbbf653 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,10 +23,10 @@ as well as the [`PyReadonlyArray::try_as_matrix`] and [`PyReadwriteArray::try_as //! ``` //! use numpy::pyo3::Python; //! use numpy::ndarray::array; -//! use numpy::{ToPyArray, PyArray}; +//! use numpy::{ToPyArray, PyArray, PyArrayMethods}; //! //! Python::with_gil(|py| { -//! let py_array = array![[1i64, 2], [3, 4]].to_pyarray(py); +//! let py_array = array![[1i64, 2], [3, 4]].to_pyarray_bound(py); //! //! assert_eq!( //! py_array.readonly().as_array(), @@ -130,6 +130,7 @@ pub use ndarray::{array, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn}; /// ``` pub mod prelude { pub use crate::array::{PyArray0Methods, PyArrayMethods}; + pub use crate::convert::{IntoPyArray, ToPyArray}; pub use crate::dtype::PyArrayDescrMethods; pub use crate::untyped_array::PyUntypedArrayMethods; } @@ -171,12 +172,15 @@ fn cold() {} #[macro_export] macro_rules! pyarray { ($py: ident, $([$([$($x:expr),* $(,)*]),+ $(,)*]),+ $(,)*) => {{ + #[allow(deprecated)] $crate::IntoPyArray::into_pyarray($crate::array![$([$([$($x,)*],)*],)*], $py) }}; ($py: ident, $([$($x:expr),* $(,)*]),+ $(,)*) => {{ + #[allow(deprecated)] $crate::IntoPyArray::into_pyarray($crate::array![$([$($x,)*],)*], $py) }}; ($py: ident, $($x:expr),* $(,)*) => {{ + #[allow(deprecated)] $crate::IntoPyArray::into_pyarray($crate::array![$($x,)*], $py) }}; } diff --git a/src/strings.rs b/src/strings.rs index ba9f14236..74606289e 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -47,10 +47,10 @@ use crate::npyffi::NPY_TYPES; /// /// ```rust /// # use pyo3::Python; -/// use numpy::{PyArray1, PyFixedString}; +/// use numpy::{PyArray1, PyUntypedArrayMethods, PyFixedString}; /// /// # Python::with_gil(|py| { -/// let array = PyArray1::>::from_vec(py, vec![[b'f', b'o', b'o'].into()]); +/// let array = PyArray1::>::from_vec_bound(py, vec![[b'f', b'o', b'o'].into()]); /// /// assert!(array.dtype().to_string().contains("S3")); /// # }); @@ -110,10 +110,10 @@ unsafe impl Element for PyFixedString { /// /// ```rust /// # use pyo3::Python; -/// use numpy::{PyArray1, PyFixedUnicode}; +/// use numpy::{PyArray1, PyUntypedArrayMethods, PyFixedUnicode}; /// /// # Python::with_gil(|py| { -/// let array = PyArray1::>::from_vec(py, vec![[b'b' as _, b'a' as _, b'r' as _].into()]); +/// let array = PyArray1::>::from_vec_bound(py, vec![[b'b' as _, b'a' as _, b'r' as _].into()]); /// /// assert!(array.dtype().to_string().contains("U3")); /// # }); diff --git a/src/untyped_array.rs b/src/untyped_array.rs index 46f631542..c51a89458 100644 --- a/src/untyped_array.rs +++ b/src/untyped_array.rs @@ -99,13 +99,14 @@ impl PyUntypedArray { /// # Example /// /// ``` + /// use numpy::prelude::*; /// use numpy::{dtype_bound, PyArray}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let array = PyArray::from_vec(py, vec![1_i32, 2, 3]); + /// let array = PyArray::from_vec_bound(py, vec![1_i32, 2, 3]); /// - /// assert!(array.dtype().is_equiv_to(dtype_bound::(py).as_gil_ref())); + /// assert!(array.dtype().is_equiv_to(&dtype_bound::(py))); /// }); /// ``` /// @@ -269,13 +270,14 @@ pub trait PyUntypedArrayMethods<'py>: Sealed { /// # Example /// /// ``` + /// use numpy::prelude::*; /// use numpy::{dtype_bound, PyArray}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let array = PyArray::from_vec(py, vec![1_i32, 2, 3]); + /// let array = PyArray::from_vec_bound(py, vec![1_i32, 2, 3]); /// - /// assert!(array.dtype().is_equiv_to(dtype_bound::(py).as_gil_ref())); + /// assert!(array.dtype().is_equiv_to(&dtype_bound::(py))); /// }); /// ``` /// diff --git a/tests/array.rs b/tests/array.rs index 5adf3ef8b..610821b1c 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -195,7 +195,7 @@ fn is_instance() { #[test] fn from_vec2() { Python::with_gil(|py| { - let pyarray = PyArray::from_vec2(py, &[vec![1, 2, 3], vec![4, 5, 6]]).unwrap(); + let pyarray = PyArray::from_vec2_bound(py, &[vec![1, 2, 3], vec![4, 5, 6]]).unwrap(); assert_eq!(pyarray.readonly().as_array(), array![[1, 2, 3], [4, 5, 6]]); }); @@ -204,7 +204,7 @@ fn from_vec2() { #[test] fn from_vec2_ragged() { Python::with_gil(|py| { - let pyarray = PyArray::from_vec2(py, &[vec![1, 2, 3], vec![4, 5]]); + let pyarray = PyArray::from_vec2_bound(py, &[vec![1, 2, 3], vec![4, 5]]); let err = pyarray.unwrap_err(); assert_eq!(err.to_string(), "invalid length: 2, but expected 3"); @@ -214,7 +214,7 @@ fn from_vec2_ragged() { #[test] fn from_vec3() { Python::with_gil(|py| { - let pyarray = PyArray::from_vec3( + let pyarray = PyArray::from_vec3_bound( py, &[ vec![vec![1, 2], vec![3, 4]], @@ -234,7 +234,7 @@ fn from_vec3() { #[test] fn from_vec3_ragged() { Python::with_gil(|py| { - let pyarray = PyArray::from_vec3( + let pyarray = PyArray::from_vec3_bound( py, &[ vec![vec![1, 2], vec![3, 4]], @@ -246,7 +246,7 @@ fn from_vec3_ragged() { let err = pyarray.unwrap_err(); assert_eq!(err.to_string(), "invalid length: 1, but expected 2"); - let pyarray = PyArray::from_vec3( + let pyarray = PyArray::from_vec3_bound( py, &[ vec![vec![1, 2], vec![3, 4]], @@ -358,12 +358,16 @@ fn array_cast() { fn handle_negative_strides() { Python::with_gil(|py| { let arr = array![[2, 3], [4, 5u32]]; - let pyarr = arr.to_pyarray(py); + let pyarr = arr.to_pyarray_bound(py); - let neg_str_pyarr: &PyArray2 = py - .eval("a[::-1]", Some([("a", pyarr)].into_py_dict(py)), None) + let neg_str_pyarr = py + .eval_bound( + "a[::-1]", + Some(&[("a", pyarr)].into_py_dict_bound(py)), + None, + ) .unwrap() - .downcast() + .downcast_into::>() .unwrap(); assert_eq!( @@ -377,7 +381,7 @@ fn handle_negative_strides() { fn dtype_via_python_attribute() { Python::with_gil(|py| { let arr = array![[2, 3], [4, 5u32]]; - let pyarr = arr.to_pyarray(py); + let pyarr = arr.to_pyarray_bound(py); let dt = py .eval_bound( @@ -519,7 +523,7 @@ fn get_works() { #[test] fn reshape() { Python::with_gil(|py| { - let array = PyArray::from_iter(py, 0..9) + let array = PyArray::from_iter_bound(py, 0..9) .reshape_with_order([3, 3], NPY_ORDER::NPY_FORTRANORDER) .unwrap(); diff --git a/tests/to_py.rs b/tests/to_py.rs index 92c18626d..d09c3e464 100644 --- a/tests/to_py.rs +++ b/tests/to_py.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use std::mem::size_of; use ndarray::{array, s, Array2, Array3}; -use numpy::{IntoPyArray, PyArray, ToPyArray}; +use numpy::{prelude::*, PyArray}; use pyo3::{ py_run, types::{PyDict, PyString}, @@ -13,7 +13,7 @@ use pyo3::{ fn to_pyarray_vec() { Python::with_gil(|py| { #[allow(clippy::useless_vec)] - let arr = vec![1, 2, 3].to_pyarray(py); + let arr = vec![1, 2, 3].to_pyarray_bound(py); assert_eq!(arr.shape(), [3]); assert_eq!(arr.readonly().as_slice().unwrap(), &[1, 2, 3]) @@ -23,7 +23,7 @@ fn to_pyarray_vec() { #[test] fn to_pyarray_boxed_slice() { Python::with_gil(|py| { - let arr = vec![1, 2, 3].into_boxed_slice().to_pyarray(py); + let arr = vec![1, 2, 3].into_boxed_slice().to_pyarray_bound(py); assert_eq!(arr.shape(), [3]); assert_eq!(arr.readonly().as_slice().unwrap(), &[1, 2, 3]) @@ -42,7 +42,7 @@ fn to_pyarray_array() { .map(|dim| dim * size_of::() as isize) .collect::>(); - let py_arr = PyArray::from_array(py, &arr); + let py_arr = PyArray::from_array_bound(py, &arr); assert_eq!(py_arr.shape(), shape.as_slice()); assert_eq!(py_arr.strides(), strides.as_slice()); @@ -52,7 +52,7 @@ fn to_pyarray_array() { #[test] fn iter_to_pyarray() { Python::with_gil(|py| { - let arr = PyArray::from_iter(py, (0..10).map(|x| x * x)); + let arr = PyArray::from_iter_bound(py, (0..10).map(|x| x * x)); assert_eq!( arr.readonly().as_slice().unwrap(), @@ -64,7 +64,7 @@ fn iter_to_pyarray() { #[test] fn long_iter_to_pyarray() { Python::with_gil(|py| { - let arr = PyArray::from_iter(py, 0_u32..512); + let arr = PyArray::from_iter_bound(py, 0_u32..512); assert_eq!( arr.readonly().as_slice().unwrap(), @@ -80,7 +80,7 @@ fn from_small_array() { $({ Python::with_gil(|py| { let array: [$t; 2] = [<$t>::min_value(), <$t>::max_value()]; - let pyarray = array.to_pyarray(py); + let pyarray = array.to_pyarray_bound(py); assert_eq!( pyarray.readonly().as_slice().unwrap(), @@ -97,7 +97,7 @@ fn from_small_array() { #[test] fn usize_dtype() { Python::with_gil(|py| { - let x = vec![1_usize, 2, 3].into_pyarray(py); + let x = vec![1_usize, 2, 3].into_pyarray_bound(py); if cfg!(target_pointer_width = "64") { py_run!(py, x, "assert str(x.dtype) == 'uint64'") @@ -110,7 +110,7 @@ fn usize_dtype() { #[test] fn into_pyarray_vec() { Python::with_gil(|py| { - let arr = vec![1, 2, 3].into_pyarray(py); + let arr = vec![1, 2, 3].into_pyarray_bound(py); assert_eq!(arr.readonly().as_slice().unwrap(), &[1, 2, 3]) }); @@ -119,7 +119,7 @@ fn into_pyarray_vec() { #[test] fn into_pyarray_boxed_slice() { Python::with_gil(|py| { - let arr = vec![1, 2, 3].into_boxed_slice().into_pyarray(py); + let arr = vec![1, 2, 3].into_boxed_slice().into_pyarray_bound(py); assert_eq!(arr.readonly().as_slice().unwrap(), &[1, 2, 3]) }); @@ -137,7 +137,7 @@ fn into_pyarray_array() { .map(|dim| dim * size_of::() as isize) .collect::>(); - let py_arr = arr.into_pyarray(py); + let py_arr = arr.into_pyarray_bound(py); assert_eq!(py_arr.shape(), shape.as_slice()); assert_eq!(py_arr.strides(), strides.as_slice()); @@ -147,7 +147,7 @@ fn into_pyarray_array() { #[test] fn into_pyarray_cannot_resize() { Python::with_gil(|py| { - let arr = vec![1, 2, 3].into_pyarray(py); + let arr = vec![1, 2, 3].into_pyarray_bound(py); unsafe { assert!(arr.resize(100).is_err()); @@ -158,7 +158,7 @@ fn into_pyarray_cannot_resize() { #[test] fn into_pyarray_can_write() { Python::with_gil(|py| { - let arr = vec![1, 2, 3].into_pyarray(py); + let arr = vec![1, 2, 3].into_pyarray_bound(py); py_run!(py, arr, "assert arr.flags['WRITEABLE']"); py_run!(py, arr, "arr[1] = 4"); @@ -175,7 +175,7 @@ fn collapsed_into_pyarray() { arr.slice_collapse(s![1.., ..]); let cloned_arr = arr.clone(); - let py_arr = arr.into_pyarray(py); + let py_arr = arr.into_pyarray_bound(py); assert_eq!(py_arr.readonly().as_array(), cloned_arr); }); @@ -187,7 +187,7 @@ fn sliced_to_pyarray() { let matrix = Array2::from_shape_vec([4, 2], vec![0, 1, 2, 3, 4, 5, 6, 7]).unwrap(); let sliced_matrix = matrix.slice(s![1..4; -1, ..]); - let py_arr = sliced_matrix.to_pyarray(py); + let py_arr = sliced_matrix.to_pyarray_bound(py); assert_eq!(py_arr.readonly().as_array(), array![[6, 7], [4, 5], [2, 3]],); @@ -201,7 +201,7 @@ fn forder_to_pyarray() { let matrix = Array2::from_shape_vec([4, 2], vec![0, 1, 2, 3, 4, 5, 6, 7]).unwrap(); let forder_matrix = matrix.reversed_axes(); - let py_arr = forder_matrix.to_pyarray(py); + let py_arr = forder_matrix.to_pyarray_bound(py); assert_eq!( py_arr.readonly().as_array(), @@ -218,7 +218,7 @@ fn forder_into_pyarray() { let matrix = Array2::from_shape_vec([4, 2], vec![0, 1, 2, 3, 4, 5, 6, 7]).unwrap(); let forder_matrix = matrix.reversed_axes(); - let py_arr = forder_matrix.into_pyarray(py); + let py_arr = forder_matrix.into_pyarray_bound(py); assert_eq!( py_arr.readonly().as_array(), @@ -237,7 +237,7 @@ fn to_pyarray_object_vec() { #[allow(clippy::useless_vec)] // otherwise we do not test the right trait impl let vec = vec![dict.to_object(py), string.to_object(py)]; - let arr = vec.to_pyarray(py); + let arr = vec.to_pyarray_bound(py); for (a, b) in vec.iter().zip(arr.readonly().as_slice().unwrap().iter()) { assert_eq!( @@ -255,7 +255,7 @@ fn to_pyarray_object_array() { nd_arr[(0, 2)] = PyDict::new(py).to_object(py); nd_arr[(1, 0)] = PyString::new(py, "Hello:)").to_object(py); - let py_arr = nd_arr.to_pyarray(py); + let py_arr = nd_arr.to_pyarray_bound(py); for (a, b) in nd_arr .as_slice() @@ -278,13 +278,13 @@ fn slice_container_type_confusion() { nd_arr[(0, 2)] = PyDict::new(py).to_object(py); nd_arr[(1, 0)] = PyString::new(py, "Hello:)").to_object(py); - let _py_arr = nd_arr.into_pyarray(py); + let _py_arr = nd_arr.into_pyarray_bound(py); // Dropping `_py_arr` used to trigger a segmentation fault due to calling `Py_DECREF` // on 1, 2 and 3 interpreted as pointers into the Python heap // after having created a `SliceBox` backing `_py_arr`, // c.f. https://github.com/PyO3/rust-numpy/issues/232. - let _py_arr = vec![1, 2, 3].into_pyarray(py); + let _py_arr = vec![1, 2, 3].into_pyarray_bound(py); }); } @@ -295,7 +295,7 @@ fn matrix_to_numpy() { assert!(nalgebra::RawStorage::is_contiguous(&matrix.data)); Python::with_gil(|py| { - let array = matrix.to_pyarray(py); + let array = matrix.to_pyarray_bound(py); assert_eq!( array.readonly().as_array(), @@ -307,7 +307,7 @@ fn matrix_to_numpy() { assert!(!nalgebra::RawStorage::is_contiguous(&matrix.data)); Python::with_gil(|py| { - let array = matrix.to_pyarray(py); + let array = matrix.to_pyarray_bound(py); assert_eq!(array.readonly().as_array(), array![[0, 1, 2]]); }); @@ -315,7 +315,7 @@ fn matrix_to_numpy() { let vector = nalgebra::Vector4::::new(-4, 1, 2, 3); Python::with_gil(|py| { - let array = vector.to_pyarray(py); + let array = vector.to_pyarray_bound(py); assert_eq!(array.readonly().as_array(), array![[-4], [1], [2], [3]]); }); @@ -323,7 +323,7 @@ fn matrix_to_numpy() { let vector = nalgebra::RowVector2::::new(23, 42); Python::with_gil(|py| { - let array = vector.to_pyarray(py); + let array = vector.to_pyarray_bound(py); assert_eq!(array.readonly().as_array(), array![[23, 42]]); });