コード例 #1
0
def sweeten_errors():
    try:
        yield
    except Exception as exc:
        SPACES = 2
        w = term.white
        prefix = w("║" + " " * (SPACES - 1))
        suffix = w(" " * (SPACES - 1) + "║")

        pre_re = re.compile("([^`]*)`([^`]*)`([^`]*)")

        def format_arg(arg):
            length = len(pre_re.sub("\\1\\2\\3", arg))

            arg = pre_re.sub(w("\\1") + term.bold("\\2") + w("\\3"), arg)
            arg = re.sub(r"^  \$ (.*)", term.lightblack("  $ ") + term.reset("\\1"), arg)

            return (arg, length)

        def f(*args):
            return "".join(args)

        term_width, term_height = term.get_size()
        line_length = min(80, term_width)
        for arg in exc.args:
            line_length = max(min(line_length, len(arg) + 2 * SPACES), 120)

        print(f(w("╔" + "═" * (line_length - 2) + "╗")))
        for i, arg in enumerate(exc.args):

            if i == 1:
                print(f(prefix, " " * (line_length - 2 * SPACES), suffix))

            arg_formatted, arg_length = format_arg(arg)
            if not i:
                # first line
                print(
                    f(
                        prefix,
                        term.red_bg(term.bold(" " + type(exc).__name__ + " ")),
                        " ",
                        w(arg_formatted),
                        " " * (line_length - (arg_length + 3 + len(type(exc).__name__) + 2 * SPACES)),
                        suffix,
                    )
                )
            else:
                # other lines
                print(f(prefix, arg_formatted + " " * (line_length - arg_length - 2 * SPACES), suffix))

        print(f(w("╚" + "═" * (line_length - 2) + "╝")))

        logging.getLogger().debug("This error was caused by the following exception chain.", exc_info=exc_info())
コード例 #2
0
ファイル: humanizer.py プロジェクト: bhushanpant/mondrian
def humanized(exc,
              *,
              fg=term.red,
              bg=lambda *args: term.red_bg(term.bold(*args)),
              help_url=None):
    SPACES = 2
    prefix, suffix = fg(VERT + " " * (SPACES - 1)), fg(" " * (SPACES - 1) +
                                                       VERT)
    result = []

    def format_arg(arg):
        length = len(preformatted_pattern.sub("\\1\\2\\3", arg))
        arg = preformatted_pattern.sub("\\1" + term.bold("\\2") + "\\3", arg)
        arg = re.sub("^  \$ (.*)",
                     term.lightblack("  $ ") + term.reset("\\1"), arg)
        return (arg, length)

    def joined(*args):
        return "".join(args)

    term_width, term_height = term.get_size()
    line_length = min(80, term_width)
    for arg in exc.args:
        line_length = max(min(line_length, len(arg) + 2 * SPACES), 120)

    result.append(joined(fg(TOP_LEFT + HORIZ * (line_length - 2) + TOP_RIGHT)))

    args = list(exc.args)

    for i, arg in enumerate(args):

        if i == 1:
            result.append(
                joined(prefix, " " * (line_length - 2 * SPACES), suffix))

        arg_formatted, arg_length = format_arg(arg)
        if not i:
            # first line
            result.append(
                joined(
                    prefix,
                    bg(" " + type(exc).__name__ + " "),
                    " ",
                    term.white(arg_formatted),
                    " " *
                    (line_length -
                     (arg_length + 3 + len(type(exc).__name__) + 2 * SPACES)),
                    suffix,
                ))
        else:
            # other lines
            result.append(
                joined(
                    prefix, arg_formatted + " " *
                    (line_length - arg_length - 2 * SPACES), suffix))

    if help_url:
        help_prefix = "Read more: "
        arg_length = len(help_url) + len(help_prefix)
        arg_formatted = help_prefix + term.underline(term.lightblue(help_url))
        result.append(joined(prefix, " " * (line_length - 2 * SPACES), suffix))
        result.append(
            joined(
                prefix,
                arg_formatted + " " * (line_length - arg_length - 2 * SPACES),
                suffix))

    more = settings.DEBUG
    exc_lines = format_exception(exc_info(), fg=fg, bg=bg,
                                 summary=False).splitlines()

    if not len(exc_lines):
        more = False

    result.append(
        joined(
            fg((VERT_LEFT if more else BOTTOM_LEFT) + HORIZ *
               (line_length - 2) + BOTTOM_RIGHT)))

    if more:
        for _line in exc_lines:
            result.append(_line)
        result.append(joined(fg("╵")))
    elif len(exc_lines):
        result.append(
            term.lightblack(
                "(add DEBUG=1 to system environment for stack trace)".rjust(
                    line_length)))

    return "\n".join(result)
