Skip to content

Commit 2b2e15e

Browse files
committed
BUG: fix pickling on Timestamp, all tests pass
1 parent b526c85 commit 2b2e15e

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

pandas/core/index.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,13 +1150,13 @@ def __new__(cls, data=None,
11501150
periods=periods, offset=offset)
11511151

11521152
index = np.array(_dt_unbox_array(list(xdr)), dtype='M8[us]',
1153-
copy=False)
1153+
copy=False)
11541154

11551155
index = index.view(cls)
11561156
index.name = name
11571157
index.offset = offset
1158-
index.tzinfo = tzinfo
11591158
index.freq = freq
1159+
index.tzinfo = tzinfo
11601160

11611161
return index
11621162

@@ -1200,8 +1200,8 @@ def __new__(cls, data=None,
12001200
subarr = subarr.view(cls)
12011201
subarr.name = name
12021202
subarr.offset = offset
1203-
subarr.tzinfo = tzinfo
12041203
subarr.freq = freq
1204+
subarr.tzinfo = tzinfo
12051205

12061206
return subarr
12071207

@@ -1281,18 +1281,19 @@ def __repr__(self):
12811281
def __reduce__(self):
12821282
"""Necessary for making this object picklable"""
12831283
object_state = list(np.ndarray.__reduce__(self))
1284-
subclass_state = self.name, self.offset, self.freq
1284+
subclass_state = self.name, self.offset, self.freq, self.tzinfo
12851285
object_state[2] = (object_state[2], subclass_state)
12861286
return tuple(object_state)
12871287

12881288
def __setstate__(self, state):
12891289
"""Necessary for making this object picklable"""
12901290
if len(state) == 2:
12911291
nd_state, own_state = state
1292-
np.ndarray.__setstate__(self, nd_state)
12931292
self.name = own_state[0]
12941293
self.offset = own_state[1]
12951294
self.freq = own_state[2]
1295+
self.tzinfo = own_state[3]
1296+
np.ndarray.__setstate__(self, nd_state)
12961297
else: # pragma: no cover
12971298
np.ndarray.__setstate__(self, state)
12981299

@@ -1417,6 +1418,7 @@ def __array_finalize__(self, obj):
14171418
return self.item()
14181419

14191420
self.offset = getattr(obj, 'offset', None)
1421+
self.freq = getattr(obj, 'freq', None)
14201422
self.tzinfo = getattr(obj, 'tzinfo', None)
14211423

14221424
def intersection(self, other):
@@ -1464,14 +1466,22 @@ def __getitem__(self, key):
14641466
else:
14651467
return _dt_box(val, tzinfo=self.tzinfo)
14661468
else:
1469+
new_offset = self.offset
1470+
new_freq = self.freq
1471+
if (type(key) == slice and new_offset is not None
1472+
and key.step is not None):
1473+
new_offset = key.step * self.offset
1474+
new_freq = None
1475+
14671476
if com._is_bool_indexer(key):
14681477
key = np.asarray(key)
14691478

14701479
result = arr_idx[key]
14711480
if result.ndim > 1:
14721481
return result
14731482

1474-
return DatetimeIndex(result, name=self.name)
1483+
return DatetimeIndex(result, name=self.name, offset=new_offset,
1484+
freq=new_freq, tzinfo=self.tzinfo)
14751485

14761486
# Try to run function on index first, and then on elements of index
14771487
# Especially important for group-by functionality

pandas/src/datetime.pyx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ class Timestamp(_Timestamp):
5959

6060
return ts_base
6161

62+
def __setstate__(self, state):
63+
self.value = state[0]
64+
self.offset = state[1]
65+
self.tzinfo = state[2]
66+
67+
def __reduce__(self):
68+
object_state = self.value, self.offset, self.tzinfo
69+
return (Timestamp, object_state)
70+
71+
6272
# This is PITA. Because we inherit from datetime, which has very specific
6373
# construction requirements, we need to do object instantiation in python
6474
# (see Timestamp class above). This will serve as a C extension type that

pandas/tests/test_daterange.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ def test_union(self):
152152

153153
the_union = left.union(right)
154154
self.assert_(isinstance(the_union, Index))
155-
self.assert_(not isinstance(the_union, DateRange))
156155

157156
# non-overlapping, no gap
158157
left = self.rng[:5]
@@ -168,7 +167,7 @@ def test_union(self):
168167
rng = DateRange(START, END, offset=datetools.bmonthEnd)
169168

170169
the_union = self.rng.union(rng)
171-
self.assert_(not isinstance(the_union, DateRange))
170+
self.assert_(isinstance(the_union, DateRange))
172171

173172
def test_outer_join(self):
174173
""" should behave just as union test"""
@@ -228,7 +227,7 @@ def test_intersection(self):
228227

229228
# non-overlapping
230229
the_int = rng[:10].intersection(rng[10:])
231-
expected = DateRange([])
230+
expected = DatetimeIndex([])
232231
self.assert_(the_int.equals(expected))
233232

234233
def test_intersection_bug(self):

0 commit comments

Comments
 (0)