Skip to content

Commit 9ff163e

Browse files
committed
move tests to generically tests for index
generify __unicode__ for Index
1 parent bd9b2af commit 9ff163e

File tree

8 files changed

+193
-90
lines changed

8 files changed

+193
-90
lines changed

pandas/core/index.py

+27-7
Original file line numberDiff line numberDiff line change
@@ -410,15 +410,35 @@ def __unicode__(self):
410410
Invoked by unicode(df) in py2 only. Yields a Unicode String in both
411411
py2/py3.
412412
"""
413-
prepr = com.pprint_thing(self, escape_chars=('\t', '\r', '\n'),
414-
quote_strings=True)
413+
klass = self.__class__.__name__
414+
space = ' ' * (len(klass) + 1)
415+
data = self._format_data()
416+
attrs = self._format_attrs()
417+
prepr = (u(",\n%s") % space).join([u("%s=%s") % (k, v)
418+
for k, v in attrs])
419+
res = u("%s(%s,\n%s%s)") % (klass,
420+
data,
421+
space,
422+
prepr)
423+
424+
return res
415425

416-
name_attr=''
417-
if self.name:
418-
name_attr = u(" %s=%s,") % ('name', self.name)
426+
def _format_data(self):
427+
"""
428+
Return the formatted data as a unicode string
429+
"""
430+
return com.pprint_thing(self, escape_chars=('\t', '\r', '\n'),
431+
quote_strings=True)
419432

420-
return "%s(%s,%s dtype='%s')" % (type(self).__name__,
421-
prepr, name_attr, self.dtype)
433+
def _format_attrs(self):
434+
"""
435+
Return a list of tuples of the (attr,formatted_value)
436+
"""
437+
attrs = []
438+
if self.name is not None:
439+
attrs.append(('name',default_pprint(self.name)))
440+
attrs.append(('dtype',"'%s'" % self.dtype))
441+
return attrs
422442

423443
def to_series(self, **kwargs):
424444
"""

pandas/tests/test_index.py

+35-2
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@ def test_ndarray_compat_properties(self):
118118
idx.nbytes
119119
idx.values.nbytes
120120

121+
def test_repr_roundtrip(self):
122+
123+
idx = self.create_index()
124+
tm.assert_index_equal(eval(repr(idx)),idx)
125+
126+
def test_str(self):
127+
128+
# test the string repr
129+
idx = self.create_index()
130+
idx.name = 'foo'
131+
self.assertTrue("name=u'foo'" in str(idx))
132+
self.assertTrue(idx.__class__.__name__ in str(idx))
121133

122134
class TestIndex(Base, tm.TestCase):
123135
_holder = Index
@@ -2052,6 +2064,26 @@ def test_slice_keep_name(self):
20522064

20532065
class DatetimeLike(Base):
20542066

2067+
def test_repr_roundtrip(self):
2068+
raise nose.SkipTest("Short reprs are not supported repr for Datetimelike indexes")
2069+
2070+
def test_str(self):
2071+
2072+
# test the string repr
2073+
idx = self.create_index()
2074+
idx.name = 'foo'
2075+
self.assertTrue("length=%s" % len(idx) in str(idx))
2076+
self.assertTrue("name=u'foo'" in str(idx))
2077+
self.assertTrue(idx.__class__.__name__ in str(idx))
2078+
2079+
if hasattr(idx,'tz'):
2080+
if idx.tz is not None:
2081+
self.assertTrue("tz='%s'" % idx.tz in str(idx))
2082+
else:
2083+
self.assertTrue("tz=None" in str(idx))
2084+
if hasattr(idx,'freq'):
2085+
self.assertTrue("freq='%s'" % idx.freqstr in str(idx))
2086+
20552087
def test_view(self):
20562088

20572089
i = self.create_index()
@@ -3951,8 +3983,9 @@ def test_repr_with_unicode_data(self):
39513983
index = pd.DataFrame(d).set_index(["a", "b"]).index
39523984
self.assertFalse("\\u" in repr(index)) # we don't want unicode-escaped
39533985

3954-
def test_repr_roundtrip(self):
3955-
tm.assert_index_equal(eval(repr(self.index)), self.index)
3986+
def test_str(self):
3987+
# tested elsewhere
3988+
pass
39563989

