@@ -59,15 +59,13 @@ impl<T> PyArray<T> {
59
59
}
60
60
61
61
/// Constructs `PyArray` from raw python object without incrementing reference counts.
62
- pub unsafe fn from_owned_ptr ( py : Python , ptr : * mut pyo3:: ffi:: PyObject ) -> Self {
63
- let obj = PyObject :: from_owned_ptr ( py, ptr) ;
64
- PyArray ( obj, PhantomData )
62
+ pub unsafe fn from_owned_ptr ( py : Python , ptr : * mut pyo3:: ffi:: PyObject ) -> & Self {
63
+ py. from_owned_ptr ( ptr)
65
64
}
66
65
67
66
/// Constructs PyArray from raw python object and increments reference counts.
68
- pub unsafe fn from_borrowed_ptr ( py : Python , ptr : * mut pyo3:: ffi:: PyObject ) -> Self {
69
- let obj = PyObject :: from_borrowed_ptr ( py, ptr) ;
70
- PyArray ( obj, PhantomData )
67
+ pub unsafe fn from_borrowed_ptr ( py : Python , ptr : * mut pyo3:: ffi:: PyObject ) -> & Self {
68
+ py. from_owned_ptr ( ptr)
71
69
}
72
70
73
71
/// Returns the number of dimensions in the array.
@@ -162,7 +160,7 @@ impl<T: TypeNum> PyArray<T> {
162
160
/// assert_eq!(pyarray.as_slice().unwrap(), &[1, 2, 3, 4, 5]);
163
161
/// # }
164
162
/// ```
165
- pub fn from_boxed_slice ( py : Python , v : Box < [ T ] > ) -> PyArray < T > {
163
+ pub fn from_boxed_slice ( py : Python , v : Box < [ T ] > ) -> & Self {
166
164
IntoPyArray :: into_pyarray ( v, py)
167
165
}
168
166
@@ -180,7 +178,7 @@ impl<T: TypeNum> PyArray<T> {
180
178
/// assert_eq!(pyarray.as_slice().unwrap(), &[1, 2, 3, 4, 5]);
181
179
/// # }
182
180
/// ```
183
- pub fn from_iter ( py : Python , i : impl IntoIterator < Item = T > ) -> PyArray < T > {
181
+ pub fn from_iter ( py : Python , i : impl IntoIterator < Item = T > ) -> & Self {
184
182
i. into_iter ( ) . collect :: < Vec < _ > > ( ) . into_pyarray ( py)
185
183
}
186
184
@@ -196,7 +194,7 @@ impl<T: TypeNum> PyArray<T> {
196
194
/// assert_eq!(pyarray.as_slice().unwrap(), &[1, 2, 3, 4, 5]);
197
195
/// # }
198
196
/// ```
199
- pub fn from_vec ( py : Python , v : Vec < T > ) -> PyArray < T > {
197
+ pub fn from_vec ( py : Python , v : Vec < T > ) -> & Self {
200
198
IntoPyArray :: into_pyarray ( v, py)
201
199
}
202
200
@@ -217,7 +215,7 @@ impl<T: TypeNum> PyArray<T> {
217
215
/// assert!(PyArray::from_vec2(gil.python(), &np, &vec![vec![1], vec![2, 3]]).is_err());
218
216
/// # }
219
217
/// ```
220
- pub fn from_vec2 ( py : Python , v : & Vec < Vec < T > > ) -> Result < PyArray < T > , ArrayCastError > {
218
+ pub fn from_vec2 < ' py > ( py : Python < ' py > , v : & Vec < Vec < T > > ) -> Result < & ' py Self , ArrayCastError > {
221
219
let last_len = v. last ( ) . map_or ( 0 , |v| v. len ( ) ) ;
222
220
if v. iter ( ) . any ( |v| v. len ( ) != last_len) {
223
221
return Err ( ArrayCastError :: FromVec ) ;
@@ -250,7 +248,10 @@ impl<T: TypeNum> PyArray<T> {
250
248
/// assert!(PyArray::from_vec3(gil.python(), &np, &vec![vec![vec![1], vec![]]]).is_err());
251
249
/// # }
252
250
/// ```
253
- pub fn from_vec3 ( py : Python , v : & Vec < Vec < Vec < T > > > ) -> Result < PyArray < T > , ArrayCastError > {
251
+ pub fn from_vec3 < ' py > (
252
+ py : Python < ' py > ,
253
+ v : & Vec < Vec < Vec < T > > > ,
254
+ ) -> Result < & ' py PyArray < T > , ArrayCastError > {
254
255
let dim2 = v. last ( ) . map_or ( 0 , |v| v. len ( ) ) ;
255
256
if v. iter ( ) . any ( |v| v. len ( ) != dim2) {
256
257
return Err ( ArrayCastError :: FromVec ) ;
@@ -279,7 +280,7 @@ impl<T: TypeNum> PyArray<T> {
279
280
/// assert_eq!(pyarray.as_array().unwrap(), array![[1, 2], [3, 4]].into_dyn());
280
281
/// # }
281
282
/// ```
282
- pub fn from_ndarray < D > ( py : Python , arr : Array < T , D > ) -> PyArray < T >
283
+ pub fn from_ndarray < D > ( py : Python , arr : Array < T , D > ) -> & Self
283
284
where
284
285
D : Dimension ,
285
286
{
@@ -356,12 +357,12 @@ impl<T: TypeNum> PyArray<T> {
356
357
/// Construct a new PyArray given a raw pointer and dimensions.
357
358
///
358
359
/// Please use `new` or from methods instead.
359
- pub unsafe fn new_ (
360
- py : Python ,
360
+ pub unsafe fn new_ < ' py > (
361
+ py : Python < ' py > ,
361
362
dims : & [ usize ] ,
362
363
strides : * mut npy_intp ,
363
364
data : * mut c_void ,
364
- ) -> Self {
365
+ ) -> & ' py Self {
365
366
let dims: Vec < _ > = dims. iter ( ) . map ( |d| * d as npy_intp ) . collect ( ) ;
366
367
let ptr = PyArrayAPI . PyArray_New (
367
368
PyArrayAPI . get_type_object ( npyffi:: ArrayType :: PyArray_Type ) ,
@@ -391,7 +392,7 @@ impl<T: TypeNum> PyArray<T> {
391
392
/// assert_eq!(pyarray.shape(), &[4, 5, 6]);
392
393
/// # }
393
394
/// ```
394
- pub fn new ( py : Python , dims : & [ usize ] ) -> Self {
395
+ pub fn new < ' py > ( py : Python < ' py > , dims : & [ usize ] ) -> & ' py Self {
395
396
unsafe { Self :: new_ ( py, dims, null_mut ( ) , null_mut ( ) ) }
396
397
}
397
398
@@ -410,7 +411,7 @@ impl<T: TypeNum> PyArray<T> {
410
411
/// assert_eq!(pyarray.as_array().unwrap(), array![[0, 0], [0, 0]].into_dyn());
411
412
/// # }
412
413
/// ```
413
- pub fn zeros ( py : Python , dims : & [ usize ] , is_fortran : bool ) -> Self {
414
+ pub fn zeros < ' py > ( py : Python < ' py > , dims : & [ usize ] , is_fortran : bool ) -> & ' py Self {
414
415
let dims: Vec < npy_intp > = dims. iter ( ) . map ( |d| * d as npy_intp ) . collect ( ) ;
415
416
unsafe {
416
417
let descr = PyArrayAPI . PyArray_DescrFromType ( T :: typenum_default ( ) ) ;
@@ -440,7 +441,7 @@ impl<T: TypeNum> PyArray<T> {
440
441
/// let pyarray = PyArray::<i32>::arange(gil.python(), &np, -2.0, 4.0, 3.0);
441
442
/// assert_eq!(pyarray.as_slice().unwrap(), &[-2, 1]);
442
443
/// # }
443
- pub fn arange ( py : Python , start : f64 , stop : f64 , step : f64 ) -> Self {
444
+ pub fn arange < ' py > ( py : Python < ' py > , start : f64 , stop : f64 , step : f64 ) -> & ' py Self {
444
445
unsafe {
445
446
let ptr = PyArrayAPI . PyArray_Arange ( start, stop, step, T :: typenum_default ( ) ) ;
446
447
Self :: from_owned_ptr ( py, ptr)
@@ -473,6 +474,32 @@ impl<T: TypeNum> PyArray<T> {
473
474
}
474
475
}
475
476
477
+ /// Move the data of self into `other`, performing a data-type conversion if necessary.
478
+ /// # Example
479
+ /// ```
480
+ /// # extern crate pyo3; extern crate numpy; fn main() {
481
+ /// use numpy::{PyArray, PyArrayModule, IntoPyArray};
482
+ /// let gil = pyo3::Python::acquire_gil();
483
+ /// let np = PyArrayModule::import(gil.python()).unwrap();
484
+ /// let pyarray_f = PyArray::<f64>::arange(gil.python(), &np, 2.0, 5.0, 1.0);
485
+ /// let mut pyarray_i = PyArray::<i64>::new(gil.python(), &np, &[3]);
486
+ /// assert!(pyarray_f.move_to(&np, &mut pyarray_i).is_ok());
487
+ /// assert_eq!(pyarray_i.as_slice().unwrap(), &[2, 3, 4]);
488
+ /// # }
489
+ pub fn move_to < U : TypeNum > ( & self , other : & mut PyArray < U > ) -> Result < ( ) , ArrayCastError > {
490
+ let self_ptr = self . as_array_ptr ( ) ;
491
+ let other_ptr = other. as_array_ptr ( ) ;
492
+ let result = unsafe { PyArrayAPI . PyArray_MoveInto ( other_ptr, self_ptr) } ;
493
+ if result == -1 {
494
+ Err ( ArrayCastError :: Numpy {
495
+ from : T :: npy_data_type ( ) ,
496
+ to : U :: npy_data_type ( ) ,
497
+ } )
498
+ } else {
499
+ Ok ( ( ) )
500
+ }
501
+ }
502
+
476
503
/// Cast the `PyArray<T>` to `PyArray<U>`, by allocating a new array.
477
504
/// # Example
478
505
/// ```
@@ -484,11 +511,11 @@ impl<T: TypeNum> PyArray<T> {
484
511
/// let pyarray_i = pyarray_f.cast::<i32>(gil.python(), &np, false).unwrap();
485
512
/// assert_eq!(pyarray_i.as_slice().unwrap(), &[2, 3, 4]);
486
513
/// # }
487
- pub fn cast < U : TypeNum > (
514
+ pub fn cast < ' py , U : TypeNum > (
488
515
& self ,
489
- py : Python ,
516
+ py : Python < ' py > ,
490
517
is_fortran : bool ,
491
- ) -> Result < PyArray < U > , ArrayCastError > {
518
+ ) -> Result < & ' py PyArray < U > , ArrayCastError > {
492
519
let ptr = unsafe {
493
520
let descr = PyArrayAPI . PyArray_DescrFromType ( U :: typenum_default ( ) ) ;
494
521
PyArrayAPI . PyArray_CastToType (
0 commit comments