diff --git a/IPython/parallel/tests/test_view.py b/IPython/parallel/tests/test_view.py index bb3625c..e1ff878 100644 --- a/IPython/parallel/tests/test_view.py +++ b/IPython/parallel/tests/test_view.py @@ -287,6 +287,21 @@ class TestView(ClusterTestCase): assert_array_equal(B,C) @skip_without('numpy') + def test_apply_numpy_object_dtype(self): + """view.apply(f, ndarray) with dtype=object""" + import numpy + from numpy.testing.utils import assert_array_equal + view = self.client[-1] + + A = numpy.array([dict(a=5)]) + B = view.apply_sync(lambda x:x, A) + assert_array_equal(A,B) + + A = numpy.array([(0, dict(b=10))], dtype=[('i', int), ('o', object)]) + B = view.apply_sync(lambda x:x, A) + assert_array_equal(A,B) + + @skip_without('numpy') def test_push_pull_recarray(self): """push/pull recarrays""" import numpy diff --git a/IPython/utils/pickleutil.py b/IPython/utils/pickleutil.py index 4b85a22..d3fed87 100644 --- a/IPython/utils/pickleutil.py +++ b/IPython/utils/pickleutil.py @@ -192,7 +192,15 @@ class CannedArray(CannedObject): from numpy import ascontiguousarray self.shape = obj.shape self.dtype = obj.dtype.descr if obj.dtype.fields else obj.dtype.str + self.pickled = False if sum(obj.shape) == 0: + self.pickled = True + elif obj.dtype == 'O': + # can't handle object dtype with buffer approach + self.pickled = True + elif obj.dtype.fields and any(dt == 'O' for dt,sz in obj.dtype.fields.values()): + self.pickled = True + if self.pickled: # just pickle it self.buffers = [pickle.dumps(obj, -1)] else: @@ -203,7 +211,7 @@ class CannedArray(CannedObject): def get_object(self, g=None): from numpy import frombuffer data = self.buffers[0] - if sum(self.shape) == 0: + if self.pickled: # no shape, we just pickled it return pickle.loads(data) else: