예제 #1
0
def inspect_frames(frames):
    for fi in frames:
        if isinstance(fi, ex.FrameInfo):
            yield fi
        elif isinstance(fi, types.FrameType):
            yield ex.get_info(fi)
        else:
            raise ValueError("Expected a frame or a FrameInfo tuple, got %r" % fi)
예제 #2
0
def format_stack(frames,
                 style='plaintext',
                 source_lines=5,
                 show_signature=True,
                 show_vals='like_source',
                 truncate_vals=500,
                 line_wrap=60,
                 reverse=False,
                 suppressed_paths=None):
    """
    Render a list of frames (or FrameInfo tuples)

    keyword args like stackprinter.format()
    """

    min_src_lines = 0 if source_lines == 0 else 1

    minimal_formatter = get_formatter(style=style,
                                      source_lines=min_src_lines,
                                      show_signature=False,
                                      show_vals=False)

    reduced_formatter = get_formatter(style=style,
                                      source_lines=min_src_lines,
                                      show_signature=show_signature,
                                      show_vals=show_vals,
                                      truncate_vals=truncate_vals,
                                      line_wrap=line_wrap,
                                      suppressed_paths=suppressed_paths)

    verbose_formatter = get_formatter(style=style,
                                      source_lines=source_lines,
                                      show_signature=show_signature,
                                      show_vals=show_vals,
                                      truncate_vals=truncate_vals,
                                      line_wrap=line_wrap,
                                      suppressed_paths=suppressed_paths)

    frame_msgs = []
    parent_is_boring = True
    for frame in frames:
        fi = ex.get_info(frame)
        is_boring = match(fi.filename, suppressed_paths)
        if is_boring:
            if parent_is_boring:
                formatter = minimal_formatter
            else:
                formatter = reduced_formatter
        else:
            formatter = verbose_formatter

        parent_is_boring = is_boring
        frame_msgs.append(formatter(fi))

    if reverse:
        frame_msgs = reversed(frame_msgs)

    return ''.join(frame_msgs)
예제 #3
0
def format_exc_info(etype,
                    evalue,
                    tb,
                    style='plaintext',
                    add_summary='auto',
                    reverse=False,
                    **kwargs):
    """
    Format an exception traceback, including the exception message

    keyword args like stackprinter.format()
    """
    try:
        msgs = []
        if tb:
            frameinfos = [ex.get_info(tb_) for tb_ in _walk_traceback(tb)]
            stack_msg = format_stack(frameinfos,
                                     style=style,
                                     reverse=reverse,
                                     **kwargs)
            msgs.append(stack_msg)

            if add_summary == 'auto':
                add_summary = stack_msg.count('\n') > 50

            if add_summary:
                summ = format_summary(frameinfos,
                                      style=style,
                                      reverse=reverse,
                                      **kwargs)
                summ += '\n'
                msgs.append('---- (full traceback below) ----\n\n' if reverse
                            else '---- (full traceback above) ----\n')
                msgs.append(summ)

        exc = format_exception_message(etype, evalue, style=style)
        msgs.append('\n\n' if reverse else '')
        msgs.append(exc)

        if reverse:
            msgs = reversed(msgs)

        msg = ''.join(msgs)

    except Exception as exc:
        our_tb = traceback.format_exception(exc.__class__,
                                            exc,
                                            exc.__traceback__,
                                            chain=False)

        msg = 'Stackprinter failed:\n%s' % ''.join(our_tb[-2:])
        msg += 'So here is the original traceback at least:\n\n'
        msg += ''.join(traceback.format_exception(etype, evalue, tb))

    return msg
예제 #4
0
def frameinfo():
    somevalue = 'spam'

    supersecretthings = "gaaaah"

    class Blob():
        pass

    someobject = Blob()
    someobject.secretattribute = "uarrgh"

    fr = sys._getframe()
    hidden = [r".*secret.*", r"someobject\..*attribute"]
    return ex.get_info(fr, suppressed_vars=hidden)
def format_stack_from_frame(fr, add_summary=False, **kwargs):
    """
    Render a frame and its parents


    keyword args like stackprinter.format()

    """
    stack = []
    while fr is not None:
        stack.append(ex.get_info(fr))
        fr = fr.f_back
    stack = reversed(stack)

    return format_stack(stack, **kwargs)
