Skip to content

Commit 11e68de

Browse files
TomAugspurgerchris
authored and
chris
committed
BUG: Restore return value in notebook reprs (pandas-dev#16171)
* BUG: Restore return value in notebook reprs Monkey patches the _ipython_display_ method onto NDFrame, so that notebook cells have a real return value. Setting the display.html.table_schema will monkey patch the method on, and remove it when unset. closes ipython/ipython#10491 * Define in generic.py * PEP8
1 parent 80403c6 commit 11e68de

File tree

3 files changed

+75
-26
lines changed

3 files changed

+75
-26
lines changed

pandas/core/config_init.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,21 @@ def mpl_style_cb(key):
340340
return val
341341

342342

343+
def table_schema_cb(key):
344+
# Having _ipython_display_ defined messes with the return value
345+
# from cells, so the Out[x] dictionary breaks.
346+
# Currently table schema is the only thing using it, so we'll
347+
# monkey patch `_ipython_display_` onto NDFrame when config option
348+
# is set
349+
# see https://github.com/pandas-dev/pandas/issues/16168
350+
from pandas.core.generic import NDFrame, _ipython_display_
351+
352+
if cf.get_option(key):
353+
NDFrame._ipython_display_ = _ipython_display_
354+
elif getattr(NDFrame, '_ipython_display_', None):
355+
del NDFrame._ipython_display_
356+
357+
343358
with cf.config_prefix('display'):
344359
cf.register_option('precision', 6, pc_precision_doc, validator=is_int)
345360
cf.register_option('float_format', None, float_format_doc,
@@ -407,7 +422,7 @@ def mpl_style_cb(key):
407422
cf.register_option('latex.multirow', False, pc_latex_multirow,
408423
validator=is_bool)
409424
cf.register_option('html.table_schema', False, pc_table_schema_doc,
410-
validator=is_bool)
425+
validator=is_bool, cb=table_schema_cb)
411426

412427

413428
cf.deprecate_option('display.line_width',

pandas/core/generic.py

+32-25
Original file line numberDiff line numberDiff line change
@@ -130,31 +130,6 @@ def __init__(self, data, axes=None, copy=False, dtype=None,
130130
object.__setattr__(self, '_data', data)
131131
object.__setattr__(self, '_item_cache', {})
132132

133-
def _ipython_display_(self):
134-
try:
135-
from IPython.display import display
136-
except ImportError:
137-
return None
138-
139-
# Series doesn't define _repr_html_ or _repr_latex_
140-
latex = self._repr_latex_() if hasattr(self, '_repr_latex_') else None
141-
html = self._repr_html_() if hasattr(self, '_repr_html_') else None
142-
try:
143-
table_schema = self._repr_table_schema_()
144-
except Exception as e:
145-
warnings.warn("Cannot create table schema representation. "
146-
"{}".format(e), UnserializableWarning)
147-
table_schema = None
148-
# We need the inital newline since we aren't going through the
149-
# usual __repr__. See
150-
# https://github.com/pandas-dev/pandas/pull/14904#issuecomment-277829277
151-
text = "\n" + repr(self)
152-
153-
reprs = {"text/plain": text, "text/html": html, "text/latex": latex,
154-
"application/vnd.dataresource+json": table_schema}
155-
reprs = {k: v for k, v in reprs.items() if v}
156-
display(reprs, raw=True)
157-
158133
def _repr_table_schema_(self):
159134
"""
160135
Not a real Jupyter special repr method, but we use the same
@@ -6283,6 +6258,38 @@ def logical_func(self, axis=None, bool_only=None, skipna=None, level=None,
62836258
return set_function_name(logical_func, name, cls)
62846259

62856260

6261+
def _ipython_display_(self):
6262+
# Having _ipython_display_ defined messes with the return value
6263+
# from cells, so the Out[x] dictionary breaks.
6264+
# Currently table schema is the only thing using it, so we'll
6265+
# monkey patch `_ipython_display_` onto NDFrame when config option
6266+
# is set
6267+
# see https://github.com/pandas-dev/pandas/issues/16168
6268+
try:
6269+
from IPython.display import display
6270+
except ImportError:
6271+
return None
6272+
6273+
# Series doesn't define _repr_html_ or _repr_latex_
6274+
latex = self._repr_latex_() if hasattr(self, '_repr_latex_') else None
6275+
html = self._repr_html_() if hasattr(self, '_repr_html_') else None
6276+
try:
6277+
table_schema = self._repr_table_schema_()
6278+
except Exception as e:
6279+
warnings.warn("Cannot create table schema representation. "
6280+
"{}".format(e), UnserializableWarning)
6281+
table_schema = None
6282+
# We need the inital newline since we aren't going through the
6283+
# usual __repr__. See
6284+
# https://github.com/pandas-dev/pandas/pull/14904#issuecomment-277829277
6285+
text = "\n" + repr(self)
6286+
6287+
reprs = {"text/plain": text, "text/html": html, "text/latex": latex,
6288+
"application/vnd.dataresource+json": table_schema}
6289+
reprs = {k: v for k, v in reprs.items() if v}
6290+
display(reprs, raw=True)
6291+
6292+
62866293
# install the indexes
62876294
for _name, _indexer in indexing.get_indexers_list():
62886295
NDFrame._create_indexer(_name, _indexer)

pandas/tests/io/formats/test_printing.py

+27
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,33 @@ def test_config_default_off(self):
203203

204204
assert result is None
205205

206+
def test_config_monkeypatches(self):
207+
# GH 10491
208+
df = pd.DataFrame({"A": [1, 2]})
209+
assert not hasattr(df, '_ipython_display_')
210+
assert not hasattr(df['A'], '_ipython_display_')
211+
212+
with pd.option_context('display.html.table_schema', True):
213+
assert hasattr(df, '_ipython_display_')
214+
# smoke test that it works
215+
df._ipython_display_()
216+
assert hasattr(df['A'], '_ipython_display_')
217+
df['A']._ipython_display_()
218+
219+
assert not hasattr(df, '_ipython_display_')
220+
assert not hasattr(df['A'], '_ipython_display_')
221+
# re-unsetting is OK
222+
assert not hasattr(df, '_ipython_display_')
223+
assert not hasattr(df['A'], '_ipython_display_')
224+
225+
# able to re-set
226+
with pd.option_context('display.html.table_schema', True):
227+
assert hasattr(df, '_ipython_display_')
228+
# smoke test that it works
229+
df._ipython_display_()
230+
assert hasattr(df['A'], '_ipython_display_')
231+
df['A']._ipython_display_()
232+
206233

207234
# TODO: fix this broken test
208235

0 commit comments

Comments
 (0)