<commit_before>"""
Definition and registration of display hooks for the IPython Notebook.
"""
from functools import wraps
import sys, traceback, inspect, io

import IPython
from IPython.core.ultratb import AutoFormattedTB

from ..core.options import Store, StoreOptions, BackendError
from ..core import (ViewableElement, UniformNdMapping,
                    HoloMap, AdjointLayout, NdLayout, GridSpace, Layout,
                    CompositeOverlay, DynamicMap)
from ..core.traversal import unique_dimkeys
from .magics import OutputMagic, OptsMagic

from .archive import notebook_archive
# To assist with debugging of display hooks
FULL_TRACEBACK = None
ABBREVIATE_TRACEBACKS = True

#==================#
# Helper functions #
#==================#

def sanitize_HTML(obj):
    "Sanitize text output for HTML display"
    return repr(obj).replace('\n', '<br>').replace(' ', '&nbsp;')

def max_frame_warning(max_frames):
    sys.stderr.write("Skipping regular visual display to avoid "
                     "lengthy animation render times\n"
                     "[Total item frames exceeds max_frames on OutputMagic (%d)]"
                     % max_frames)

def process_object(obj):
    "Hook to process the object currently being displayed."
    invalid_options = OptsMagic.process_element(obj)
    if invalid_options: return invalid_options
    OutputMagic.info(obj)


def render(obj, **kwargs):
    info = process_object(obj)
    if info: return info

    if render_anim is not None:
        return render_anim(obj)

    backend = Store.current_backend
    return Store.renderers[backend].html(obj, **kwargs)


def single_frame_plot(obj):
    """
    Returns plot, renderer and format for single frame export.
    """
    obj = Layout.from_values(obj) if isinstance(obj, AdjointLayout) else obj

    backend = Store.current_backend
    renderer = Store.renderers[backend]

    plot_cls = renderer.plotting_class(obj)
    plot = plot_cls(obj, **renderer.plot_options(obj, renderer.size))
    fmt = renderer.params('fig').objects[0] if renderer.fig == 'auto' else renderer.fig
    return plot, renderer, fmt


def first_frame(obj):
    "Only display the first frame of an animated plot"
    plot, renderer, fmt = single_frame_plot(obj)
    plot.update(0)
    return renderer.html(plot, fmt)

def middle_frame(obj):
    "Only display the (approximately) middle frame of an animated plot"
    plot, renderer, fmt = single_frame_plot(obj)
    middle_frame = int(len(plot) / 2)
    plot.update(middle_frame)
    return renderer.html(plot, fmt)

def last_frame(obj):
    "Only display the last frame of an animated plot"
    plot, renderer, fmt = single_frame_plot(obj)
    plot.update(len(plot))
    return renderer.html(plot, fmt)

#===============#
# Display hooks #
#===============#


def display_hook(fn):
    @wraps(fn)
    def wrapped(element):
        global FULL_TRACEBACK
        optstate = StoreOptions.state(element)
        try:
            html = fn(element,
                      max_frames=OutputMagic.options['max_frames'],
                      max_branches = OutputMagic.options['max_branches'])

            # Only want to add to the archive for one display hook...
            disabled_suffixes = ['png_display', 'svg_display']
            if not any(fn.__name__.endswith(suffix) for suffix in disabled_suffixes):
                notebook_archive.add(element, html=html)
            filename = OutputMagic.options['filename']
            if filename:
                Store.renderers[Store.current_backend].save(element, filename)

            return html
        except Exception as e:
            StoreOptions.state(element, state=optstate)
            frame = inspect.trace()[-1]
            mod = inspect.getmodule(frame[0])
            module = (mod.__name__ if mod else frame[1]).split('.')[0]
            backends = Store.renderers.keys()
            abbreviate =  isinstance(e, BackendError) or module in backends
            if ABBREVIATE_TRACEBACKS and abbreviate:
                AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
                buff = io.StringIO()
                AutoTB(out=buff)
                buff.seek(0)
                FULL_TRACEBACK = buff.read()
                info = dict(name=type(e).__name__,
                            message=str(e).replace('\n','<br>'))
                msg ='<i> [Call ipython.show_traceback() for details]</i>'
                return "<b>{name}</b>{msg}<br>{message}".format(msg=msg, **info)
            else:
                traceback.print_exc()
    return wrapped


@display_hook
def element_display(element, max_frames, max_branches):
    info = process_object(element)
    if info: return info
<commit_msg>Made the traceback printing system more robust to internal errors<commit_after>"""
Definition and registration of display hooks for the IPython Notebook.
"""
from functools import wraps
import sys, traceback, inspect, io

import IPython
from IPython.core.ultratb import AutoFormattedTB

