@@ -17,7 +17,7 @@ use std::{iter::ExactSizeIterator, marker::PhantomData};
1717use crate :: convert:: { ArrayExt , IntoPyArray , NpyIndex , ToNpyDims , ToPyArray } ;
1818use crate :: dtype:: { DataType , Element } ;
1919use crate :: error:: { FromVecError , NotContiguousError , ShapeError } ;
20- use crate :: slice_box :: SliceBox ;
20+ use crate :: slice_container :: PySliceContainer ;
2121
2222/// A safe, static-typed interface for
2323/// [NumPy ndarray](https://numpy.org/doc/stable/reference/arrays.ndarray.html).
@@ -432,53 +432,71 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
432432 PY_ARRAY_API . get_type_object ( npyffi:: NpyTypes :: PyArray_Type ) ,
433433 dims. ndim_cint ( ) ,
434434 dims. as_dims_ptr ( ) ,
435- T :: npy_type ( ) as i32 ,
436- strides as * mut _ , // strides
437- ptr:: null_mut ( ) , // data
438- 0 , // itemsize
439- flag, // flag
440- ptr:: null_mut ( ) , // obj
435+ T :: npy_type ( ) as c_int ,
436+ strides as * mut npy_intp , // strides
437+ ptr:: null_mut ( ) , // data
438+ 0 , // itemsize
439+ flag, // flag
440+ ptr:: null_mut ( ) , // obj
441441 ) ;
442442 Self :: from_owned_ptr ( py, ptr)
443443 }
444444
445- pub ( crate ) unsafe fn from_boxed_slice < ' py , ID > (
445+ unsafe fn new_with_data < ' py , ID > (
446446 py : Python < ' py > ,
447447 dims : ID ,
448448 strides : * const npy_intp ,
449- boxed_slice : Box < [ T ] > ,
450- data_ptr : Option < * const T > ,
449+ data_ptr : * const T ,
450+ container : * mut PyAny ,
451451 ) -> & ' py Self
452452 where
453453 ID : IntoDimension < Dim = D > ,
454454 {
455455 let dims = dims. into_dimension ( ) ;
456- let data_ptr = data_ptr. unwrap_or_else ( || boxed_slice. as_ptr ( ) ) ;
457- let container = SliceBox :: new ( boxed_slice) ;
458- let cell = pyo3:: PyClassInitializer :: from ( container)
459- . create_cell ( py)
460- . expect ( "Object creation failed." ) ;
461456 let ptr = PY_ARRAY_API . PyArray_New (
462457 PY_ARRAY_API . get_type_object ( npyffi:: NpyTypes :: PyArray_Type ) ,
463458 dims. ndim_cint ( ) ,
464459 dims. as_dims_ptr ( ) ,
465- T :: npy_type ( ) as i32 ,
466- strides as * mut _ , // strides
467- data_ptr as _ , // data
468- mem:: size_of :: < T > ( ) as i32 , // itemsize
469- npyffi:: NPY_ARRAY_WRITEABLE , // flag
470- ptr:: null_mut ( ) , // obj
460+ T :: npy_type ( ) as c_int ,
461+ strides as * mut npy_intp , // strides
462+ data_ptr as * mut c_void , // data
463+ mem:: size_of :: < T > ( ) as c_int , // itemsize
464+ npyffi:: NPY_ARRAY_WRITEABLE , // flag
465+ ptr:: null_mut ( ) , // obj
466+ ) ;
467+
468+ PY_ARRAY_API . PyArray_SetBaseObject (
469+ ptr as * mut npyffi:: PyArrayObject ,
470+ container as * mut ffi:: PyObject ,
471471 ) ;
472- PY_ARRAY_API . PyArray_SetBaseObject ( ptr as * mut npyffi :: PyArrayObject , cell as _ ) ;
472+
473473 Self :: from_owned_ptr ( py, ptr)
474474 }
475475
476- /// Creates a NumPy array backed by `array` and ties its ownership to the Python object `owner`.
476+ pub ( crate ) unsafe fn from_raw_parts < ' py , ID , C > (
477+ py : Python < ' py > ,
478+ dims : ID ,
479+ strides : * const npy_intp ,
480+ data_ptr : * const T ,
481+ container : C ,
482+ ) -> & ' py Self
483+ where
484+ ID : IntoDimension < Dim = D > ,
485+ PySliceContainer : From < C > ,
486+ {
487+ let container = pyo3:: PyClassInitializer :: from ( PySliceContainer :: from ( container) )
488+ . create_cell ( py)
489+ . expect ( "Object creation failed." ) ;
490+
491+ Self :: new_with_data ( py, dims, strides, data_ptr, container as * mut PyAny )
492+ }
493+
494+ /// Creates a NumPy array backed by `array` and ties its ownership to the Python object `container`.
477495 ///
478496 /// # Safety
479497 ///
480- /// `owner ` is set as a base object of the returned array which must not be dropped until `owner ` is dropped.
481- /// Furthermore, `array` must not be reallocated from the time this method is called and until `owner ` is dropped.
498+ /// `container ` is set as a base object of the returned array which must not be dropped until `container ` is dropped.
499+ /// Furthermore, `array` must not be reallocated from the time this method is called and until `container ` is dropped.
482500 ///
483501 /// # Example
484502 ///
@@ -503,33 +521,27 @@ impl<T: Element, D: Dimension> PyArray<T, D> {
503521 /// }
504522 /// }
505523 /// ```
506- pub unsafe fn borrow_from_array < ' py , S > ( array : & ArrayBase < S , D > , owner : & ' py PyAny ) -> & ' py Self
524+ pub unsafe fn borrow_from_array < ' py , S > (
525+ array : & ArrayBase < S , D > ,
526+ container : & ' py PyAny ,
527+ ) -> & ' py Self
507528 where
508529 S : Data < Elem = T > ,
509530 {
510531 let ( strides, dims) = ( array. npy_strides ( ) , array. raw_dim ( ) ) ;
511532 let data_ptr = array. as_ptr ( ) ;
512533
513- let ptr = PY_ARRAY_API . PyArray_New (
514- PY_ARRAY_API . get_type_object ( npyffi:: NpyTypes :: PyArray_Type ) ,
515- dims. ndim_cint ( ) ,
516- dims. as_dims_ptr ( ) ,
517- T :: npy_type ( ) as c_int ,
518- strides. as_ptr ( ) as * mut npy_intp , // strides
519- data_ptr as * mut c_void , // data
520- mem:: size_of :: < T > ( ) as c_int , // itemsize
521- 0 , // flag
522- ptr:: null_mut ( ) , // obj
523- ) ;
524-
525- mem:: forget ( owner. to_object ( owner. py ( ) ) ) ;
534+ let py = container. py ( ) ;
526535
527- PY_ARRAY_API . PyArray_SetBaseObject (
528- ptr as * mut npyffi:: PyArrayObject ,
529- owner as * const PyAny as * mut PyAny as * mut ffi:: PyObject ,
530- ) ;
536+ mem:: forget ( container. to_object ( py) ) ;
531537
532- Self :: from_owned_ptr ( owner. py ( ) , ptr)
538+ Self :: new_with_data (
539+ py,
540+ dims,
541+ strides. as_ptr ( ) ,
542+ data_ptr,
543+ container as * const PyAny as * mut PyAny ,
544+ )
533545 }
534546
535547 /// Construct a new nd-dimensional array filled with 0.
0 commit comments