Skip to content

Commit 271b634

Browse files
Icxoluadamreichold
authored andcommitted
deprecate PyArray::new
1 parent 219cfda commit 271b634

File tree

3 files changed

+55
-30
lines changed

3 files changed

+55
-30
lines changed

src/array.rs

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,21 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
292292
D::from_dimension(&Dim(self.shape())).expect(DIMENSIONALITY_MISMATCH_ERR)
293293
}
294294

295+
/// Deprecated form of [`PyArray<T, D>::new_bound`]
296+
///
297+
/// # Safety
298+
/// Same as [`PyArray<T, D>::new_bound`]
299+
#[deprecated(
300+
since = "0.21.0",
301+
note = "will be replaced by `PyArray::new_bound` in the future"
302+
)]
303+
pub unsafe fn new<'py, ID>(py: Python<'py>, dims: ID, is_fortran: bool) -> &Self
304+
where
305+
ID: IntoDimension<Dim = D>,
306+
{
307+
Self::new_bound(py, dims, is_fortran).into_gil_ref()
308+
}
309+
295310
/// Creates a new uninitialized NumPy array.
296311
///
297312
/// If `is_fortran` is true, then it has Fortran/column-major order,
@@ -311,12 +326,12 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
311326
/// # Example
312327
///
313328
/// ```
314-
/// use numpy::PyArray3;
329+
/// use numpy::{PyArray3, PyArrayMethods, PyUntypedArrayMethods};
315330
/// use pyo3::Python;
316331
///
317332
/// Python::with_gil(|py| {
318333
/// let arr = unsafe {
319-
/// let arr = PyArray3::<i32>::new(py, [4, 5, 6], false);
334+
/// let arr = PyArray3::<i32>::new_bound(py, [4, 5, 6], false);
320335
///
321336
/// for i in 0..4 {
322337
/// for j in 0..5 {
@@ -332,7 +347,11 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
332347
/// assert_eq!(arr.shape(), &[4, 5, 6]);
333348
/// });
334349
/// ```
335-
pub unsafe fn new<'py, ID>(py: Python<'py>, dims: ID, is_fortran: bool) -> &Self
350+
pub unsafe fn new_bound<'py, ID>(
351+
py: Python<'py>,
352+
dims: ID,
353+
is_fortran: bool,
354+
) -> Bound<'py, Self>
336355
where
337356
ID: IntoDimension<Dim = D>,
338357
{
@@ -345,7 +364,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
345364
dims: ID,
346365
strides: *const npy_intp,
347366
flag: c_int,
348-
) -> &Self
367+
) -> Bound<'py, Self>
349368
where
350369
ID: IntoDimension<Dim = D>,
351370
{
@@ -362,7 +381,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
362381
ptr::null_mut(), // obj
363382
);
364383

365-
Self::from_owned_ptr(py, ptr)
384+
Bound::from_owned_ptr(py, ptr).downcast_into_unchecked()
366385
}
367386

368387
unsafe fn new_with_data<'py, ID>(
@@ -371,7 +390,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
371390
strides: *const npy_intp,
372391
data_ptr: *const T,
373392
container: *mut PyAny,
374-
) -> &'py Self
393+
) -> Bound<'py, Self>
375394
where
376395
ID: IntoDimension<Dim = D>,
377396
{
@@ -394,7 +413,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
394413
container as *mut ffi::PyObject,
395414
);
396415

397-
Self::from_owned_ptr(py, ptr)
416+
Bound::from_owned_ptr(py, ptr).downcast_into_unchecked()
398417
}
399418

400419
pub(crate) unsafe fn from_raw_parts<'py>(
@@ -403,7 +422,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
403422
strides: *const npy_intp,
404423
data_ptr: *const T,
405424
container: PySliceContainer,
406-
) -> &'py Self {
425+
) -> Bound<'py, Self> {
407426
let container = Bound::new(py, container)
408427
.expect("Failed to create slice container")
409428
.into_ptr();
@@ -462,6 +481,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
462481
data_ptr,
463482
container as *const PyAny as *mut PyAny,
464483
)
484+
.into_gil_ref()
465485
}
466486

467487
/// Construct a new NumPy array filled with zeros.
@@ -568,6 +588,7 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
568588
data_ptr,
569589
PySliceContainer::from(arr),
570590
)
591+
.into_gil_ref()
571592
}
572593
}
573594

