@@ -10,7 +10,7 @@ use std::{cell::Cell, mem, os::raw::c_int, ptr, slice};
1010use std:: { iter:: ExactSizeIterator , marker:: PhantomData } ;
1111
1212use crate :: convert:: { IntoPyArray , NpyIndex , ToNpyDims , ToPyArray } ;
13- use crate :: dtype:: Element ;
13+ use crate :: dtype:: { DataType , Element } ;
1414use crate :: error:: { FromVecError , NotContiguousError , ShapeError } ;
1515use crate :: slice_box:: SliceBox ;
1616
@@ -731,8 +731,17 @@ impl<T: Element> PyArray<T, Ix1> {
731731 /// ```
732732 pub fn from_slice < ' py > ( py : Python < ' py > , slice : & [ T ] ) -> & ' py Self {
733733 let array = PyArray :: new ( py, [ slice. len ( ) ] , false ) ;
734- unsafe {
735- array. copy_ptr ( slice. as_ptr ( ) , slice. len ( ) ) ;
734+ if T :: DATA_TYPE != DataType :: Object {
735+ unsafe {
736+ array. copy_ptr ( slice. as_ptr ( ) , slice. len ( ) ) ;
737+ }
738+ } else {
739+ unsafe {
740+ let data_ptr = array. data ( ) ;
741+ for ( i, item) in slice. iter ( ) . enumerate ( ) {
742+ data_ptr. add ( i) . write ( item. clone ( ) ) ;
743+ }
744+ }
736745 }
737746 array
738747 }
@@ -767,7 +776,14 @@ impl<T: Element> PyArray<T, Ix1> {
767776 /// });
768777 /// ```
769778 pub fn from_exact_iter ( py : Python < ' _ > , iter : impl ExactSizeIterator < Item = T > ) -> & Self {
770- let array = Self :: new ( py, [ iter. len ( ) ] , false ) ;
779+ // Use zero-initialized pointers for object arrays
780+ // so that partially initialized arrays can be dropped safely
781+ // in case the iterator implementation panics.
782+ let array = if T :: DATA_TYPE == DataType :: Object {
783+ Self :: zeros ( py, [ iter. len ( ) ] , false )
784+ } else {
785+ Self :: new ( py, [ iter. len ( ) ] , false )
786+ } ;
771787 unsafe {
772788 for ( i, item) in iter. enumerate ( ) {
773789 * array. uget_mut ( [ i] ) = item;
@@ -795,7 +811,14 @@ impl<T: Element> PyArray<T, Ix1> {
795811 let iter = iter. into_iter ( ) ;
796812 let ( min_len, max_len) = iter. size_hint ( ) ;
797813 let mut capacity = max_len. unwrap_or_else ( || min_len. max ( 512 / mem:: size_of :: < T > ( ) ) ) ;
798- let array = Self :: new ( py, [ capacity] , false ) ;
814+ // Use zero-initialized pointers for object arrays
815+ // so that partially initialized arrays can be dropped safely
816+ // in case the iterator implementation panics.
817+ let array = if T :: DATA_TYPE == DataType :: Object {
818+ Self :: zeros ( py, [ capacity] , false )
819+ } else {
820+ Self :: new ( py, [ capacity] , false )
821+ } ;
799822 let mut length = 0 ;
800823 unsafe {
801824 for ( i, item) in iter. enumerate ( ) {
0 commit comments