Skip to content

Commit

Permalink
Inject display into builtins
Browse files Browse the repository at this point in the history
display is an underutilized feature of IPython which is relatively hard
to access to. You need to explicitly import from `IPython.display`,
which not only is long to type, but users get confused if they should
use `IPython.display` or `IPython.display.display` also many tutorials
tell users to import from IPython.core.display which is not right.

So inject that directly in builtin module – so that user can overwrite
and delete without issues – and document display a lot more.
  • Loading branch information
Carreau committed May 25, 2017
1 parent 0217dcd commit 4e5fd23
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 3 deletions.
99 changes: 96 additions & 3 deletions IPython/core/display.py
Expand Up @@ -145,6 +145,9 @@ def display(*objs, include=None, exclude=None, metadata=None, transient=None, di
By default all representations will be computed and sent to the frontends.
Frontends can decide which representation is used and how.
In terminal IPython this will be similar to using `print`, for use in richer
frontends see Jupyter notebook examples with rich display logic.
Parameters
----------
objs : tuple of objects
Expand Down Expand Up @@ -173,19 +176,109 @@ def display(*objs, include=None, exclude=None, metadata=None, transient=None, di
If given as True, generate a new display_id
kwargs: additional keyword-args, optional
Additional keyword-arguments are passed through to the display publisher.
Returns
-------
handle: DisplayHandle
Returns a handle on updatable displays, if display_id is given.
Returns None if no display_id is given (default).
Examples
--------
>>> class Json(object):
... def __init__(self, json):
... self.json = json
... def _repr_pretty_(self, pp, cycle):
... import json
... pp.text(json.dumps(self.json, indent=2))
... def __repr__(self):
... return str(self.json)
...
>>> d = Json({1:2, 3: {4:5}})
>>> print(d)
{1: 2, 3: {4: 5}}
>>> display(d)
{
"1": 2,
"3": {
"4": 5
}
}
>>> def int_formatter(integer, pp, cycle):
... pp.text('I'*integer)
>>> plain = get_ipython().display_formatter.formatters['text/plain']
>>> plain.for_type(int, int_formatter)
<function _repr_pprint at 0x...>
>>> display(7-5)
II
>>> del plain.type_printers[int]
>>> display(7-5)
2
See Also
--------
`update_display`
Notes
-----
In Python, objects can declare their textual representation using the
`__repr__` method. IPython expands on this idea and allows objects to declare
other, rich representations including:
- HTML
- JSON
- PNG
- JPEG
- SVG
- LaTeX
A single object can declare some or all of these representations; all are
handled by IPython's display system.
The main idea of the first approach is that you have to implement special
display methods when you define your class, one for each representation you
want to use. Here is a list of the names of the special methods and the
values they must return:
- `_repr_html_`: return raw HTML as a string
- `_repr_json_`: return a JSONable dict
- `_repr_jpeg_`: return raw JPEG data
- `_repr_png_`: return raw PNG data
- `_repr_svg_`: return raw SVG data as a string
- `_repr_latex_`: return LaTeX commands in a string surrounded by "$".
- `_repr_mimebundle_`: return a full mimebundle containing the mapping
from all mimetypes to data
When you are directly writing your own classes, you can adapt them for
display in IPython by following the above approach. But in practice, you
often need to work with existing classes that you can't easily modify.
You can refer to the documentation on IPython display formatters in order to
register custom formatters for already existing types.
Since IPython 5.4 and 6.1 display is automatically made available to the
user without import. If you are using display in a document that might be
used in a pure python context or with older version of IPython use the
following import at the top of your file::
from IPython.display import display
"""
raw = kwargs.pop('raw', False)
if transient is None:
transient = {}
if display_id:
if display_id == True:
if display_id is True:
display_id = _new_id()
transient['display_id'] = display_id
if kwargs.get('update') and 'display_id' not in transient:
Expand Down
2 changes: 2 additions & 0 deletions IPython/core/interactiveshell.py
Expand Up @@ -56,6 +56,7 @@
from IPython.core.prefilter import PrefilterManager
from IPython.core.profiledir import ProfileDir
from IPython.core.usage import default_banner
from IPython.display import display
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils import PyColorize
from IPython.utils import io
Expand Down Expand Up @@ -618,6 +619,7 @@ def init_builtins(self):
# removing on exit or representing the existence of more than one
# IPython at a time.
builtin_mod.__dict__['__IPYTHON__'] = True
builtin_mod.__dict__['display'] = display

self.builtin_trap = BuiltinTrap(shell=self)

Expand Down

0 comments on commit 4e5fd23

Please sign in to comment.