39573990
def test_unicode_string_with_unicode(self):
39583991
d = {"a": [u("\u05d0"), 2, 3], "b": [4, 5, 6], "c": [7, 8, 9]}

pandas/tseries/base.py

+27-10
Original file line numberDiff line numberDiff line change
@@ -260,31 +260,48 @@ def _formatter_func(self):
260260
"""
261261
return str
262262

263-
def _format_footer(self):
264-
raise AbstractMethodError(self)
263+
def _format_data(self):
264+
"""
265+
Return the formatted data as a unicode string
266+
"""
265267

266-
def __unicode__(self):
267268
formatter = self._formatter_func
268-
summary = str(self.__class__) + '\n'
269-
270269
n = len(self)
271270
if n == 0:
272-
pass
271+
summary = '[]'
273272
elif n == 1:
274273
first = formatter(self[0])
275-
summary += '[%s]\n' % first
274+
summary = '[%s]' % first
276275
elif n == 2:
277276
first = formatter(self[0])
278277
last = formatter(self[-1])
279-
summary += '[%s, %s]\n' % (first, last)
278+
summary = '[%s, %s]' % (first, last)
280279
else:
281280
first = formatter(self[0])
282281
last = formatter(self[-1])
283-
summary += '[%s, ..., %s]\n' % (first, last)
282+
summary = '[%s, ..., %s]' % (first, last)
284283

285-
summary += self._format_footer()
286284
return summary
287285

286+
def _format_attrs(self):
287+
"""
288+
Return a list of tuples of the (attr,formatted_value)
289+
"""
290+
attrs = super(DatetimeIndexOpsMixin, self)._format_attrs()
291+
attrs.append(('length',len(self)))
292+
for attrib in self._attributes:
293+
if attrib == 'freq':
294+
freq = self.freqstr
295+
if freq is not None:
296+
freq = "'%s'" % freq
297+
attrs.append(('freq',freq))
298+
elif attrib == 'tz':
299+
tz = self.tz
300+
if tz is not None:
301+
tz = "'%s'" % tz
302+
attrs.append(('tz',tz))
303+
return attrs
304+
288305
@cache_readonly
289306
def _resolution(self):
290307
from pandas.tseries.frequencies import Resolution

pandas/tseries/index.py

-4
Original file line numberDiff line numberDiff line change
@@ -683,10 +683,6 @@ def _format_native_types(self, na_rep=u('NaT'),
683683
def to_datetime(self, dayfirst=False):
684684
return self.copy()
685685

686-
def _format_footer(self):
687-
tagline = 'Length: %d, Freq: %s, Timezone: %s'
688-
return tagline % (len(self), self.freqstr, self.tz)
689-
690686
def astype(self, dtype):
691687
dtype = np.dtype(dtype)
692688

pandas/tseries/period.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ def to_datetime(self, dayfirst=False):
387387
qyear = _field_accessor('qyear', 1)
388388
days_in_month = _field_accessor('days_in_month', 11, "The number of days in the month")
389389
daysinmonth = days_in_month
390-
390+
391391
def _get_object_array(self):
392392
freq = self.freq
393393
return np.array([ Period._from_ordinal(ordinal=x, freq=freq) for x in self.values], copy=False)
@@ -697,10 +697,6 @@ def __array_finalize__(self, obj):
697697
self.name = getattr(obj, 'name', None)
698698
self._reset_identity()
699699

700-
def _format_footer(self):
701-
tagline = 'Length: %d, Freq: %s'
702-
return tagline % (len(self), self.freqstr)
703-
704700
def take(self, indices, axis=None):
705701
"""
706702
Analogous to ndarray.take

pandas/tseries/tdi.py

-4
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,6 @@ def _formatter_func(self):
274274
from pandas.core.format import _get_format_timedelta64
275275
return _get_format_timedelta64(self, box=True)
276276

277-
def _format_footer(self):
278-
tagline = 'Length: %d, Freq: %s'
279-
return tagline % (len(self), self.freqstr)
280-
281277
def __setstate__(self, state):
282278
"""Necessary for making this object picklable"""
283279
if isinstance(state, dict):

pandas/tseries/tests/test_base.py

+102-57
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,41 @@ def test_representation(self):
119119
idx6 = DatetimeIndex(['2011-01-01 09:00', '2011-01-01 10:00', pd.NaT],
120120
tz='US/Eastern')
121121