コード例 #3
0
ファイル: basics.py プロジェクト: zkan/bonobo
class PrettyPrinter(Configurable):
    max_width = Option(
        int,
        default=term.get_size()[0],
        required=False,
        __doc__="""
        If set, truncates the output values longer than this to this width.
    """,
    )

    filter = Method(
        default=(lambda self, index, key, value: (value is not None) and
                 (not isinstance(key, str) or not key.startswith("_"))),
        __doc__="""
            A filter that determine what to print.
            
            Default is to ignore any key starting with an underscore and none values.
        """,
    )

    @ContextProcessor
    def context(self, context):
        context.setdefault("_jupyter_html", None)
        yield context
        if context._jupyter_html is not None:
            from IPython.display import display, HTML

            display(
                HTML("\n".join(["<table>"] + context._jupyter_html +
                               ["</table>"])))

    def __call__(self, context, *args, **kwargs):
        if not settings.QUIET:
            if term.isjupyter:
                self.print_jupyter(context, *args, **kwargs)
                return NOT_MODIFIED
            if term.istty:
                self.print_console(context, *args, **kwargs)
                return NOT_MODIFIED

        self.print_quiet(context, *args, **kwargs)
        return NOT_MODIFIED

    def print_quiet(self, context, *args, **kwargs):
        for index, (key, value) in enumerate(
                itertools.chain(enumerate(args), kwargs.items())):
            if self.filter(index, key, value):
                print(
                    self.format_quiet(index,
                                      key,
                                      value,
                                      fields=context.get_input_fields()))

    def format_quiet(self, index, key, value, *, fields=None):
        # XXX should we implement argnames here ?
        return " ".join(
            ((" " if index else "-"), str(key), ":", str(value).strip()))

    def print_console(self, context, *args, **kwargs):
        print("\u250c")
        for index, (key, value) in enumerate(
                itertools.chain(enumerate(args), kwargs.items())):
            if self.filter(index, key, value):
                print(
                    self.format_console(index,
                                        key,
                                        value,
                                        fields=context.get_input_fields()))
        print("\u2514")

    def format_console(self, index, key, value, *, fields=None):
        fields = fields or []
        if not isinstance(key, str):
            if len(fields) > key and str(key) != str(fields[key]):
                key = "{}{}".format(fields[key],
                                    term.lightblack("[{}]".format(key)))
            else:
                key = str(index)

        prefix = "\u2502 {} = ".format(key)
        prefix_length = len(prefix)

        def indent(text, prefix):
            for i, line in enumerate(text.splitlines()):
                yield (prefix if i else "") + line + CLEAR_EOL + "\n"

        repr_of_value = "".join(
            indent(pprint.pformat(value, width=self.max_width - prefix_length),
                   "\u2502" + " " * (len(prefix) - 1))).strip()
        return "{}{}{}".format(prefix,
                               repr_of_value.replace("\n", CLEAR_EOL + "\n"),
                               CLEAR_EOL)

    def print_jupyter(self, context, *args):
        if not context._jupyter_html:
            context._jupyter_html = [
                "<thead><tr>",
                *map(
                    "<th>{}</th>".format,
                    map(
                        html.escape,
                        map(str,
                            context.get_input_fields() or range(len(args))))),
                "</tr></thead>",
            ]

        context._jupyter_html += [
            "<tr>",
            *map("<td>{}</td>".format, map(html.escape, map(repr, args))),
            "</tr>"
        ]