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 {
179
179
///
180
180
/// A type `T` that implements this trait should be safe when managed in numpy array,
181
181
/// 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.
184
185
pub unsafe trait Element : Clone + Send {
185
186
/// `DataType` corresponding to this type.
186
187
const DATA_TYPE : DataType ;
@@ -246,3 +247,10 @@ cfg_if! {
246
247
impl_num_element!( u64 , Uint64 , NPY_ULONG , NPY_ULONGLONG ) ;
247
248
}
248
249
}
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() {
169
169
pyo3:: py_run!( py, fmat_py, "assert fmat_py.flags['F_CONTIGUOUS']" )
170
170
} )
171
171
}
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