122-
exp1 = """<class 'pandas.tseries.index.DatetimeIndex'>
123-
Length: 0, Freq: D, Timezone: None"""
124-
exp2 = """<class 'pandas.tseries.index.DatetimeIndex'>
125-
[2011-01-01]
126-
Length: 1, Freq: D, Timezone: None"""
127-
exp3 = """<class 'pandas.tseries.index.DatetimeIndex'>
128-
[2011-01-01, 2011-01-02]
129-
Length: 2, Freq: D, Timezone: None"""
130-
exp4 = """<class 'pandas.tseries.index.DatetimeIndex'>
131-
[2011-01-01, ..., 2011-01-03]
132-
Length: 3, Freq: D, Timezone: None"""
133-
exp5 = """<class 'pandas.tseries.index.DatetimeIndex'>
134-
[2011-01-01 09:00:00+09:00, ..., 2011-01-01 11:00:00+09:00]
135-
Length: 3, Freq: H, Timezone: Asia/Tokyo"""
136-
exp6 = """<class 'pandas.tseries.index.DatetimeIndex'>
137-
[2011-01-01 09:00:00-05:00, ..., NaT]
138-
Length: 3, Freq: None, Timezone: US/Eastern"""
122+
exp1 = """DatetimeIndex([],
123+
dtype='datetime64[ns]',
124+
length=0,
125+
freq='D',
126+
tz=None)"""
127+
128+
exp2 = """DatetimeIndex([2011-01-01],
129+
dtype='datetime64[ns]',
130+
length=1,
131+
freq='D',
132+
tz=None)"""
133+
134+
exp3 = """DatetimeIndex([2011-01-01, 2011-01-02],
135+
dtype='datetime64[ns]',
136+
length=2,
137+
freq='D',
138+
tz=None)"""
139+
140+
exp4 = """DatetimeIndex([2011-01-01, ..., 2011-01-03],
141+
dtype='datetime64[ns]',
142+
length=3,
143+
freq='D',
144+
tz=None)"""
145+
146+
exp5 = """DatetimeIndex([2011-01-01 09:00:00+09:00, ..., 2011-01-01 11:00:00+09:00],
147+
dtype='datetime64[ns]',
148+
length=3,
149+
freq='H',
150+
tz='Asia/Tokyo')"""
151+
152+
exp6 = """DatetimeIndex([2011-01-01 09:00:00-05:00, ..., NaT],
153+
dtype='datetime64[ns]',
154+
length=3,
155+
freq=None,
156+
tz='US/Eastern')"""
139157

140158
for idx, expected in zip([idx1, idx2, idx3, idx4, idx5, idx6],
141159
[exp1, exp2, exp3, exp4, exp5, exp6]):
@@ -372,21 +390,30 @@ def test_representation(self):
372390
idx4 = TimedeltaIndex(['1 days', '2 days', '3 days'], freq='D')
373391
idx5 = TimedeltaIndex(['1 days 00:00:01', '2 days', '3 days'])
374392

393+
exp1 = """TimedeltaIndex([],
394+
dtype='timedelta64[ns]',
395+
length=0,
396+
freq='D')"""
375397

376-
exp1 = """<class 'pandas.tseries.tdi.TimedeltaIndex'>
377-
Length: 0, Freq: D"""
378-
exp2 = """<class 'pandas.tseries.tdi.TimedeltaIndex'>
379-
['1 days']
380-
Length: 1, Freq: D"""
381-
exp3 = """<class 'pandas.tseries.tdi.TimedeltaIndex'>
382-
['1 days', '2 days']
383-
Length: 2, Freq: D"""
384-
exp4 = """<class 'pandas.tseries.tdi.TimedeltaIndex'>
385-
['1 days', ..., '3 days']
386-
Length: 3, Freq: D"""
387-
exp5 = """<class 'pandas.tseries.tdi.TimedeltaIndex'>
388-
['1 days 00:00:01', ..., '3 days 00:00:00']
389-
Length: 3, Freq: None"""
398+
exp2 = """TimedeltaIndex(['1 days'],
399+
dtype='timedelta64[ns]',
400+
length=1,
401+
freq='D')"""
402+
403+
exp3 = """TimedeltaIndex(['1 days', '2 days'],
404+
dtype='timedelta64[ns]',
405+
length=2,
406+
freq='D')"""
407+
408+
exp4 = """TimedeltaIndex(['1 days', ..., '3 days'],
409+
dtype='timedelta64[ns]',
410+
length=3,
411+
freq='D')"""
412+
413+
exp5 = """TimedeltaIndex(['1 days 00:00:01', ..., '3 days 00:00:00'],
414+
dtype='timedelta64[ns]',
415+
length=3,
416+
freq=None)"""
390417