@@ -972,6 +993,7 @@ impl<D: Dimension> PyArray<PyObject, D> {
972993
data_ptr,
973994
PySliceContainer::from(arr),
974995
)
996+
.into_gil_ref()
975997
}
976998
}
977999
}
@@ -1002,10 +1024,10 @@ impl<T: Element> PyArray<T, Ix1> {
10021024
/// ```
10031025
pub fn from_slice<'py>(py: Python<'py>, slice: &[T]) -> &'py Self {
10041026
unsafe {
1005-
let array = PyArray::new(py, [slice.len()], false);
1027+
let array = PyArray::new_bound(py, [slice.len()], false);
10061028
let mut data_ptr = array.data();
10071029
clone_elements(slice, &mut data_ptr);
1008-
array
1030+
array.into_gil_ref()
10091031
}
10101032
}
10111033

@@ -1080,7 +1102,7 @@ impl<T: Element> PyArray<T, Ix2> {
10801102
let dims = [v.len(), len2];
10811103
// SAFETY: The result of `Self::new` is always safe to drop.
10821104
unsafe {
1083-
let array = Self::new(py, dims, false);
1105+
let array = Self::new_bound(py, dims, false);
10841106
let mut data_ptr = array.data();
10851107
for v in v {
10861108
if v.len() != len2 {
@@ -1089,7 +1111,7 @@ impl<T: Element> PyArray<T, Ix2> {
10891111
}
10901112
clone_elements(v, &mut data_ptr);
10911113
}
1092-
Ok(array)
1114+
Ok(array.into_gil_ref())
10931115
}
10941116
}
10951117
}
@@ -1131,7 +1153,7 @@ impl<T: Element> PyArray<T, Ix3> {
11311153
let dims = [v.len(), len2, len3];
11321154
// SAFETY: The result of `Self::new` is always safe to drop.
11331155
unsafe {
1134-
let array = Self::new(py, dims, false);
1156+
let array = Self::new_bound(py, dims, false);
11351157
let mut data_ptr = array.data();
11361158
for v in v {
11371159
if v.len() != len2 {
@@ -1146,7 +1168,7 @@ impl<T: Element> PyArray<T, Ix3> {
11461168
clone_elements(v, &mut data_ptr);
11471169
}
11481170
}
1149-
Ok(array)
1171+
Ok(array.into_gil_ref())
11501172
}
11511173
}
11521174
}
@@ -1159,14 +1181,14 @@ impl<T: Element, D> PyArray<T, D> {
11591181
/// # Example
11601182
///
11611183
/// ```
1162-
/// use numpy::PyArray;
1184+
/// use numpy::{PyArray, PyArrayMethods};
11631185
/// use pyo3::Python;
11641186
///
11651187
/// Python::with_gil(|py| {
11661188
/// let pyarray_f = PyArray::arange(py, 2.0, 5.0, 1.0);
1167-
/// let pyarray_i = unsafe { PyArray::<i64, _>::new(py, [3], false) };
1189+
/// let pyarray_i = unsafe { PyArray::<i64, _>::new_bound(py, [3], false) };
11681190
///
1169-
/// assert!(pyarray_f.copy_to(pyarray_i).is_ok());
1191+
/// assert!(pyarray_f.copy_to(pyarray_i.as_gil_ref()).is_ok());
11701192
///
11711193
/// assert_eq!(pyarray_i.readonly().as_slice().unwrap(), &[2, 3, 4]);
11721194
/// });
@@ -1691,14 +1713,14 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> {
16911713
/// # Example
16921714
///
16931715
/// ```
1694-
/// use numpy::PyArray;
1716+
/// use numpy::{PyArray, PyArrayMethods};
16951717
/// use pyo3::Python;
16961718
///
16971719
/// Python::with_gil(|py| {
16981720
/// let pyarray_f = PyArray::arange(py, 2.0, 5.0, 1.0);
1699-
/// let pyarray_i = unsafe { PyArray::<i64, _>::new(py, [3], false) };
1721+
/// let pyarray_i = unsafe { PyArray::<i64, _>::new_bound(py, [3], false) };
17001722
///
1701-
/// assert!(pyarray_f.copy_to(pyarray_i).is_ok());
1723+
/// assert!(pyarray_f.copy_to(pyarray_i.as_gil_ref()).is_ok());
17021724
///
17031725
/// assert_eq!(pyarray_i.readonly().as_slice().unwrap(), &[2, 3, 4]);
17041726
/// });

src/convert.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{mem, os::raw::c_int, ptr};
55
use ndarray::{ArrayBase, Data, Dim, Dimension, IntoDimension, Ix1, OwnedRepr};
66
use pyo3::Python;
77

8-
use crate::array::PyArray;
8+
use crate::array::{PyArray, PyArrayMethods};
99
use crate::dtype::Element;
1010
use crate::error::MAX_DIMENSIONALITY_ERR;
1111
use crate::npyffi::{self, npy_intp};
@@ -57,7 +57,9 @@ impl<T: Element> IntoPyArray for Box<[T]> {
5757
// to avoid unsound aliasing of Box<[T]> which is currently noalias,
5858
// c.f. https://github.com/rust-lang/unsafe-code-guidelines/issues/326
5959
let data_ptr = container.ptr as *mut T;
60-
unsafe { PyArray::from_raw_parts(py, dims, strides.as_ptr(), data_ptr, container) }
60+
unsafe {
61+
PyArray::from_raw_parts(py, dims, strides.as_ptr(), data_ptr, container).into_gil_ref()
62+
}
6163
}
6264
}
6365

@@ -77,6 +79,7 @@ impl<T: Element> IntoPyArray for Vec<T> {
7779
data_ptr,
7880
PySliceContainer::from(self),
7981
)
82+
.into_gil_ref()
8083
}
8184
}
8285
}
@@ -163,20 +166,20 @@ where
163166
unsafe {
164167
let array = PyArray::new_uninit(py, self.raw_dim(), strides.as_ptr(), flag);
165168
ptr::copy_nonoverlapping(self.as_ptr(), array.data(), len);
166-
array
169+
array.into_gil_ref()
167170
}
168171
}
169172
_ => {
170173
// if the array is not contiguous, copy all elements by `ArrayBase::iter`.
171174
let dim = self.raw_dim();
172175
unsafe {
173-
let array = PyArray::<A, _>::new(py, dim, false);
176+
let array = PyArray::<A, _>::new_bound(py, dim, false);
174177
let mut data_ptr = array.data();
175178
for item in self.iter() {
176179
data_ptr.write(item.clone());
177180
data_ptr = data_ptr.add(1);
178181
}
179-
array
182+
array.into_gil_ref()
180183
}
181184
}
182185
}
@@ -200,7 +203,7 @@ where
200203
/// [memory-layout]: https://nalgebra.org/docs/faq/#what-is-the-memory-layout-of-matrices
201204
fn to_pyarray<'py>(&self, py: Python<'py>) -> &'py PyArray<Self::Item, Self::Dim> {
202205
unsafe {
203-
let array = PyArray::<N, _>::new(py, (self.nrows(), self.ncols()), true);
206+
let array = PyArray::<N, _>::new_bound(py, (self.nrows(), self.ncols()), true);
204207
let mut data_ptr = array.data();
205208
if self.data.is_contiguous() {
206209
ptr::copy_nonoverlapping(self.data.ptr(), data_ptr, self.len());
@@ -210,7 +213,7 @@ where
210213
data_ptr = data_ptr.add(1);
211214
}
212215
}
213-
array
216+
array.into_gil_ref()
214217
}
215218
}
216219
}

