Skip to content

Commit 420655d

Browse files
committed
Merge pull request #168 from shoyer/fix-pickle
Fix pickle for Dataset objects
2 parents 75f5f93 + 306c6d8 commit 420655d

File tree

2 files changed

+16
-15
lines changed

2 files changed

+16
-15
lines changed

test/test_dataset.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,8 @@ def test_pickle(self):
651651
data = create_test_data()
652652
roundtripped = pickle.loads(pickle.dumps(data))
653653
self.assertDatasetIdentical(data, roundtripped)
654+
# regression test for #167:
655+
self.assertEqual(data.dimensions, roundtripped.dimensions)
654656

655657
def test_lazy_load(self):
656658
store = InaccessibleVariableDataStore()

xray/utils.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,18 @@ def ordered_dict_intersection(first_dict, second_dict, compat=equivalent):
215215
return new_dict
216216

217217

218-
class Frozen(Mapping):
218+
class SingleSlotPickleMixin(object):
219+
"""Mixin class to add the ability to pickle objects whose state is defined
220+
by a single __slots__ attribute. Only necessary under Python 2.
221+
"""
222+
def __getstate__(self):
223+
return getattr(self, self.__slots__[0])
224+
225+
def __setstate__(self, state):
226+
setattr(self, self.__slots__[0], state)
227+
228+
229+
class Frozen(Mapping, SingleSlotPickleMixin):
219230
"""Wrapper around an object implementing the mapping interface to make it
220231
immutable. If you really want to modify the mapping, the mutable version is
221232
saved under the `mapping` attribute.
@@ -240,16 +251,12 @@ def __contains__(self, key):
240251
def __repr__(self):
241252
return '%s(%r)' % (type(self).__name__, self.mapping)
242253

243-
if not PY3:
244-
def __getstate__(self):
245-
return self.__dict__
246-
247254

248255
def FrozenOrderedDict(*args, **kwargs):
249256
return Frozen(OrderedDict(*args, **kwargs))
250257

251258

252-
class SortedKeysDict(MutableMapping):
259+
class SortedKeysDict(MutableMapping, SingleSlotPickleMixin):
253260
"""An wrapper for dictionary-like objects that always iterates over its
254261
items in sorted order by key but is otherwise equivalent to the underlying
255262
mapping.
@@ -283,12 +290,8 @@ def __repr__(self):
283290
def copy(self):
284291
return type(self)(self.mapping.copy())
285292

286-
if not PY3:
287-
def __getstate__(self):
288-
return self.__dict__
289-
290293

291-
class ChainMap(MutableMapping):
294+
class ChainMap(MutableMapping, SingleSlotPickleMixin):
292295
"""Partial backport of collections.ChainMap from Python>=3.3
293296
294297
Don't return this from any public APIs, since some of the public methods
@@ -319,10 +322,6 @@ def __iter__(self):
319322
def __len__(self):
320323
raise NotImplementedError
321324

322-
if not PY3:
323-
def __getstate__(self):
324-
return self.__dict__
325-
326325

327326
class NDArrayMixin(object):
328327
"""Mixin class for making wrappers of N-dimensional arrays that conform to

0 commit comments

Comments
 (0)