391418
for idx, expected in zip([idx1, idx2, idx3, idx4, idx5],
392419
[exp1, exp2, exp3, exp4, exp5]):
@@ -835,32 +862,50 @@ def test_representation(self):
835862
idx8 = pd.period_range('2013Q1', periods=2, freq="Q")
836863
idx9 = pd.period_range('2013Q1', periods=3, freq="Q")
837864

838-
exp1 = """<class 'pandas.tseries.period.PeriodIndex'>
839-
Length: 0, Freq: D"""
840-
exp2 = """<class 'pandas.tseries.period.PeriodIndex'>
841-
[2011-01-01]
842-
Length: 1, Freq: D"""
843-
exp3 = """<class 'pandas.tseries.period.PeriodIndex'>
844-
[2011-01-01, 2011-01-02]
845-
Length: 2, Freq: D"""
846-
exp4 = """<class 'pandas.tseries.period.PeriodIndex'>
847-
[2011-01-01, ..., 2011-01-03]
848-
Length: 3, Freq: D"""
849-
exp5 = """<class 'pandas.tseries.period.PeriodIndex'>
850-
[2011, ..., 2013]
851-
Length: 3, Freq: A-DEC"""
852-
exp6 = """<class 'pandas.tseries.period.PeriodIndex'>
853-
[2011-01-01 09:00, ..., NaT]
854-
Length: 3, Freq: H"""
855-
exp7 = """<class 'pandas.tseries.period.PeriodIndex'>
856-
[2013Q1]
857-
Length: 1, Freq: Q-DEC"""
858-
exp8 = """<class 'pandas.tseries.period.PeriodIndex'>
859-
[2013Q1, 2013Q2]
860-
Length: 2, Freq: Q-DEC"""
861-
exp9 = """<class 'pandas.tseries.period.PeriodIndex'>
862-
[2013Q1, ..., 2013Q3]
863-
Length: 3, Freq: Q-DEC"""
865+
exp1 = """PeriodIndex([],
866+
dtype='int64',
867+
length=0,
868+
freq='D')"""
869+
870+
exp2 = """PeriodIndex([2011-01-01],
871+
dtype='int64',
872+
length=1,
873+
freq='D')"""
874+
875+
exp3 = """PeriodIndex([2011-01-01, 2011-01-02],
876+
dtype='int64',
877+
length=2,
878+
freq='D')"""
879+
880+
exp4 = """PeriodIndex([2011-01-01, ..., 2011-01-03],
881+
dtype='int64',
882+
length=3,
883+
freq='D')"""
884+
885+
exp5 = """PeriodIndex([2011, ..., 2013],
886+
dtype='int64',
887+
length=3,
888+
freq='A-DEC')"""
889+
890+
exp6 = """PeriodIndex([2011-01-01 09:00, ..., NaT],
891+
dtype='int64',
892+
length=3,
893+
freq='H')"""
894+
895+
exp7 = """PeriodIndex([2013Q1],
896+
dtype='int64',
897+
length=1,
898+
freq='Q-DEC')"""
899+
900+
exp8 = """PeriodIndex([2013Q1, 2013Q2],
901+
dtype='int64',
902+
length=2,
903+
freq='Q-DEC')"""
904+
905+
exp9 = """PeriodIndex([2013Q1, ..., 2013Q3],
906+
dtype='int64',
907+
length=3,
908+
freq='Q-DEC')"""
864909

865910
for idx, expected in zip([idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9],
866911
[exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, exp9]):

pandas/util/testing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1633,7 +1633,7 @@ class _AssertRaisesContextmanager(object):
16331633
def __init__(self, exception, regexp=None, *args, **kwargs):
16341634
self.exception = exception
16351635
if regexp is not None and not hasattr(regexp, "search"):
1636-
regexp = re.compile(regexp)
1636+
regexp = re.compile(regexp, re.DOTALL)
16371637
self.regexp = regexp
16381638

16391639
def __enter__(self):

0 commit comments

Comments
 (0)