예제 #6
0
    def __call__(self, frame, lineno=None):
        """
        Render a single stack frame or traceback entry


        Params
        ----

        frame: Frame object, Traceback object (or FrameInfo tuple)
            The frame or traceback entry to be formatted.

            The only difference between passing a frame or a traceback object is
            which line gets highlighted in the source listing: For a frame, it's
            the currently executed line; for a traceback, it's the line where an
            error occurred. (technically: `frame.f_lineno` vs. `tb.tb_lineno`)

            The third option is interesting only if you're planning to format
            one frame multiple different ways: It is a little faster to format a
            pre-chewed verion of the frame, since non-formatting-specific steps
            like "finding the source code", "finding all the variables" etc only
            need to be done once per frame. So, this method also accepts the raw
            results of `extraction.get_info()` of type FrameInfo. In that case,
            this method will really just do formatting, no more chewing.

        lineno: int
            override which line gets highlighted
        """
        accepted_types = (types.FrameType, types.TracebackType, ex.FrameInfo)
        if not isinstance(frame, accepted_types):
            raise ValueError("Expected one of these types: "
                             "%s. Got %r" % (accepted_types, frame))

        try:
            if isinstance(frame, ex.FrameInfo):
                finfo = frame
            else:
                finfo = ex.get_info(frame, lineno)

            return self._format_frame(finfo, self.lines, self.lines_after,
                                      self.show_vals, self.show_signature,
                                      self.truncate_vals,
                                      self.suppressed_paths)
        except Exception as exc:
            if isinstance(frame, ex.FrameInfo):
                exc.where = [finfo.filename, finfo.function, finfo.lineno]
            else:
                exc.where = frame
            raise
예제 #7
0
def format_exc_info(etype,
                    evalue,
                    tb,
                    style='plaintext',
                    add_summary='auto',
                    reverse=False,
                    **kwargs):
    """
    Format an exception traceback, including the exception message

    keyword args like stackprinter.format()
    """
    msg = ''
    try:
        # First, recursively format any chained exceptions (exceptions during whose handling
        # the given one happened).
        # TODO: refactor this whole messy function to return a more... structured datastructure
        # before assembling a string, so that e.g. a summary of the whole chain can be shown at
        # the end.
        context = getattr(evalue, '__context__', None)
        cause = getattr(evalue, '__cause__', None)
        suppress_context = getattr(evalue, '__suppress_context__', False)
        if cause:
            chained_exc = cause
            chain_hint = ("\n\nThe above exception was the direct cause "
                          "of the following exception:\n\n")
        elif context and not suppress_context:
            chained_exc = context
            chain_hint = ("\n\nWhile handling the above exception, "
                          "another exception occurred:\n\n")
        else:
            chained_exc = None

        if chained_exc:
            msg += format_exc_info(chained_exc.__class__,
                                   chained_exc,
                                   chained_exc.__traceback__,
                                   style=style,
                                   add_summary=add_summary,
                                   reverse=reverse,
                                   **kwargs)

            if style == 'plaintext':
                msg += chain_hint
            else:
                sc = getattr(colorschemes, style)
                clr = get_ansi_tpl(*sc.colors['exception_type'])
                msg += clr % chain_hint

        # Now, actually do some formatting:
        msgs = []
        if tb:
            frameinfos = [ex.get_info(tb_) for tb_ in _walk_traceback(tb)]
            stack_msg = format_stack(frameinfos,
                                     style=style,
                                     reverse=reverse,
                                     **kwargs)
            msgs.append(stack_msg)

            if add_summary == 'auto':
                add_summary = stack_msg.count('\n') > 50

            if add_summary:
                summ = format_summary(frameinfos,
                                      style=style,
                                      reverse=reverse,
                                      **kwargs)
                summ += '\n'
                msgs.append('---- (full traceback below) ----\n\n' if reverse
                            else '---- (full traceback above) ----\n')
                msgs.append(summ)

        exc = format_exception_message(etype, evalue, style=style)
        msgs.append('\n\n' if reverse else '')
        msgs.append(exc)

        if reverse:
            msgs = reversed(msgs)

        msg += ''.join(msgs)

    except Exception as exc:
        import os
        if 'PY_STACKPRINTER_DEBUG' in os.environ:
            raise

        our_tb = traceback.format_exception(exc.__class__,
                                            exc,
                                            exc.__traceback__,
                                            chain=False)
        where = getattr(exc, 'where', None)
        context = " while formatting " + str(where) if where else ''
        msg = 'Stackprinter failed%s:\n%s\n' % (context, ''.join(our_tb[-2:]))
        msg += 'So here is your original traceback at least:\n\n'
        msg += ''.join(traceback.format_exception(etype, evalue, tb))

    return msg
예제 #8
0
def frameinfo():
    somevalue = 'spam'
    fr = sys._getframe()
    return ex.get_info(fr)