from ..core.options import Store, StoreOptions, BackendError
from ..core import (ViewableElement, UniformNdMapping,
                    HoloMap, AdjointLayout, NdLayout, GridSpace, Layout,
                    CompositeOverlay, DynamicMap)
from ..core.traversal import unique_dimkeys
from .magics import OutputMagic, OptsMagic

from .archive import notebook_archive
# To assist with debugging of display hooks
FULL_TRACEBACK = None
ABBREVIATE_TRACEBACKS = True

#==================#
# Helper functions #
#==================#

def sanitize_HTML(obj):
    "Sanitize text output for HTML display"
    return repr(obj).replace('\n', '<br>').replace(' ', '&nbsp;')

def max_frame_warning(max_frames):
    sys.stderr.write("Skipping regular visual display to avoid "
                     "lengthy animation render times\n"
                     "[Total item frames exceeds max_frames on OutputMagic (%d)]"
                     % max_frames)

def process_object(obj):
    "Hook to process the object currently being displayed."
    invalid_options = OptsMagic.process_element(obj)
    if invalid_options: return invalid_options
    OutputMagic.info(obj)


def render(obj, **kwargs):
    info = process_object(obj)
    if info: return info

    if render_anim is not None:
        return render_anim(obj)

    backend = Store.current_backend
    return Store.renderers[backend].html(obj, **kwargs)


def single_frame_plot(obj):
    """
    Returns plot, renderer and format for single frame export.
    """
    obj = Layout.from_values(obj) if isinstance(obj, AdjointLayout) else obj

    backend = Store.current_backend
    renderer = Store.renderers[backend]

    plot_cls = renderer.plotting_class(obj)
    plot = plot_cls(obj, **renderer.plot_options(obj, renderer.size))
    fmt = renderer.params('fig').objects[0] if renderer.fig == 'auto' else renderer.fig
    return plot, renderer, fmt


def first_frame(obj):
    "Only display the first frame of an animated plot"
    plot, renderer, fmt = single_frame_plot(obj)
    plot.update(0)
    return renderer.html(plot, fmt)

def middle_frame(obj):
    "Only display the (approximately) middle frame of an animated plot"
    plot, renderer, fmt = single_frame_plot(obj)
    middle_frame = int(len(plot) / 2)
    plot.update(middle_frame)
    return renderer.html(plot, fmt)

def last_frame(obj):
    "Only display the last frame of an animated plot"
    plot, renderer, fmt = single_frame_plot(obj)
    plot.update(len(plot))
    return renderer.html(plot, fmt)

#===============#
# Display hooks #
#===============#


def display_hook(fn):
    @wraps(fn)
    def wrapped(element):
        global FULL_TRACEBACK
        optstate = StoreOptions.state(element)
        try:
            html = fn(element,
                      max_frames=OutputMagic.options['max_frames'],
                      max_branches = OutputMagic.options['max_branches'])

            # Only want to add to the archive for one display hook...
            disabled_suffixes = ['png_display', 'svg_display']
            if not any(fn.__name__.endswith(suffix) for suffix in disabled_suffixes):
                notebook_archive.add(element, html=html)
            filename = OutputMagic.options['filename']
            if filename:
                Store.renderers[Store.current_backend].save(element, filename)

            return html
        except Exception as e:
            try:
                StoreOptions.state(element, state=optstate)
                frame = inspect.trace()[-1]
                mod = inspect.getmodule(frame[0])
                module = (mod.__name__ if mod else frame[1]).split('.')[0]
                backends = Store.renderers.keys()
                abbreviate =  isinstance(e, BackendError) or module in backends
                if ABBREVIATE_TRACEBACKS and abbreviate:
                    AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
                    buff = io.StringIO()
                    AutoTB(out=buff)
                    buff.seek(0)
                    FULL_TRACEBACK = buff.read()
                    info = dict(name=type(e).__name__,
                                message=str(e).replace('\n','<br>'))
                    msg ='<i> [Call ipython.show_traceback() for details]</i>'
                    return "<b>{name}</b>{msg}<br>{message}".format(msg=msg, **info)
                else:
                    traceback.print_exc()
            except:
                FULL_TRACEBACK = traceback.format_exc()
                msg = ('<i>Error catching exception:</i> %r <br>'
                       'Call ipython.show_traceback() for details')
                return msg % e

    return wrapped


@display_hook
def element_display(element, max_frames, max_branches):
    info = process_object(element)
    if info: return info

{'fraction_non_alphanumeric': 0.1108728943338438, 'fraction_numerical': 0.001633486472690148, 'mean_word_length': 2.662056074766355, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5982013', 'n_tokens_mistral': 2850, 'n_tokens_neox': 2717, 'n_words': 734}