/opt/imh-python/lib/python3.9/site-packages/IPython/core
Edit: /opt/imh-python/lib/python3.9/site-packages/IPython/core/display.py (42503B)
# -*- coding: utf-8 -*-
"""Top-level display functions for displaying object in different formats."""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
from binascii import b2a_base64, hexlify
import html
import json
import mimetypes
import os
import struct
import warnings
from copy import deepcopy
from os.path import splitext
from pathlib import Path, PurePath
from IPython.utils.py3compat import cast_unicode
from IPython.testing.skipdoctest import skip_doctest
from . import display_functions
__all__ = ['display_pretty', 'display_html', 'display_markdown',
'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'ProgressBar', 'JSON',
'GeoJSON', 'Javascript', 'Image', 'set_matplotlib_formats',
'set_matplotlib_close',
'Video']
_deprecated_names = ["display", "clear_output", "publish_display_data", "update_display", "DisplayHandle"]
__all__ = __all__ + _deprecated_names
# ----- warn to import from IPython.display -----
from warnings import warn
def __getattr__(name):
if name in _deprecated_names:
warn(f"Importing {name} from IPython.core.display is deprecated since IPython 7.14, please import from IPython display", DeprecationWarning, stacklevel=2)
return getattr(display_functions, name)
if name in globals().keys():
return globals()[name]
else:
raise AttributeError(f"module {__name__} has no attribute {name}")
#-----------------------------------------------------------------------------
# utility functions
#-----------------------------------------------------------------------------
def _safe_exists(path):
"""Check path, but don't let exceptions raise"""
try:
return os.path.exists(path)
except Exception:
return False
def _display_mimetype(mimetype, objs, raw=False, metadata=None):
"""internal implementation of all display_foo methods
Parameters
----------
mimetype : str
The mimetype to be published (e.g. 'image/png')
*objs : object
The Python objects to display, or if raw=True raw text data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
if metadata:
metadata = {mimetype: metadata}
if raw:
# turn list of pngdata into list of { 'image/png': pngdata }
objs = [ {mimetype: obj} for obj in objs ]
display_functions.display(*objs, raw=raw, metadata=metadata, include=[mimetype])
#-----------------------------------------------------------------------------
# Main functions
#-----------------------------------------------------------------------------
def display_pretty(*objs, **kwargs):
"""Display the pretty (default) representation of an object.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw text data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('text/plain', objs, **kwargs)
def display_html(*objs, **kwargs):
"""Display the HTML representation of an object.
Note: If raw=False and the object does not have a HTML
representation, no HTML will be shown.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw HTML data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('text/html', objs, **kwargs)
def display_markdown(*objs, **kwargs):
"""Displays the Markdown representation of an object.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw markdown data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('text/markdown', objs, **kwargs)
def display_svg(*objs, **kwargs):
"""Display the SVG representation of an object.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw svg data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('image/svg+xml', objs, **kwargs)
def display_png(*objs, **kwargs):
"""Display the PNG representation of an object.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw png data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('image/png', objs, **kwargs)
def display_jpeg(*objs, **kwargs):
"""Display the JPEG representation of an object.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw JPEG data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('image/jpeg', objs, **kwargs)
def display_latex(*objs, **kwargs):
"""Display the LaTeX representation of an object.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw latex data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('text/latex', objs, **kwargs)
def display_json(*objs, **kwargs):
"""Display the JSON representation of an object.
Note that not many frontends support displaying JSON.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw json data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('application/json', objs, **kwargs)
def display_javascript(*objs, **kwargs):
"""Display the Javascript representation of an object.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw javascript data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('application/javascript', objs, **kwargs)
def display_pdf(*objs, **kwargs):
"""Display the PDF representation of an object.
Parameters
----------
*objs : object
The Python objects to display, or if raw=True raw javascript data to
display.
raw : bool
Are the data objects raw data or Python objects that need to be
formatted before display? [default: False]
metadata : dict (optional)
Metadata to be associated with the specific mimetype output.
"""
_display_mimetype('application/pdf', objs, **kwargs)
#-----------------------------------------------------------------------------
# Smart classes
#-----------------------------------------------------------------------------
class DisplayObject(object):
"""An object that wraps data to be displayed."""
_read_flags = 'r'
_show_mem_addr = False
metadata = None
def __init__(self, data=None, url=None, filename=None, metadata=None):
"""Create a display object given raw data.
When this object is returned by an expression or passed to the
display function, it will result in the data being displayed
in the frontend. The MIME type of the data should match the
subclasses used, so the Png subclass should be used for 'image/png'
data. If the data is a URL, the data will first be downloaded
and then displayed.
Parameters
----------
data : unicode, str or bytes
The raw data or a URL or file to load the data from
url : unicode
A URL to download the data from.
filename : unicode
Path to a local file to load the data from.
metadata : dict
Dict of metadata associated to be the object when displayed
"""
if isinstance(data, (Path, PurePath)):
data = str(data)
if data is not None and isinstance(data, str):
if data.startswith('http') and url is None:
url = data
filename = None
data = None
elif _safe_exists(data) and filename is None:
url = None
filename = data
data = None
self.url = url
self.filename = filename
# because of @data.setter methods in
# subclasses ensure url and filename are set
# before assigning to self.data
self.data = data
if metadata is not None:
self.metadata = metadata
elif self.metadata is None:
self.metadata = {}
self.reload()
self._check_data()
def __repr__(self):
if not self._show_mem_addr:
cls = self.__class__
r = "<%s.%s object>" % (cls.__module__, cls.__name__)
else:
r = super(DisplayObject, self).__repr__()
return r
def _check_data(self):
"""Override in subclasses if there's something to check."""
pass
def _data_and_metadata(self):
"""shortcut for returning metadata with shape information, if defined"""
if self.metadata:
return self.data, deepcopy(self.metadata)
else:
return self.data
def reload(self):
"""Reload the raw data from file or URL."""
if self.filename is not None:
encoding = None if "b" in self._read_flags else "utf-8"
with open(self.filename, self._read_flags, encoding=encoding) as f:
self.data = f.read()
elif self.url is not None:
# Deferred import
from urllib.request import urlopen
response = urlopen(self.url)
data = response.read()
# extract encoding from header, if there is one:
encoding = None
if 'content-type' in response.headers:
for sub in response.headers['content-type'].split(';'):
sub = sub.strip()
if sub.startswith('charset'):
encoding = sub.split('=')[-1].strip()
break
if 'content-encoding' in response.headers:
# TODO: do deflate?
if 'gzip' in response.headers['content-encoding']:
import gzip
from io import BytesIO
# assume utf-8 if encoding is not specified
with gzip.open(
BytesIO(data), "rt", encoding=encoding or "utf-8"
) as fp:
encoding = None
data = fp.read()
# decode data, if an encoding was specified
# We only touch self.data once since
# subclasses such as SVG have @data.setter methods
# that transform self.data into ... well svg.
if encoding:
self.data = data.decode(encoding, 'replace')
else:
self.data = data
class TextDisplayObject(DisplayObject):
"""Create a text display object given raw data.
Parameters
----------
data : str or unicode
The raw data or a URL or file to load the data from.
url : unicode
A URL to download the data from.
filename : unicode
Path to a local file to load the data from.
metadata : dict
Dict of metadata associated to be the object when displayed
"""
def _check_data(self):
if self.data is not None and not isinstance(self.data, str):
raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
class Pretty(TextDisplayObject):
def _repr_pretty_(self, pp, cycle):
return pp.text(self.data)
class HTML(TextDisplayObject):
def __init__(self, data=None, url=None, filename=None, metadata=None):
def warn():
if not data:
return False
#
# Avoid calling lower() on the entire data, because it could be a
# long string and we're only interested in its beginning and end.
#
prefix = data[:10].lower()
suffix = data[-10:].lower()
return prefix.startswith("