Skip to content

Commit 1fe9f7b

Browse files
committed
move tests to generically tests for index
generify __unicode__ for Index
1 parent 45697f4 commit 1fe9f7b

File tree

8 files changed

+193
-89
lines changed

8 files changed

+193
-89
lines changed

pandas/core/index.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -392,15 +392,35 @@ def __unicode__(self):
392392
Invoked by unicode(df) in py2 only. Yields a Unicode String in both
393393
py2/py3.
394394
"""
395-
prepr = com.pprint_thing(self, escape_chars=('\t', '\r', '\n'),
396-
quote_strings=True)
395+
klass = self.__class__.__name__
396+
space = ' ' * (len(klass) + 1)
397+
data = self._format_data()
398+
attrs = self._format_attrs()
399+
prepr = (u(",\n%s") % space).join([u("%s=%s") % (k, v)
400+
for k, v in attrs])
401+
res = u("%s(%s,\n%s%s)") % (klass,
402+
data,
403+
space,
404+
prepr)
405+
406+
return res
397407

398-
name_attr=''
399-
if self.name:
400-
name_attr = u(" %s=%s,") % ('name', self.name)
408+
def _format_data(self):
409+
"""
410+
Return the formatted data as a unicode string
411+
"""
412+
return com.pprint_thing(self, escape_chars=('\t', '\r', '\n'),
413+
quote_strings=True)
401414

402-
return "%s(%s,%s dtype='%s')" % (type(self).__name__,
403-
prepr, name_attr, self.dtype)
415+
def _format_attrs(self):
416+
"""
417+
Return a list of tuples of the (attr,formatted_value)
418+
"""
419+
attrs = []
420+
if self.name is not None:
421+
attrs.append(('name',default_pprint(self.name)))
422+
attrs.append(('dtype',"'%s'" % self.dtype))
423+
return attrs
404424

405425
def to_series(self, **kwargs):
406426
"""

pandas/tests/test_index.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ def test_ndarray_compat_properties(self):
120120
idx.nbytes
121121
idx.values.nbytes
122122

123+
def test_repr_roundtrip(self):
124+
125+
idx = self.create_index()
126+
tm.assert_index_equal(eval(repr(idx)),idx)
127+
128+
def test_str(self):
129+
130+
# test the string repr
131+
idx = self.create_index()
132+
idx.name = 'foo'
133+
self.assertTrue("'foo'" in str(idx))
134+
self.assertTrue(idx.__class__.__name__ in str(idx))
135+
123136
def test_wrong_number_names(self):
124137
def testit(ind):
125138
ind.names = ["apple", "banana", "carrot"]
@@ -2441,6 +2454,26 @@ def test_slice_keep_name(self):
24412454

24422455
class DatetimeLike(Base):
24432456

2457+
def test_repr_roundtrip(self):
2458+
raise nose.SkipTest("Short reprs are not supported repr for Datetimelike indexes")
2459+
2460+
def test_str(self):
2461+
2462+
# test the string repr
2463+
idx = self.create_index()
2464+
idx.name = 'foo'
2465+
self.assertTrue("length=%s" % len(idx) in str(idx))
2466+
self.assertTrue("u'foo'" in str(idx))
2467+
self.assertTrue(idx.__class__.__name__ in str(idx))
2468+
2469+
if hasattr(idx,'tz'):
2470+
if idx.tz is not None:
2471+
self.assertTrue("tz='%s'" % idx.tz in str(idx))
2472+
else:
2473+
self.assertTrue("tz=None" in str(idx))
2474+
if hasattr(idx,'freq'):
2475+
self.assertTrue("freq='%s'" % idx.freqstr in str(idx))
2476+
24442477
def test_view(self):
24452478
super(DatetimeLike, self).test_view()
24462479

@@ -4348,8 +4381,9 @@ def test_repr_with_unicode_data(self):
43484381
index = pd.DataFrame(d).set_index(["a", "b"]).index
43494382
self.assertFalse("\\u" in repr(index)) # we don't want unicode-escaped
43504383

4351-
def test_repr_roundtrip(self):
4352-
tm.assert_index_equal(eval(repr(self.index)), self.index)
4384+
def test_str(self):
4385+
# tested elsewhere
4386+
pass
43534387

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

pandas/tseries/base.py

Lines changed: 27 additions & 10 deletions
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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -684,10 +684,6 @@ def _format_native_types(self, na_rep=u('NaT'),
684684
def to_datetime(self, dayfirst=False):
685685
return self.copy()
686686

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

pandas/tseries/period.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 0 additions & 4 deletions
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

Lines changed: 102 additions & 57 deletions
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1620,7 +1620,7 @@ class _AssertRaisesContextmanager(object):
16201620
def __init__(self, exception, regexp=None, *args, **kwargs):
16211621
self.exception = exception
16221622
if regexp is not None and not hasattr(regexp, "search"):
1623-
regexp = re.compile(regexp)
1623+
regexp = re.compile(regexp, re.DOTALL)
16241624
self.regexp = regexp
16251625

16261626
def __enter__(self):

0 commit comments

Comments
 (0)