tests/array.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use half::{bf16, f16};
55
use ndarray::{array, s, Array1, Dim};
66
use numpy::{
77
dtype_bound, get_array_module, npyffi::NPY_ORDER, pyarray, PyArray, PyArray1, PyArray2,
8-
PyArrayDescr, PyArrayDescrMethods, PyArrayDyn, PyFixedString, PyFixedUnicode,
8+
PyArrayDescr, PyArrayDescrMethods, PyArrayDyn, PyArrayMethods, PyFixedString, PyFixedUnicode,
99
PyUntypedArrayMethods, ToPyArray,
1010
};
1111
use pyo3::{
@@ -487,9 +487,9 @@ fn to_owned_works() {
487487
fn copy_to_works() {
488488
Python::with_gil(|py| {
489489
let arr1 = PyArray::arange(py, 2.0, 5.0, 1.0);
490-
let arr2 = unsafe { PyArray::<i64, _>::new(py, [3], false) };
490+
let arr2 = unsafe { PyArray::<i64, _>::new_bound(py, [3], false) };
491491

492-
arr1.copy_to(arr2).unwrap();
492+
arr1.copy_to(arr2.as_gil_ref()).unwrap();
493493

494494
assert_eq!(arr2.readonly().as_slice().unwrap(), &[2, 3, 4]);
495495
});

0 commit comments

Comments
 (0)