File tree Expand file tree Collapse file tree 2 files changed +33
-2
lines changed Expand file tree Collapse file tree 2 files changed +33
-2
lines changed Original file line number Diff line number Diff line change @@ -179,8 +179,9 @@ impl DataType {
179179///
180180/// A type `T` that implements this trait should be safe when managed in numpy array,
181181/// thus implementing this trait is marked unsafe.
182- /// For example, we don't support `PyObject` because of [an odd segfault](https://github.com/PyO3/rust-numpy/pull/143),
183- /// although numpy itself supports it.
182+ /// This means that all data types except for `DataType::Object` are assumed to be trivially copyable.
183+ /// Furthermore, it is assumed that for `DataType::Object` the elements are pointers into the Python heap
184+ /// and that the corresponding `Clone` implemenation will never panic as it only increases the reference count.
184185pub unsafe trait Element : Clone + Send {
185186 /// `DataType` corresponding to this type.
186187 const DATA_TYPE : DataType ;
@@ -246,3 +247,10 @@ cfg_if! {
246247 impl_num_element!( u64 , Uint64 , NPY_ULONG , NPY_ULONGLONG ) ;
247248 }
248249}
250+
251+ unsafe impl Element for PyObject {
252+ const DATA_TYPE : DataType = DataType :: Object ;
253+ fn is_same_type ( dtype : & PyArrayDescr ) -> bool {
254+ dtype. get_typenum ( ) == NPY_TYPES :: NPY_OBJECT as i32
255+ }
256+ }
Original file line number Diff line number Diff line change @@ -169,3 +169,26 @@ fn forder_into_pyarray() {
169169 pyo3:: py_run!( py, fmat_py, "assert fmat_py.flags['F_CONTIGUOUS']" )
170170 } )
171171}
172+
173+ #[ test]
174+ fn to_pyarray_object_vec ( ) {
175+ use pyo3:: {
176+ types:: { PyDict , PyString } ,
177+ ToPyObject ,
178+ } ;
179+ use std:: cmp:: Ordering ;
180+
181+ pyo3:: Python :: with_gil ( |py| {
182+ let dict = PyDict :: new ( py) ;
183+ let string = PyString :: new ( py, "Hello:)" ) ;
184+ let vec = vec ! [ dict. to_object( py) , string. to_object( py) ] ;
185+ let arr = vec. to_pyarray ( py) . readonly ( ) ;
186+
187+ for ( a, b) in vec. iter ( ) . zip ( arr. as_slice ( ) . unwrap ( ) . iter ( ) ) {
188+ assert_eq ! (
189+ a. as_ref( py) . compare( b) . map_err( |e| e. print( py) ) . unwrap( ) ,
190+ Ordering :: Equal
191+ ) ;
192+ }
193+ } )
194+ }
You can’t perform that action at this time.
0 commit comments