Skip to content

Commit 4aea3f2

Browse files
author
y-p
committed
ENH/CLN: redo pprint_warts merge, rebased PR lost the show
1 parent 1e2b447 commit 4aea3f2

File tree

4 files changed

+69
-54
lines changed

4 files changed

+69
-54
lines changed

pandas/core/common.py

+30-23
Original file line numberDiff line numberDiff line change
@@ -1858,7 +1858,7 @@ def _pprint_seq(seq, _nest_lvl=0, **kwds):
18581858
return fmt % body
18591859

18601860

1861-
def _pprint_dict(seq, _nest_lvl=0):
1861+
def _pprint_dict(seq, _nest_lvl=0,**kwds):
18621862
"""
18631863
internal. pprinter for iterables. you should probably use pprint_thing()
18641864
rather then calling this directly.
@@ -1871,15 +1871,17 @@ def _pprint_dict(seq, _nest_lvl=0):
18711871
nitems = get_option("max_seq_items") or len(seq)
18721872

18731873
for k, v in seq.items()[:nitems]:
1874-
pairs.append(pfmt % (pprint_thing(k,_nest_lvl+1), pprint_thing(v,_nest_lvl+1)))
1874+
pairs.append(pfmt % (pprint_thing(k,_nest_lvl+1,**kwds),
1875+
pprint_thing(v,_nest_lvl+1,**kwds)))
18751876

18761877
if nitems < len(seq):
18771878
return fmt % (", ".join(pairs) + ", ...")
18781879
else:
18791880
return fmt % ", ".join(pairs)
18801881

18811882

1882-
def pprint_thing(thing, _nest_lvl=0, escape_chars=None, default_escapes=False):
1883+
def pprint_thing(thing, _nest_lvl=0, escape_chars=None, default_escapes=False,
1884+
quote_strings=False):
18831885
"""
18841886
This function is the sanctioned way of converting objects
18851887
to a unicode representation.
@@ -1904,26 +1906,10 @@ def pprint_thing(thing, _nest_lvl=0, escape_chars=None, default_escapes=False):
19041906
result - unicode object on py2, str on py3. Always Unicode.
19051907
19061908
"""
1907-
1908-
if thing is None:
1909-
result = ''
1910-
elif (py3compat.PY3 and hasattr(thing, '__next__')) or \
1911-
hasattr(thing, 'next'):
1912-
return unicode(thing)
1913-
elif (isinstance(thing, dict) and
1914-
_nest_lvl < get_option("display.pprint_nest_depth")):
1915-
result = _pprint_dict(thing, _nest_lvl)
1916-
elif _is_sequence(thing) and _nest_lvl < \
1917-
get_option("display.pprint_nest_depth"):
1918-
result = _pprint_seq(thing, _nest_lvl, escape_chars=escape_chars)
1919-
else:
1920-
# when used internally in the package, everything
1921-
# should be unicode text. However as an aid to transition
1922-
# we also accept utf8 encoded strings,
1923-
# if that's not it either, we have no way of knowing,
1924-
# and the user should deal with it himself.
1925-
# we resort to utf-8 with replacing errors, rather then throwing
1926-
# an exception.
1909+
def as_escaped_unicode(thing,escape_chars=escape_chars):
1910+
# Unicode is fine, else we try to decode using utf-8 and 'replace'
1911+
# if that's not it either, we have no way of knowing and the user
1912+
#should deal with it himself.
19271913

19281914
try:
19291915
result = unicode(thing) # we should try this first
@@ -1946,6 +1932,27 @@ def pprint_thing(thing, _nest_lvl=0, escape_chars=None, default_escapes=False):
19461932
for c in escape_chars:
19471933
result = result.replace(c, translate[c])
19481934

1935+
return unicode(result)
1936+
1937+
if (py3compat.PY3 and hasattr(thing, '__next__')) or \
1938+
hasattr(thing, 'next'):
1939+
return unicode(thing)
1940+
elif (isinstance(thing, dict) and
1941+
_nest_lvl < get_option("display.pprint_nest_depth")):
1942+
result = _pprint_dict(thing, _nest_lvl,quote_strings=True)
1943+
elif _is_sequence(thing) and _nest_lvl < \
1944+
get_option("display.pprint_nest_depth"):
1945+
result = _pprint_seq(thing, _nest_lvl, escape_chars=escape_chars,
1946+
quote_strings=quote_strings)
1947+
elif isinstance(thing,basestring) and quote_strings:
1948+
if py3compat.PY3:
1949+
fmt = "'%s'"
1950+
else:
1951+
fmt = "u'%s'"
1952+
result = fmt % as_escaped_unicode(thing)
1953+
else:
1954+
result = as_escaped_unicode(thing)
1955+
19491956
return unicode(result) # always unicode
19501957

19511958

pandas/core/index.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def __unicode__(self):
175175
else:
176176
data = self.format()
177177

178-
prepr = com.pprint_thing(data, escape_chars=('\t', '\r', '\n'))
178+
prepr = com.pprint_thing(data, escape_chars=('\t', '\r', '\n'),quote_strings=True)
179179
return '%s(%s, dtype=%s)' % (type(self).__name__, prepr, self.dtype)
180180

181181
def __repr__(self):
@@ -1506,7 +1506,8 @@ def __unicode__(self):
15061506
else:
15071507
values = self.format()
15081508

1509-
summary = com.pprint_thing(values, escape_chars=('\t', '\r', '\n'))
1509+
summary = com.pprint_thing(values, escape_chars=('\t', '\r', '\n'),
1510+
quote_strings=True)
15101511

15111512
np.set_printoptions(threshold=options['threshold'])
15121513

pandas/tests/test_common.py

-24
Original file line numberDiff line numberDiff line change
@@ -288,30 +288,6 @@ def test_ensure_platform_int():
288288
# expected = u"\u05d0".encode('utf-8')
289289
# assert (result == expected)
290290

291-
292-
def test_pprint_thing():
293-
if py3compat.PY3:
294-
raise nose.SkipTest
295-
296-
pp_t = com.pprint_thing
297-
298-
assert(pp_t('a') == u'a')
299-
assert(pp_t(u'a') == u'a')
300-
assert(pp_t(None) == '')
301-
assert(pp_t(u'\u05d0') == u'\u05d0')
302-
assert(pp_t((u'\u05d0', u'\u05d1')) == u'(\u05d0, \u05d1)')
303-
assert(pp_t((u'\u05d0', (u'\u05d1', u'\u05d2'))) ==
304-
u'(\u05d0, (\u05d1, \u05d2))')
305-
assert(pp_t(('foo', u'\u05d0', (u'\u05d0', u'\u05d0'))) ==
306-
u'(foo, \u05d0, (\u05d0, \u05d0))')
307-
308-
# escape embedded tabs in string
309-
# GH #2038
310-
assert not "\t" in pp_t("a\tb", escape_chars=("\t",))
311-
312-
assert(pp_t((1,)) == u'(1,)')
313-
assert("set" in pp_t(set([1,2,3]))) # it works
314-
315291
class TestTake(unittest.TestCase):
316292

317293
_multiprocess_can_split_ = True

pandas/tests/test_format.py

+36-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
import numpy as np
1717

1818
from pandas import DataFrame, Series, Index
19-
from pandas.util.py3compat import lzip
19+
from pandas.util.py3compat import lzip, PY3
20+
2021
import pandas.core.format as fmt
2122
import pandas.util.testing as tm
2223
from pandas.util.terminal import get_terminal_size
@@ -136,6 +137,14 @@ def test_repr_obeys_max_seq_limit(self):
136137
with option_context("display.max_seq_items",5):
137138
self.assertTrue(len(com.pprint_thing(range(1000)))< 100)
138139

140+
def test_repr_is_valid_construction_code(self):
141+
import pandas as pd
142+
143+
# for the case of Index, where the repr is traditional rather then stylized
144+
idx = pd.Index(['a','b'])
145+
res = eval("pd."+repr(idx))
146+
tm.assert_series_equal(Series(res),Series(idx))
147+
139148
def test_repr_should_return_str(self):
140149
# http://docs.python.org/py3k/reference/datamodel.html#object.__repr__
141150
# http://docs.python.org/reference/datamodel.html#object.__repr__
@@ -540,7 +549,7 @@ def test_to_html_index_formatter(self):
540549
<tr style="text-align: right;">
541550
<th></th>
542551
<th>foo</th>
543-
<th></th>
552+
<th>None</th>
544553
</tr>
545554
</thead>
546555
<tbody>
@@ -637,6 +646,29 @@ def test_setting(value, nrows=3, ncols=2):
637646
test_setting(3)
638647
self.assertRaises(ValueError, test_setting, 'string')
639648

649+
def test_pprint_thing(self):
650+
import nose
651+
from pandas.core.common import pprint_thing as pp_t
652+
653+
if PY3:
654+
raise nose.SkipTest()
655+
656+
self.assertEquals(pp_t('a') , u'a')
657+
self.assertEquals(pp_t(u'a') , u'a')
658+
self.assertEquals(pp_t(None) , 'None')
659+
self.assertEquals(pp_t(u'\u05d0',quote_strings=True) , u"u'\u05d0'")
660+
self.assertEquals(pp_t(u'\u05d0',quote_strings=False) , u'\u05d0')
661+
self.assertEquals(pp_t((u'\u05d0', u'\u05d1'),quote_strings=True) ,
662+
u"(u'\u05d0', u'\u05d1')")
663+
self.assertEquals(pp_t((u'\u05d0', (u'\u05d1', u'\u05d2')),quote_strings=True) ,
664+
u"(u'\u05d0', (u'\u05d1', u'\u05d2'))")
665+
self.assertEquals(pp_t(('foo', u'\u05d0', (u'\u05d0', u'\u05d0')),quote_strings=True)
666+
, u"(u'foo', u'\u05d0', (u'\u05d0', u'\u05d0'))")
667+
668+
# escape embedded tabs in string
669+
# GH #2038
670+
self.assertTrue(not "\t" in pp_t("a\tb", escape_chars=("\t",)))
671+
640672
def test_wide_repr(self):
641673
with option_context('mode.sim_interactive', True):
642674
col = lambda l, k: [tm.rands(k) for _ in xrange(l)]
@@ -1316,9 +1348,8 @@ def test_dict_entries(self):
13161348
df = DataFrame({'A': [{'a': 1, 'b': 2}]})
13171349

13181350
val = df.to_string()
1319-
# to be fixed ot 'a': 1 when #3038 comes to town
1320-
self.assertTrue("a: 1" in val)
1321-
self.assertTrue("b: 2" in val)
1351+
self.assertTrue("'a': 1" in val)
1352+
self.assertTrue("'b': 2" in val)
13221353

13231354
def test_to_latex(self):
13241355
# it works!

0 commit comments

Comments
 (0)