Skip to content

Commit 8744104

Browse files
committed
move tests to generically tests for index
generify __unicode__ for Index
1 parent b085142 commit 8744104

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"]
@@ -2467,6 +2480,26 @@ def test_slice_keep_name(self):
24672480

24682481
class DatetimeLike(Base):
24692482

2483+
def test_repr_roundtrip(self):
2484+
raise nose.SkipTest("Short reprs are not supported repr for Datetimelike indexes")
2485+
2486+
def test_str(self):
2487+
2488+
# test the string repr
2489+
idx = self.create_index()
2490+
idx.name = 'foo'
2491+
self.assertTrue("length=%s" % len(idx) in str(idx))
2492+
self.assertTrue("u'foo'" in str(idx))
2493+
self.assertTrue(idx.__class__.__name__ in str(idx))
2494+
2495+
if hasattr(idx,'tz'):
2496+
if idx.tz is not None:
2497+
self.assertTrue("tz='%s'" % idx.tz in str(idx))
2498+
else:
2499+
self.assertTrue("tz=None" in str(idx))
2500+
if hasattr(idx,'freq'):
2501+
self.assertTrue("freq='%s'" % idx.freqstr in str(idx))
2502+
24702503
def test_view(self):
24712504
super(DatetimeLike, self).test_view()
24722505

@@ -4380,8 +4413,9 @@ def test_repr_with_unicode_data(self):
43804413
index = pd.DataFrame(d).set_index(["a", "b"]).index
43814414
self.assertFalse("\\u" in repr(index)) # we don't want unicode-escaped
43824415

4383-
def test_repr_roundtrip(self):
4384-
tm.assert_index_equal(eval(repr(self.index)), self.index)
4416+
def test_str(self):
4417+
# tested elsewhere
4418+
pass
43854419

43864420
def test_unicode_string_with_unicode(self):
43874421
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]):
@@ -842,32 +869,50 @@ def test_representation(self):
842869
idx8 = pd.period_range('2013Q1', periods=2, freq="Q")
843870
idx9 = pd.period_range('2013Q1', periods=3, freq="Q")
844871

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

872917
for idx, expected in zip([idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9],
873918
[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
@@ -1627,7 +1627,7 @@ class _AssertRaisesContextmanager(object):
16271627
def __init__(self, exception, regexp=None, *args, **kwargs):
16281628
self.exception = exception
16291629
if regexp is not None and not hasattr(regexp, "search"):
1630-
regexp = re.compile(regexp)
1630+
regexp = re.compile(regexp, re.DOTALL)
16311631
self.regexp = regexp
16321632

16331633
def __enter__(self):

0 commit comments

Comments
 (0)