From 4605d224ba5674ab200e405038dc2a3a1cfb4c3a Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Sat, 23 Mar 2024 17:57:12 +0100 Subject: [PATCH 1/5] reexport `PyArray0Methods` --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 753d65caf..a03e44799 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,8 +92,8 @@ pub use pyo3; pub use nalgebra; pub use crate::array::{ - get_array_module, PyArray, PyArray0, PyArray1, PyArray2, PyArray3, PyArray4, PyArray5, - PyArray6, PyArrayDyn, PyArrayMethods, + get_array_module, PyArray, PyArray0, PyArray0Methods, PyArray1, PyArray2, PyArray3, PyArray4, + PyArray5, PyArray6, PyArrayDyn, PyArrayMethods, }; pub use crate::array_like::{ AllowTypeChange, PyArrayLike, PyArrayLike0, PyArrayLike1, PyArrayLike2, PyArrayLike3, From a2db41fd4e6e2ce3082a530adb79ff174c897c8b Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 6 Mar 2024 19:07:44 +0100 Subject: [PATCH 2/5] deprecate `PyArray::new` --- src/array.rs | 62 ++++++++++++++++++++++++++++++++++---------------- src/convert.rs | 17 ++++++++------ tests/array.rs | 6 ++--- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/array.rs b/src/array.rs index f63455896..86976f72a 100644 --- a/src/array.rs +++ b/src/array.rs @@ -292,6 +292,21 @@ impl PyArray { D::from_dimension(&Dim(self.shape())).expect(DIMENSIONALITY_MISMATCH_ERR) } + /// Deprecated form of [`PyArray::new_bound`] + /// + /// # Safety + /// Same as [`PyArray::new_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by `PyArray::new_bound` in the future" + )] + pub unsafe fn new<'py, ID>(py: Python<'py>, dims: ID, is_fortran: bool) -> &Self + where + ID: IntoDimension, + { + Self::new_bound(py, dims, is_fortran).into_gil_ref() + } + /// Creates a new uninitialized NumPy array. /// /// If `is_fortran` is true, then it has Fortran/column-major order, @@ -311,12 +326,12 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray3; + /// use numpy::{PyArray3, PyArrayMethods, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { /// let arr = unsafe { - /// let arr = PyArray3::::new(py, [4, 5, 6], false); + /// let arr = PyArray3::::new_bound(py, [4, 5, 6], false); /// /// for i in 0..4 { /// for j in 0..5 { @@ -332,7 +347,11 @@ impl PyArray { /// assert_eq!(arr.shape(), &[4, 5, 6]); /// }); /// ``` - pub unsafe fn new<'py, ID>(py: Python<'py>, dims: ID, is_fortran: bool) -> &Self + pub unsafe fn new_bound<'py, ID>( + py: Python<'py>, + dims: ID, + is_fortran: bool, + ) -> Bound<'py, Self> where ID: IntoDimension, { @@ -345,7 +364,7 @@ impl PyArray { dims: ID, strides: *const npy_intp, flag: c_int, - ) -> &Self + ) -> Bound<'py, Self> where ID: IntoDimension, { @@ -362,7 +381,7 @@ impl PyArray { ptr::null_mut(), // obj ); - Self::from_owned_ptr(py, ptr) + Bound::from_owned_ptr(py, ptr).downcast_into_unchecked() } unsafe fn new_with_data<'py, ID>( @@ -371,7 +390,7 @@ impl PyArray { strides: *const npy_intp, data_ptr: *const T, container: *mut PyAny, - ) -> &'py Self + ) -> Bound<'py, Self> where ID: IntoDimension, { @@ -394,7 +413,7 @@ impl PyArray { container as *mut ffi::PyObject, ); - Self::from_owned_ptr(py, ptr) + Bound::from_owned_ptr(py, ptr).downcast_into_unchecked() } pub(crate) unsafe fn from_raw_parts<'py>( @@ -403,7 +422,7 @@ impl PyArray { strides: *const npy_intp, data_ptr: *const T, container: PySliceContainer, - ) -> &'py Self { + ) -> Bound<'py, Self> { let container = Bound::new(py, container) .expect("Failed to create slice container") .into_ptr(); @@ -462,6 +481,7 @@ impl PyArray { data_ptr, container as *const PyAny as *mut PyAny, ) + .into_gil_ref() } /// Construct a new NumPy array filled with zeros. @@ -568,6 +588,7 @@ impl PyArray { data_ptr, PySliceContainer::from(arr), ) + .into_gil_ref() } } @@ -968,6 +989,7 @@ impl PyArray { data_ptr, PySliceContainer::from(arr), ) + .into_gil_ref() } } } @@ -998,10 +1020,10 @@ impl PyArray { /// ``` pub fn from_slice<'py>(py: Python<'py>, slice: &[T]) -> &'py Self { unsafe { - let array = PyArray::new(py, [slice.len()], false); + let array = PyArray::new_bound(py, [slice.len()], false); let mut data_ptr = array.data(); clone_elements(slice, &mut data_ptr); - array + array.into_gil_ref() } } @@ -1076,7 +1098,7 @@ impl PyArray { let dims = [v.len(), len2]; // SAFETY: The result of `Self::new` is always safe to drop. unsafe { - let array = Self::new(py, dims, false); + let array = Self::new_bound(py, dims, false); let mut data_ptr = array.data(); for v in v { if v.len() != len2 { @@ -1085,7 +1107,7 @@ impl PyArray { } clone_elements(v, &mut data_ptr); } - Ok(array) + Ok(array.into_gil_ref()) } } } @@ -1127,7 +1149,7 @@ impl PyArray { let dims = [v.len(), len2, len3]; // SAFETY: The result of `Self::new` is always safe to drop. unsafe { - let array = Self::new(py, dims, false); + let array = Self::new_bound(py, dims, false); let mut data_ptr = array.data(); for v in v { if v.len() != len2 { @@ -1142,7 +1164,7 @@ impl PyArray { clone_elements(v, &mut data_ptr); } } - Ok(array) + Ok(array.into_gil_ref()) } } } @@ -1155,14 +1177,14 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { /// let pyarray_f = PyArray::arange(py, 2.0, 5.0, 1.0); - /// let pyarray_i = unsafe { PyArray::::new(py, [3], false) }; + /// let pyarray_i = unsafe { PyArray::::new_bound(py, [3], false) }; /// - /// assert!(pyarray_f.copy_to(pyarray_i).is_ok()); + /// assert!(pyarray_f.copy_to(pyarray_i.as_gil_ref()).is_ok()); /// /// assert_eq!(pyarray_i.readonly().as_slice().unwrap(), &[2, 3, 4]); /// }); @@ -1687,14 +1709,14 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { /// let pyarray_f = PyArray::arange(py, 2.0, 5.0, 1.0); - /// let pyarray_i = unsafe { PyArray::::new(py, [3], false) }; + /// let pyarray_i = unsafe { PyArray::::new_bound(py, [3], false) }; /// - /// assert!(pyarray_f.copy_to(pyarray_i).is_ok()); + /// assert!(pyarray_f.copy_to(pyarray_i.as_gil_ref()).is_ok()); /// /// assert_eq!(pyarray_i.readonly().as_slice().unwrap(), &[2, 3, 4]); /// }); diff --git a/src/convert.rs b/src/convert.rs index 60049d835..f5904187a 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -5,7 +5,7 @@ use std::{mem, os::raw::c_int, ptr}; use ndarray::{ArrayBase, Data, Dim, Dimension, IntoDimension, Ix1, OwnedRepr}; use pyo3::Python; -use crate::array::PyArray; +use crate::array::{PyArray, PyArrayMethods}; use crate::dtype::Element; use crate::error::MAX_DIMENSIONALITY_ERR; use crate::npyffi::{self, npy_intp}; @@ -57,7 +57,9 @@ 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) } + unsafe { + PyArray::from_raw_parts(py, dims, strides.as_ptr(), data_ptr, container).into_gil_ref() + } } } @@ -77,6 +79,7 @@ impl IntoPyArray for Vec { data_ptr, PySliceContainer::from(self), ) + .into_gil_ref() } } } @@ -163,20 +166,20 @@ 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 + array.into_gil_ref() } } _ => { // if the array is not contiguous, copy all elements by `ArrayBase::iter`. let dim = self.raw_dim(); unsafe { - let array = PyArray::::new(py, dim, false); + let array = PyArray::::new_bound(py, dim, false); let mut data_ptr = array.data(); for item in self.iter() { data_ptr.write(item.clone()); data_ptr = data_ptr.add(1); } - array + array.into_gil_ref() } } } @@ -200,7 +203,7 @@ where /// [memory-layout]: https://nalgebra.org/docs/faq/#what-is-the-memory-layout-of-matrices fn to_pyarray<'py>(&self, py: Python<'py>) -> &'py PyArray { unsafe { - let array = PyArray::::new(py, (self.nrows(), self.ncols()), true); + let array = PyArray::::new_bound(py, (self.nrows(), self.ncols()), true); let mut data_ptr = array.data(); if self.data.is_contiguous() { ptr::copy_nonoverlapping(self.data.ptr(), data_ptr, self.len()); @@ -210,7 +213,7 @@ where data_ptr = data_ptr.add(1); } } - array + array.into_gil_ref() } } } diff --git a/tests/array.rs b/tests/array.rs index ac55a3572..0b1e28e67 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -5,7 +5,7 @@ use half::{bf16, f16}; use ndarray::{array, s, Array1, Dim}; use numpy::{ dtype_bound, get_array_module, npyffi::NPY_ORDER, pyarray, PyArray, PyArray1, PyArray2, - PyArrayDescr, PyArrayDescrMethods, PyArrayDyn, PyFixedString, PyFixedUnicode, + PyArrayDescr, PyArrayDescrMethods, PyArrayDyn, PyArrayMethods, PyFixedString, PyFixedUnicode, PyUntypedArrayMethods, ToPyArray, }; use pyo3::{ @@ -487,9 +487,9 @@ fn to_owned_works() { fn copy_to_works() { Python::with_gil(|py| { let arr1 = PyArray::arange(py, 2.0, 5.0, 1.0); - let arr2 = unsafe { PyArray::::new(py, [3], false) }; + let arr2 = unsafe { PyArray::::new_bound(py, [3], false) }; - arr1.copy_to(arr2).unwrap(); + arr1.copy_to(arr2.as_gil_ref()).unwrap(); assert_eq!(arr2.readonly().as_slice().unwrap(), &[2, 3, 4]); }); From 6904173510863a32c26902e81e560091ad1f1649 Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 6 Mar 2024 19:31:46 +0100 Subject: [PATCH 3/5] deprecate `PyArray::borrow_from_array` --- src/array.rs | 35 +++++++++++++++++++++++++---------- tests/array.rs | 6 +++--- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/array.rs b/src/array.rs index 86976f72a..ef7a1d39b 100644 --- a/src/array.rs +++ b/src/array.rs @@ -20,7 +20,7 @@ use pyo3::{ ffi, pyobject_native_type_base, types::{DerefToPyAny, PyAnyMethods, PyModule}, AsPyPointer, Bound, DowncastError, FromPyObject, IntoPy, Py, PyAny, PyErr, PyNativeType, - PyObject, PyResult, PyTypeInfo, Python, ToPyObject, + PyObject, PyResult, PyTypeInfo, Python, }; use crate::borrow::{PyReadonlyArray, PyReadwriteArray}; @@ -430,6 +430,24 @@ impl PyArray { Self::new_with_data(py, dims, strides, data_ptr, container.cast()) } + /// Deprecated form of [`PyArray::borrow_from_array_bound`] + /// + /// # Safety + /// Same as [`PyArray::borrow_from_array_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by `PyArray::borrow_from_array_bound` in the future" + )] + pub unsafe fn borrow_from_array<'py, S>( + array: &ArrayBase, + container: &'py PyAny, + ) -> &'py Self + where + S: Data, + { + Self::borrow_from_array_bound(array, (*container.as_borrowed()).clone()).into_gil_ref() + } + /// Creates a NumPy array backed by `array` and ties its ownership to the Python object `container`. /// /// # Safety @@ -451,19 +469,19 @@ impl PyArray { /// #[pymethods] /// impl Owner { /// #[getter] - /// fn array<'py>(this: &'py PyCell) -> &'py PyArray1 { + /// fn array<'py>(this: Bound<'py, Self>) -> Bound<'py, PyArray1> { /// let array = &this.borrow().array; /// /// // SAFETY: The memory backing `array` will stay valid as long as this object is alive /// // as we do not modify `array` in any way which would cause it to be reallocated. - /// unsafe { PyArray1::borrow_from_array(array, this) } + /// unsafe { PyArray1::borrow_from_array_bound(array, this.into_any()) } /// } /// } /// ``` - pub unsafe fn borrow_from_array<'py, S>( + pub unsafe fn borrow_from_array_bound<'py, S>( array: &ArrayBase, - container: &'py PyAny, - ) -> &'py Self + container: Bound<'py, PyAny>, + ) -> Bound<'py, Self> where S: Data, { @@ -472,16 +490,13 @@ impl PyArray { let py = container.py(); - mem::forget(container.to_object(py)); - Self::new_with_data( py, dims, strides.as_ptr(), data_ptr, - container as *const PyAny as *mut PyAny, + container.into_ptr().cast(), ) - .into_gil_ref() } /// Construct a new NumPy array filled with zeros. diff --git a/tests/array.rs b/tests/array.rs index 0b1e28e67..ed8f77222 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -11,7 +11,7 @@ use numpy::{ use pyo3::{ py_run, pyclass, pymethods, types::{IntoPyDict, PyAnyMethods, PyDict, PyList}, - IntoPy, Py, PyAny, PyCell, PyResult, Python, + Bound, IntoPy, Py, PyAny, PyResult, Python, }; fn get_np_locals<'py>(py: Python<'py>) -> &'py PyDict { @@ -401,10 +401,10 @@ fn borrow_from_array_works() { #[pymethods] impl Owner { #[getter] - fn array(this: &PyCell) -> &PyArray1 { + fn array(this: Bound<'_, Self>) -> Bound<'_, PyArray1> { let array = &this.borrow().array; - unsafe { PyArray1::borrow_from_array(array, this) } + unsafe { PyArray1::borrow_from_array_bound(array, this.into_any()) } } } From 596ed14637f08ea9bbe5a0cc76ab692a3c875883 Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 6 Mar 2024 20:28:29 +0100 Subject: [PATCH 4/5] deprecate `PyArray::from_owned_array` --- src/array.rs | 37 ++++++++++++++++++++++++++++--------- src/convert.rs | 2 +- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/array.rs b/src/array.rs index ef7a1d39b..de4a29bc2 100644 --- a/src/array.rs +++ b/src/array.rs @@ -82,7 +82,7 @@ use crate::untyped_array::{PyUntypedArray, PyUntypedArrayMethods}; /// /// ``` /// use numpy::PyArray; -/// use ndarray::{array, Array}; +/// use ndarray::array; /// use pyo3::Python; /// /// Python::with_gil(|py| { @@ -575,6 +575,15 @@ impl PyArray { } } + /// Deprecated form of [`PyArray::from_owned_array_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by PyArray::from_owned_array_bound in the future" + )] + pub fn from_owned_array<'py>(py: Python<'py>, arr: Array) -> &'py Self { + Self::from_owned_array_bound(py, arr).into_gil_ref() + } + /// Constructs a NumPy from an [`ndarray::Array`] /// /// This method uses the internal [`Vec`] of the [`ndarray::Array`] as the base object of the NumPy array. @@ -582,17 +591,17 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// use ndarray::array; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let pyarray = PyArray::from_owned_array(py, array![[1, 2], [3, 4]]); + /// let pyarray = PyArray::from_owned_array_bound(py, array![[1, 2], [3, 4]]); /// /// assert_eq!(pyarray.readonly().as_array(), array![[1, 2], [3, 4]]); /// }); /// ``` - pub fn from_owned_array<'py>(py: Python<'py>, mut arr: Array) -> &'py Self { + pub fn from_owned_array_bound(py: Python<'_>, mut arr: Array) -> Bound<'_, Self> { let (strides, dims) = (arr.npy_strides(), arr.raw_dim()); let data_ptr = arr.as_mut_ptr(); unsafe { @@ -603,7 +612,6 @@ impl PyArray { data_ptr, PySliceContainer::from(arr), ) - .into_gil_ref() } } @@ -959,6 +967,15 @@ where } impl PyArray { + /// Deprecated form of [`PyArray::from_owned_object_array_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by PyArray::from_owned_object_array_bound in the future" + )] + pub fn from_owned_object_array<'py, T>(py: Python<'py>, arr: Array, D>) -> &'py Self { + Self::from_owned_object_array_bound(py, arr).into_gil_ref() + } + /// Construct a NumPy array containing objects stored in a [`ndarray::Array`] /// /// This method uses the internal [`Vec`] of the [`ndarray::Array`] as the base object of the NumPy array. @@ -968,7 +985,7 @@ impl PyArray { /// ``` /// use ndarray::array; /// use pyo3::{pyclass, Py, Python}; - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods}; /// /// #[pyclass] /// struct CustomElement { @@ -988,12 +1005,15 @@ impl PyArray { /// }).unwrap(), /// ]; /// - /// let pyarray = PyArray::from_owned_object_array(py, array); + /// let pyarray = PyArray::from_owned_object_array_bound(py, array); /// /// assert!(pyarray.readonly().as_array().get(0).unwrap().as_ref(py).is_instance_of::()); /// }); /// ``` - pub fn from_owned_object_array<'py, T>(py: Python<'py>, mut arr: Array, D>) -> &'py Self { + pub fn from_owned_object_array_bound( + py: Python<'_>, + mut arr: Array, D>, + ) -> Bound<'_, Self> { let (strides, dims) = (arr.npy_strides(), arr.raw_dim()); let data_ptr = arr.as_mut_ptr() as *const PyObject; unsafe { @@ -1004,7 +1024,6 @@ impl PyArray { data_ptr, PySliceContainer::from(arr), ) - .into_gil_ref() } } } diff --git a/src/convert.rs b/src/convert.rs index f5904187a..a0d04018c 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -93,7 +93,7 @@ where type Dim = D; fn into_pyarray<'py>(self, py: Python<'py>) -> &'py PyArray { - PyArray::from_owned_array(py, self) + PyArray::from_owned_array_bound(py, self).into_gil_ref() } } From 3adc8fa7a201bccdcde7e8fe5057ff480c3176a8 Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 6 Mar 2024 20:18:18 +0100 Subject: [PATCH 5/5] deprecate `PyArray::zeros` --- src/array.rs | 34 +++++++++----- src/borrow/mod.rs | 44 +++++++++--------- src/borrow/shared.rs | 103 ++++++++++++++++++++++--------------------- src/datetime.rs | 4 +- src/untyped_array.rs | 43 +++++++++--------- tests/array.rs | 26 ++++++----- tests/borrow.rs | 102 ++++++++++++++++++++++-------------------- 7 files changed, 188 insertions(+), 168 deletions(-) diff --git a/src/array.rs b/src/array.rs index de4a29bc2..779c5a2f0 100644 --- a/src/array.rs +++ b/src/array.rs @@ -214,15 +214,15 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray1; + /// use numpy::{PyArray1, PyArrayMethods}; /// use pyo3::{Py, Python}; /// /// let array: Py> = Python::with_gil(|py| { - /// PyArray1::zeros(py, 5, false).to_owned() + /// PyArray1::zeros_bound(py, 5, false).unbind() /// }); /// /// Python::with_gil(|py| { - /// assert_eq!(array.as_ref(py).readonly().as_slice().unwrap(), [0.0; 5]); + /// assert_eq!(array.bind(py).readonly().as_slice().unwrap(), [0.0; 5]); /// }); /// ``` #[deprecated(since = "0.21.0", note = "use Bound::unbind() instead")] @@ -499,6 +499,18 @@ impl PyArray { ) } + /// Deprecated form of [`PyArray::zeros_bound`] + #[deprecated( + since = "0.21.0", + note = "will be replaced by `PyArray::zeros_bound` in the future" + )] + pub fn zeros<'py, ID>(py: Python<'py>, dims: ID, is_fortran: bool) -> &Self + where + ID: IntoDimension, + { + Self::zeros_bound(py, dims, is_fortran).into_gil_ref() + } + /// Construct a new NumPy array filled with zeros. /// /// If `is_fortran` is true, then it has Fortran/column-major order, @@ -512,11 +524,11 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray2; + /// use numpy::{PyArray2, PyArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let pyarray: &PyArray2 = PyArray2::zeros(py, [2, 2], true); + /// let pyarray = PyArray2::::zeros_bound(py, [2, 2], true); /// /// assert_eq!(pyarray.readonly().as_slice().unwrap(), [0; 4]); /// }); @@ -524,7 +536,7 @@ impl PyArray { /// /// [numpy-zeros]: https://numpy.org/doc/stable/reference/generated/numpy.zeros.html /// [PyArray_Zeros]: https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_Zeros - pub fn zeros<'py, ID>(py: Python<'py>, dims: ID, is_fortran: bool) -> &Self + pub fn zeros_bound(py: Python<'_>, dims: ID, is_fortran: bool) -> Bound<'_, Self> where ID: IntoDimension, { @@ -537,7 +549,7 @@ impl PyArray { T::get_dtype_bound(py).into_dtype_ptr(), if is_fortran { -1 } else { 0 }, ); - Self::from_owned_ptr(py, ptr) + Bound::from_owned_ptr(py, ptr).downcast_into_unchecked() } } @@ -1313,11 +1325,11 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let pyarray = PyArray::::zeros(py, (10, 10), false); + /// let pyarray = PyArray::::zeros_bound(py, (10, 10), false); /// assert_eq!(pyarray.shape(), [10, 10]); /// /// unsafe { @@ -1843,11 +1855,11 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// # Example /// /// ``` - /// use numpy::PyArray; + /// use numpy::{PyArray, PyArrayMethods, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let pyarray = PyArray::::zeros(py, (10, 10), false); + /// let pyarray = PyArray::::zeros_bound(py, (10, 10), false); /// assert_eq!(pyarray.shape(), [10, 10]); /// /// unsafe { diff --git a/src/borrow/mod.rs b/src/borrow/mod.rs index 26b189936..0cc436567 100644 --- a/src/borrow/mod.rs +++ b/src/borrow/mod.rs @@ -15,11 +15,11 @@ //! ```rust //! # use std::panic::{catch_unwind, AssertUnwindSafe}; //! # -//! use numpy::PyArray1; +//! use numpy::{PyArray1, PyArrayMethods}; //! use ndarray::Zip; -//! use pyo3::Python; +//! use pyo3::{Python, Bound}; //! -//! fn add(x: &PyArray1, y: &PyArray1, z: &PyArray1) { +//! fn add(x: &Bound<'_, PyArray1>, y: &Bound<'_, PyArray1>, z: &Bound<'_, PyArray1>) { //! let x1 = x.readonly(); //! let y1 = y.readonly(); //! let mut z1 = z.readwrite(); @@ -41,19 +41,19 @@ //! } //! //! Python::with_gil(|py| { -//! let x = PyArray1::::zeros(py, 42, false); -//! let y = PyArray1::::zeros(py, 42, false); -//! let z = PyArray1::::zeros(py, 42, false); +//! let x = PyArray1::::zeros_bound(py, 42, false); +//! let y = PyArray1::::zeros_bound(py, 42, false); +//! let z = PyArray1::::zeros_bound(py, 42, false); //! //! // Will work as the three arrays are distinct. -//! add(x, y, z); +//! add(&x, &y, &z); //! //! // Will work as `x1` and `y1` are compatible borrows. -//! add(x, x, z); +//! add(&x, &x, &z); //! //! // Will fail at runtime due to conflict between `y1` and `z1`. //! let res = catch_unwind(AssertUnwindSafe(|| { -//! add(x, y, y); +//! add(&x, &y, &y); //! })); //! assert!(res.is_err()); //! }); @@ -91,15 +91,15 @@ //! ```rust //! # use std::panic::{catch_unwind, AssertUnwindSafe}; //! # -//! use numpy::PyArray2; -//! use pyo3::{types::IntoPyDict, Python}; +//! use numpy::{PyArray2, PyArrayMethods}; +//! use pyo3::{types::{IntoPyDict, PyAnyMethods}, Python}; //! //! Python::with_gil(|py| { -//! let array = PyArray2::::zeros(py, (10, 10), false); -//! let locals = [("array", array)].into_py_dict(py); +//! let array = PyArray2::::zeros_bound(py, (10, 10), false); +//! let locals = [("array", array)].into_py_dict_bound(py); //! -//! let view1 = py.eval("array[:, ::3]", None, Some(locals)).unwrap().downcast::>().unwrap(); -//! let view2 = py.eval("array[:, 1::3]", None, Some(locals)).unwrap().downcast::>().unwrap(); +//! let view1 = py.eval_bound("array[:, ::3]", None, Some(&locals)).unwrap().downcast_into::>().unwrap(); +//! let view2 = py.eval_bound("array[:, 1::3]", None, Some(&locals)).unwrap().downcast_into::>().unwrap(); //! //! // A false conflict as the views do not actually share any elements. //! let res = catch_unwind(AssertUnwindSafe(|| { @@ -589,7 +589,7 @@ mod tests { #[test] fn test_debug_formatting() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); { let shared = array.readonly(); @@ -615,7 +615,7 @@ mod tests { #[should_panic(expected = "AlreadyBorrowed")] fn cannot_clone_exclusive_borrow_via_deref() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (3, 2, 1), false); + let array = PyArray::::zeros_bound(py, (3, 2, 1), false); let exclusive = array.readwrite(); let _shared = exclusive.clone(); @@ -625,14 +625,14 @@ mod tests { #[test] fn failed_resize_does_not_double_release() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, 10, false); + let array = PyArray::::zeros_bound(py, 10, false); // The view will make the internal reference check of `PyArray_Resize` fail. - let locals = [("array", array)].into_py_dict(py); + let locals = [("array", &array)].into_py_dict_bound(py); let _view = py - .eval("array[:]", None, Some(locals)) + .eval_bound("array[:]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); let exclusive = array.readwrite(); @@ -643,7 +643,7 @@ mod tests { #[test] fn ineffective_resize_does_not_conflict() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, 10, false); + let array = PyArray::::zeros_bound(py, 10, false); let exclusive = array.readwrite(); assert!(exclusive.resize(10).is_ok()); diff --git a/src/borrow/shared.rs b/src/borrow/shared.rs index feccadc7c..a92e6d35d 100644 --- a/src/borrow/shared.rs +++ b/src/borrow/shared.rs @@ -447,8 +447,9 @@ mod tests { use ndarray::Array; use pyo3::types::IntoPyDict; - use crate::array::{PyArray, PyArray1, PyArray2, PyArray3}; + use crate::array::{PyArray, PyArray1, PyArray2, PyArray3, PyArrayMethods}; use crate::convert::IntoPyArray; + use crate::untyped_array::PyUntypedArrayMethods; fn get_borrow_flags<'py>(py: Python<'py>) -> &'py BorrowFlagsInner { let shared = get_or_insert_shared(py).unwrap(); @@ -459,13 +460,13 @@ mod tests { #[test] fn without_base_object() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let base = unsafe { (*array.as_array_ptr()).base }; assert!(base.is_null()); let base_address = base_address(py, array.as_array_ptr()); - assert_eq!(base_address, array as *const _ as *mut c_void); + assert_eq!(base_address, array.as_ptr().cast()); let data_range = data_range(array.as_array_ptr()); assert_eq!(data_range.0, array.data() as *mut c_char); @@ -494,25 +495,25 @@ mod tests { #[test] fn view_without_base_object() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); - 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 as *mut c_void, array.as_ptr().cast::()); let base_address = base_address(py, view.as_array_ptr()); - assert_ne!(base_address, view as *const _ as *mut c_void); - assert_eq!(base_address, base as *mut c_void); + assert_ne!(base_address, view.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); @@ -556,43 +557,43 @@ mod tests { #[test] fn view_of_view_without_base_object() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); - 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(py); let view2 = py .eval("view1[:,0]", None, Some(locals)) .unwrap() .downcast::>() .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 as *mut c_void, 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 as *mut c_void, array.as_ptr().cast::()); 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, view2.as_ptr().cast::()); + assert_ne!(base_address, view1.as_ptr().cast::()); assert_eq!(base_address, base as *mut c_void); let data_range = data_range(view2.as_array_ptr()); @@ -656,25 +657,25 @@ mod tests { #[test] fn view_with_negative_strides() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); - let locals = [("array", array)].into_py_dict(py); + let locals = [("array", &array)].into_py_dict_bound(py); let view = py - .eval("array[::-1,:,::-1]", None, Some(locals)) + .eval_bound("array[::-1,:,::-1]", 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_address = base_address(py, view.as_array_ptr()); - assert_ne!(base_address, view as *const _ as *mut c_void); - assert_eq!(base_address, base as *mut c_void); + assert_ne!(base_address, view.as_ptr().cast::()); + assert_eq!(base_address, base.cast::()); let data_range = data_range(view.as_array_ptr()); assert_eq!(view.data(), unsafe { array.data().offset(2) }); @@ -688,13 +689,13 @@ mod tests { #[test] fn array_with_zero_dimensions() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 0, 3), false); + let array = PyArray::::zeros_bound(py, (1, 0, 3), false); let base = unsafe { (*array.as_array_ptr()).base }; assert!(base.is_null()); let base_address = base_address(py, array.as_array_ptr()); - assert_eq!(base_address, array as *const _ as *mut c_void); + assert_eq!(base_address, array.as_ptr().cast::()); let data_range = data_range(array.as_array_ptr()); assert_eq!(data_range.0, array.data() as *mut c_char); @@ -705,13 +706,13 @@ mod tests { #[test] fn view_with_non_dividing_strides() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (10, 10), false); - let locals = [("array", array)].into_py_dict(py); + let array = PyArray::::zeros_bound(py, (10, 10), false); + let locals = [("array", array)].into_py_dict_bound(py); let view1 = py - .eval("array[:,::3]", None, Some(locals)) + .eval_bound("array[:,::3]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); let key1 = borrow_key(view1.as_array_ptr()); @@ -720,9 +721,9 @@ mod tests { assert_eq!(key1.gcd_strides, 8); let view2 = py - .eval("array[:,1::3]", None, Some(locals)) + .eval_bound("array[:,1::3]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); let key2 = borrow_key(view2.as_array_ptr()); @@ -731,9 +732,9 @@ mod tests { assert_eq!(key2.gcd_strides, 8); let view3 = py - .eval("array[:,::2]", None, Some(locals)) + .eval_bound("array[:,::2]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); let key3 = borrow_key(view3.as_array_ptr()); @@ -742,9 +743,9 @@ mod tests { assert_eq!(key3.gcd_strides, 16); let view4 = py - .eval("array[:,1::2]", None, Some(locals)) + .eval_bound("array[:,1::2]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); let key4 = borrow_key(view4.as_array_ptr()); @@ -764,8 +765,8 @@ mod tests { #[test] fn borrow_multiple_arrays() { Python::with_gil(|py| { - let array1 = PyArray::::zeros(py, 10, false); - let array2 = PyArray::::zeros(py, 10, false); + let array1 = PyArray::::zeros_bound(py, 10, false); + let array2 = PyArray::::zeros_bound(py, 10, false); let base1 = base_address(py, array1.as_array_ptr()); let base2 = base_address(py, array2.as_array_ptr()); @@ -809,7 +810,7 @@ mod tests { #[test] fn borrow_multiple_views() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, 10, false); + let array = PyArray::::zeros_bound(py, 10, false); let base = base_address(py, array.as_array_ptr()); let locals = [("array", array)].into_py_dict(py); diff --git a/src/datetime.rs b/src/datetime.rs index adcd77cf5..38036c5a4 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -254,7 +254,7 @@ mod tests { types::{PyDict, PyModule}, }; - use crate::array::PyArray1; + use crate::array::{PyArray1, PyArrayMethods}; #[test] fn from_python_to_rust() { @@ -283,7 +283,7 @@ mod tests { #[test] fn from_rust_to_python() { Python::with_gil(|py| { - let array = PyArray1::>::zeros(py, 1, false); + let array = PyArray1::>::zeros_bound(py, 1, false); *array.readwrite().get_mut(0).unwrap() = Timedelta::::from(5); diff --git a/src/untyped_array.rs b/src/untyped_array.rs index cf5bd385c..15eba035a 100644 --- a/src/untyped_array.rs +++ b/src/untyped_array.rs @@ -28,11 +28,12 @@ use crate::npyffi; /// ``` /// # use pyo3::prelude::*; /// use pyo3::exceptions::PyTypeError; -/// use numpy::{Element, PyUntypedArray, PyArray1, dtype}; +/// use numpy::{Element, PyUntypedArray, PyArray1, dtype_bound}; +/// use numpy::{PyUntypedArrayMethods, PyArrayMethods, PyArrayDescrMethods}; /// /// #[pyfunction] -/// fn entry_point(py: Python, array: &PyUntypedArray) -> PyResult<()> { -/// fn implementation(array: &PyArray1) -> PyResult<()> { +/// fn entry_point(py: Python<'_>, array: &Bound<'_, PyUntypedArray>) -> PyResult<()> { +/// fn implementation(array: &Bound<'_, PyArray1>) -> PyResult<()> { /// /* .. */ /// /// Ok(()) @@ -40,12 +41,12 @@ use crate::npyffi; /// /// let element_type = array.dtype(); /// -/// if element_type.is_equiv_to(dtype::(py)) { -/// let array: &PyArray1 = array.downcast()?; +/// if element_type.is_equiv_to(&dtype_bound::(py)) { +/// let array = array.downcast::>()?; /// /// implementation(array) -/// } else if element_type.is_equiv_to(dtype::(py)) { -/// let array: &PyArray1 = array.downcast()?; +/// } else if element_type.is_equiv_to(&dtype_bound::(py)) { +/// let array = array.downcast::>()?; /// /// implementation(array) /// } else { @@ -54,8 +55,8 @@ use crate::npyffi; /// } /// # /// # Python::with_gil(|py| { -/// # let array = PyArray1::::zeros(py, 42, false); -/// # entry_point(py, array) +/// # let array = PyArray1::::zeros_bound(py, 42, false); +/// # entry_point(py, array.as_untyped()) /// # }).unwrap(); /// ``` #[repr(transparent)] @@ -160,11 +161,11 @@ impl PyUntypedArray { /// # Example /// /// ``` - /// use numpy::PyArray3; + /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); + /// let arr = PyArray3::::zeros_bound(py, [4, 5, 6], false); /// /// assert_eq!(arr.ndim(), 3); /// }); @@ -184,11 +185,11 @@ impl PyUntypedArray { /// # Example /// /// ``` - /// use numpy::PyArray3; + /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); + /// let arr = PyArray3::::zeros_bound(py, [4, 5, 6], false); /// /// assert_eq!(arr.strides(), &[240, 48, 8]); /// }); @@ -216,11 +217,11 @@ impl PyUntypedArray { /// # Example /// /// ``` - /// use numpy::PyArray3; + /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); + /// let arr = PyArray3::::zeros_bound(py, [4, 5, 6], false); /// /// assert_eq!(arr.shape(), &[4, 5, 6]); /// }); @@ -329,11 +330,11 @@ pub trait PyUntypedArrayMethods<'py>: sealed::Sealed { /// # Example /// /// ``` - /// use numpy::PyArray3; + /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); + /// let arr = PyArray3::::zeros_bound(py, [4, 5, 6], false); /// /// assert_eq!(arr.ndim(), 3); /// }); @@ -353,11 +354,11 @@ pub trait PyUntypedArrayMethods<'py>: sealed::Sealed { /// # Example /// /// ``` - /// use numpy::PyArray3; + /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); + /// let arr = PyArray3::::zeros_bound(py, [4, 5, 6], false); /// /// assert_eq!(arr.strides(), &[240, 48, 8]); /// }); @@ -385,11 +386,11 @@ pub trait PyUntypedArrayMethods<'py>: sealed::Sealed { /// # Example /// /// ``` - /// use numpy::PyArray3; + /// use numpy::{PyArray3, PyUntypedArrayMethods}; /// use pyo3::Python; /// /// Python::with_gil(|py| { - /// let arr = PyArray3::::zeros(py, [4, 5, 6], false); + /// let arr = PyArray3::::zeros_bound(py, [4, 5, 6], false); /// /// assert_eq!(arr.shape(), &[4, 5, 6]); /// }); diff --git a/tests/array.rs b/tests/array.rs index ed8f77222..65bc7621c 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -4,9 +4,11 @@ use std::mem::size_of; use half::{bf16, f16}; use ndarray::{array, s, Array1, Dim}; use numpy::{ - dtype_bound, get_array_module, npyffi::NPY_ORDER, pyarray, PyArray, PyArray1, PyArray2, - PyArrayDescr, PyArrayDescrMethods, PyArrayDyn, PyArrayMethods, PyFixedString, PyFixedUnicode, - PyUntypedArrayMethods, ToPyArray, + array::{PyArray0Methods, PyArrayMethods}, + dtype_bound, get_array_module, + npyffi::NPY_ORDER, + pyarray, PyArray, PyArray1, PyArray2, PyArrayDescr, PyArrayDescrMethods, PyArrayDyn, + PyFixedString, PyFixedUnicode, PyUntypedArrayMethods, ToPyArray, }; use pyo3::{ py_run, pyclass, pymethods, @@ -34,7 +36,7 @@ fn new_c_order() { Python::with_gil(|py| { let dims = [3, 5]; - let arr = PyArray::::zeros(py, dims, false); + let arr = PyArray::::zeros_bound(py, dims, false); assert!(arr.ndim() == 2); assert!(arr.dims() == dims); @@ -56,7 +58,7 @@ fn new_fortran_order() { Python::with_gil(|py| { let dims = [3, 5]; - let arr = PyArray::::zeros(py, dims, true); + let arr = PyArray::::zeros_bound(py, dims, true); assert!(arr.ndim() == 2); assert!(arr.dims() == dims); @@ -78,7 +80,7 @@ fn tuple_as_dim() { Python::with_gil(|py| { let dims = (3, 5); - let arr = PyArray::::zeros(py, dims, false); + let arr = PyArray::::zeros_bound(py, dims, false); assert!(arr.ndim() == 2); assert!(arr.dims() == [3, 5]); @@ -88,7 +90,7 @@ fn tuple_as_dim() { #[test] fn rank_zero_array_has_invalid_strides_dimensions() { Python::with_gil(|py| { - let arr = PyArray::::zeros(py, (), false); + let arr = PyArray::::zeros_bound(py, (), false); assert_eq!(arr.ndim(), 0); assert_eq!(arr.strides(), &[]); @@ -106,7 +108,7 @@ fn zeros() { Python::with_gil(|py| { let dims = [3, 4]; - let arr = PyArray::::zeros(py, dims, false); + let arr = PyArray::::zeros_bound(py, dims, false); assert!(arr.ndim() == 2); assert!(arr.dims() == dims); @@ -114,7 +116,7 @@ fn zeros() { let size = size_of::() as isize; assert!(arr.strides() == [dims[1] as isize * size, size]); - let arr = PyArray::::zeros(py, dims, true); + let arr = PyArray::::zeros_bound(py, dims, true); assert!(arr.ndim() == 2); assert!(arr.dims() == dims); @@ -137,7 +139,7 @@ fn arange() { #[test] fn as_array() { Python::with_gil(|py| { - let pyarr = PyArray::::zeros(py, [3, 2, 4], false).readonly(); + let pyarr = PyArray::::zeros_bound(py, [3, 2, 4], false).readonly(); let arr = pyarr.as_array(); assert_eq!(pyarr.shape(), arr.shape()); @@ -171,7 +173,7 @@ fn as_raw_array() { #[test] fn as_slice() { Python::with_gil(|py| { - let arr = PyArray::::zeros(py, [3, 2, 4], false); + let arr = PyArray::::zeros_bound(py, [3, 2, 4], false); assert_eq!(arr.readonly().as_slice().unwrap().len(), 3 * 2 * 4); let not_contiguous = not_contiguous_array(py); @@ -183,7 +185,7 @@ fn as_slice() { #[test] fn is_instance() { Python::with_gil(|py| { - let arr = PyArray2::::zeros(py, [3, 5], false); + let arr = PyArray2::::zeros_bound(py, [3, 5], false); assert!(arr.is_instance_of::>()); assert!(!arr.is_instance_of::()); diff --git a/tests/borrow.rs b/tests/borrow.rs index 576eb9fc1..24cf37ad3 100644 --- a/tests/borrow.rs +++ b/tests/borrow.rs @@ -4,13 +4,17 @@ use numpy::{ array::PyArrayMethods, npyffi::NPY_ARRAY_WRITEABLE, PyArray, PyArray1, PyArray2, PyReadonlyArray3, PyReadwriteArray3, PyUntypedArrayMethods, }; -use pyo3::{py_run, pyclass, pymethods, types::IntoPyDict, Py, PyAny, PyNativeType, Python}; +use pyo3::{ + py_run, pyclass, pymethods, + types::{IntoPyDict, PyAnyMethods}, + Py, Python, +}; #[test] fn distinct_borrows() { Python::with_gil(|py| { - let array1 = PyArray::::zeros(py, (1, 2, 3), false); - let array2 = PyArray::::zeros(py, (1, 2, 3), false); + let array1 = PyArray::::zeros_bound(py, (1, 2, 3), false); + let array2 = PyArray::::zeros_bound(py, (1, 2, 3), false); let exclusive1 = array1.readwrite(); let exclusive2 = array2.readwrite(); @@ -23,7 +27,7 @@ fn distinct_borrows() { #[test] fn multiple_shared_borrows() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let shared1 = array.readonly(); let shared2 = array.readonly(); @@ -37,7 +41,7 @@ fn multiple_shared_borrows() { #[should_panic(expected = "AlreadyBorrowed")] fn exclusive_and_shared_borrows() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let _exclusive = array.readwrite(); let _shared = array.readonly(); @@ -48,7 +52,7 @@ fn exclusive_and_shared_borrows() { #[should_panic(expected = "AlreadyBorrowed")] fn shared_and_exclusive_borrows() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let _shared = array.readonly(); let _exclusive = array.readwrite(); @@ -58,7 +62,7 @@ fn shared_and_exclusive_borrows() { #[test] fn multiple_exclusive_borrows() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let _exclusive = array.try_readwrite().unwrap(); @@ -70,7 +74,7 @@ fn multiple_exclusive_borrows() { #[test] fn exclusive_borrow_requires_writeable() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); unsafe { (*array.as_array_ptr()).flags &= !NPY_ARRAY_WRITEABLE; @@ -97,7 +101,7 @@ fn borrows_span_frames() { Python::with_gil(|py| { let borrower = Py::new(py, Borrower).unwrap(); - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let _exclusive = array.readwrite(); @@ -108,7 +112,7 @@ fn borrows_span_frames() { #[test] fn borrows_span_threads() { Python::with_gil(|py| { - let array = (*PyArray::::zeros(py, (1, 2, 3), false).as_borrowed()).clone(); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let _exclusive = array.readwrite(); @@ -131,7 +135,7 @@ fn borrows_span_threads() { #[test] fn shared_borrows_can_be_cloned() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let shared1 = array.readonly(); let shared2 = shared1.clone(); @@ -145,20 +149,20 @@ fn shared_borrows_can_be_cloned() { #[should_panic(expected = "AlreadyBorrowed")] fn overlapping_views_conflict() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); - let locals = [("array", array)].into_py_dict(py); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); + let locals = [("array", array)].into_py_dict_bound(py); let view1 = py - .eval("array[0,0,0:2]", None, Some(locals)) + .eval_bound("array[0,0,0:2]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view1.shape(), [2]); let view2 = py - .eval("array[0,0,1:3]", None, Some(locals)) + .eval_bound("array[0,0,1:3]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view2.shape(), [2]); @@ -170,20 +174,20 @@ fn overlapping_views_conflict() { #[test] fn non_overlapping_views_do_not_conflict() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); - let locals = [("array", array)].into_py_dict(py); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); + let locals = [("array", array)].into_py_dict_bound(py); let view1 = py - .eval("array[0,0,0:1]", None, Some(locals)) + .eval_bound("array[0,0,0:1]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view1.shape(), [1]); let view2 = py - .eval("array[0,0,2:3]", None, Some(locals)) + .eval_bound("array[0,0,2:3]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view2.shape(), [1]); @@ -199,20 +203,20 @@ fn non_overlapping_views_do_not_conflict() { #[should_panic(expected = "AlreadyBorrowed")] fn conflict_due_to_overlapping_views() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, 3, false); - let locals = [("array", array)].into_py_dict(py); + let array = PyArray::::zeros_bound(py, 3, false); + let locals = [("array", array)].into_py_dict_bound(py); let view1 = py - .eval("array[0:2]", None, Some(locals)) + .eval_bound("array[0:2]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view1.shape(), [2]); let view2 = py - .eval("array[1:3]", None, Some(locals)) + .eval_bound("array[1:3]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view2.shape(), [2]); @@ -225,20 +229,20 @@ fn conflict_due_to_overlapping_views() { #[should_panic(expected = "AlreadyBorrowed")] fn conflict_due_to_reborrow_of_overlapping_views() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, 3, false); - let locals = [("array", array)].into_py_dict(py); + let array = PyArray::::zeros_bound(py, 3, false); + let locals = [("array", array)].into_py_dict_bound(py); let view1 = py - .eval("array[0:2]", None, Some(locals)) + .eval_bound("array[0:2]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view1.shape(), [2]); let view2 = py - .eval("array[1:3]", None, Some(locals)) + .eval_bound("array[1:3]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view2.shape(), [2]); @@ -253,27 +257,27 @@ fn conflict_due_to_reborrow_of_overlapping_views() { #[test] fn interleaved_views_do_not_conflict() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (23, 42, 3), false); - let locals = [("array", array)].into_py_dict(py); + let array = PyArray::::zeros_bound(py, (23, 42, 3), false); + 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_eq!(view1.shape(), [23, 42]); let view2 = py - .eval("array[:,:,1]", None, Some(locals)) + .eval_bound("array[:,:,1]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view2.shape(), [23, 42]); let view3 = py - .eval("array[:,:,2]", None, Some(locals)) + .eval_bound("array[:,:,2]", None, Some(&locals)) .unwrap() - .downcast::>() + .downcast_into::>() .unwrap(); assert_eq!(view2.shape(), [23, 42]); @@ -290,7 +294,7 @@ fn interleaved_views_do_not_conflict() { #[test] fn extract_readonly() { Python::with_gil(|py| { - let ob: &PyAny = PyArray::::zeros(py, (1, 2, 3), false); + let ob = PyArray::::zeros_bound(py, (1, 2, 3), false).into_any(); ob.extract::>().unwrap(); }); } @@ -298,7 +302,7 @@ fn extract_readonly() { #[test] fn extract_readwrite() { Python::with_gil(|py| { - let ob: &PyAny = PyArray::::zeros(py, (1, 2, 3), false); + let ob = PyArray::::zeros_bound(py, (1, 2, 3), false).into_any(); ob.extract::>().unwrap(); }); } @@ -306,7 +310,7 @@ fn extract_readwrite() { #[test] fn readonly_as_array_slice_get() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let array = array.readonly(); assert_eq!(array.as_array().shape(), [1, 2, 3]); @@ -318,7 +322,7 @@ fn readonly_as_array_slice_get() { #[test] fn readwrite_as_array_slice() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (1, 2, 3), false); + let array = PyArray::::zeros_bound(py, (1, 2, 3), false); let mut array = array.readwrite(); assert_eq!(array.as_array().shape(), [1, 2, 3]); @@ -333,7 +337,7 @@ fn readwrite_as_array_slice() { #[test] fn resize_using_exclusive_borrow() { Python::with_gil(|py| { - let array = PyArray::::zeros(py, 3, false); + let array = PyArray::::zeros_bound(py, 3, false); assert_eq!(array.shape(), [3]); let mut array = array.readwrite(); @@ -412,7 +416,7 @@ fn matrix_from_numpy() { }); Python::with_gil(|py| { - let array = PyArray::::zeros(py, (2, 2, 2), false); + let array = PyArray::::zeros_bound(py, (2, 2, 2), false); let array = array.readonly(); let matrix: Option> =