pytermgui.pretty

This module calls install() on import, and defines print as pprint.

It allows setting up pretty print functionality in only one line.

Usage
>>> from pytermgui.pretty import print
View Source
  0"""This module calls `install()` on import, and defines `print` as `pprint`.
  1
  2It allows setting up pretty print functionality in only one line.
  3
  4Usage:
  5    ```python3
  6    >>> from pytermgui.pretty import print
  7    ```
  8"""
  9
 10from __future__ import annotations
 11
 12import os
 13import sys
 14import builtins
 15from typing import Any
 16
 17from .parser import tim
 18from .prettifiers import prettify
 19from .terminal import get_terminal
 20
 21try:
 22    # Try to get IPython instance. This function is provided by the
 23    # IPython runtime, so if running outside of that context a NameError
 24    # is raised.
 25    IPYTHON = get_ipython()  # type: ignore
 26    from IPython.core.formatters import BaseFormatter  # pylint: disable=import-error
 27
 28except NameError:
 29    IPYTHON = None
 30    BaseFormatter = object
 31
 32
 33NO_WELCOME = os.getenv("PTG_SILENCE_PRETTY") is not None
 34
 35__all__ = ["pprint", "install"]
 36
 37
 38def pprint(
 39    *items: Any,
 40    indent: int = 2,
 41    expand_all: bool = False,
 42    force_markup: bool = False,
 43    parse: bool = True,
 44    **print_args: Any,
 45) -> None:
 46    r"""A wrapper to pretty-print any object.
 47
 48    This essentially just calls `prettify` on each given object, and passes the
 49    `**print_args` right through to print. Note that when the `sep` print argument is
 50    ommitted it is manually set to ", \n".
 51
 52    To customize any of the styles, see `MarkupLanguage.prettify`.
 53
 54    Args:
 55        *items: The items to print. These are passed in the same way they would be into
 56            builtin print.
 57        indent: The indentation value used for multi-line objects. This is ignored when
 58            the given object has a `len() < 2`, and `expand_all is not set.`
 59        force_tim: Turn all ANSI-sequences into tim before pretty printing.
 60        expand_all: Force-expand containers, even when they would normally be collapsed.
 61        **print_args: All arguments passed to builtin print.
 62    """
 63
 64    if "sep" not in print_args:
 65        print_args["sep"] = ", \n"
 66
 67    pretty = []
 68    for item in items:
 69        if hasattr(item, "get_lines"):
 70            pretty.append("\n".join(item.get_lines()))
 71            continue
 72
 73        pretty.append(
 74            prettify(
 75                item,
 76                force_markup=force_markup,
 77                indent=indent,
 78                expand_all=expand_all,
 79                parse=parse,
 80            )
 81        )
 82
 83    get_terminal().print(*pretty, **print_args)
 84
 85
 86def install(
 87    indent: int = 2, force_markup: bool = False, expand_all: bool = False
 88) -> None:
 89    """Sets up `pprint` to print all REPL output. IPython is also supported.
 90
 91    This functions sets up a hook that will call `pprint` after every interactive
 92    return. The given arguments are passed directly to `pprint`, so for more information
 93    you can check out that function.
 94
 95    Usage is pretty simple:
 96
 97    ```python3
 98    >>> from pytermgui import pretty
 99    >>> tim.setup_displayhook()
100    >>> # Any function output will now be prettified
101    ```
102
103    ...or alternatively, you can import `print` from `pytermgui.pretty`,
104    and have it automatically set up, and replace your namespace's `print`
105    function with `tim.pprint`:
106
107    ```python3
108    >>> from pytermgui.pretty import print
109    ... # Under the hood, the above is called and `tim.pprint` is set
110    ... # for the `print` name
111    >>> # Any function output will now be prettified
112    ```
113
114    Args:
115        indent: The indentation value used for multi-line objects. This is ignored when
116            the given object has a `len() < 2`, and `expand_all is not set.`
117        force_tim: Turn all ANSI-sequences into tim before pretty printing.
118        expand_all: Force-expand containers, even when they would normally be collapsed.
119    """
120
121    def _hook(value: Any) -> None:
122        if value is None:
123            return
124
125        pprint(value, force_markup=force_markup, indent=indent, expand_all=expand_all)
126
127        # Sets up "_" as a way to access return value,
128        # inkeeping with sys.displayhook
129        builtins._ = value  # type: ignore
130
131    if IPYTHON is not None:
132        IPYTHON.display_formatter.formatters["text/plain"] = PTGFormatter(
133            force_markup=force_markup, indent=indent, expand_all=expand_all
134        )
135
136    else:
137        sys.displayhook = _hook
138
139    if not NO_WELCOME:
140        with get_terminal().no_record():
141            print()
142            tim.print("[113 bold]Successfully set up prettification!")
143            tim.print("[245 italic]> All function returns will now be pretty-printed,")
144            print()
145            pprint("[245 italic]Including [/italic 210]Markup!")
146            print()
147
148    get_terminal().displayhook_installed = True
149
150
151class PTGFormatter(BaseFormatter):  # pylint: disable=too-few-public-methods
152    """An IPython formatter for PTG pretty printing."""
153
154    def __init__(self, **kwargs: Any) -> None:
155        """Initializes PTGFormatter, storing **kwargs."""
156
157        super().__init__()
158
159        self.kwargs = kwargs
160
161    def __call__(self, value: Any) -> None:
162        """Pretty prints the given value, as well as a leading newline.
163
164        The newline is needed since IPython output is prepended with
165        "Out[i]:", and it might mess alignments up.
166        """
167
168        print("\n")
169        pprint(value, **self.kwargs)
170
171        # Sets up "_" as a way to access return value,
172        # inkeeping with sys.displayhook
173        builtins._ = value  # type: ignore
174
175
176# I am normally violently against shadowing builtins, but this is an optional,
177# (hopefully always) REPL-only name, only provided for convenience.
178print = pprint  # pylint: disable=redefined-builtin
179
180install()
#   def pprint( *items: Any, indent: int = 2, expand_all: bool = False, force_markup: bool = False, parse: bool = True, **print_args: Any ) -> None:
View Source
39def pprint(
40    *items: Any,
41    indent: int = 2,
42    expand_all: bool = False,
43    force_markup: bool = False,
44    parse: bool = True,
45    **print_args: Any,
46) -> None:
47    r"""A wrapper to pretty-print any object.
48
49    This essentially just calls `prettify` on each given object, and passes the
50    `**print_args` right through to print. Note that when the `sep` print argument is
51    ommitted it is manually set to ", \n".
52
53    To customize any of the styles, see `MarkupLanguage.prettify`.
54
55    Args:
56        *items: The items to print. These are passed in the same way they would be into
57            builtin print.
58        indent: The indentation value used for multi-line objects. This is ignored when
59            the given object has a `len() < 2`, and `expand_all is not set.`
60        force_tim: Turn all ANSI-sequences into tim before pretty printing.
61        expand_all: Force-expand containers, even when they would normally be collapsed.
62        **print_args: All arguments passed to builtin print.
63    """
64
65    if "sep" not in print_args:
66        print_args["sep"] = ", \n"
67
68    pretty = []
69    for item in items:
70        if hasattr(item, "get_lines"):
71            pretty.append("\n".join(item.get_lines()))
72            continue
73
74        pretty.append(
75            prettify(
76                item,
77                force_markup=force_markup,
78                indent=indent,
79                expand_all=expand_all,
80                parse=parse,
81            )
82        )
83
84    get_terminal().print(*pretty, **print_args)

A wrapper to pretty-print any object.

This essentially just calls prettify on each given object, and passes the **print_args right through to print. Note that when the sep print argument is ommitted it is manually set to ", \n".

To customize any of the styles, see MarkupLanguage.prettify.

Args
  • *items: The items to print. These are passed in the same way they would be into builtin print.
  • indent: The indentation value used for multi-line objects. This is ignored when the given object has a len() < 2, and expand_all is not set.
  • force_tim: Turn all ANSI-sequences into tim before pretty printing.
  • expand_all: Force-expand containers, even when they would normally be collapsed.
  • **print_args: All arguments passed to builtin print.
#   def install( indent: int = 2, force_markup: bool = False, expand_all: bool = False ) -> None:
View Source
 87def install(
 88    indent: int = 2, force_markup: bool = False, expand_all: bool = False
 89) -> None:
 90    """Sets up `pprint` to print all REPL output. IPython is also supported.
 91
 92    This functions sets up a hook that will call `pprint` after every interactive
 93    return. The given arguments are passed directly to `pprint`, so for more information
 94    you can check out that function.
 95
 96    Usage is pretty simple:
 97
 98    ```python3
 99    >>> from pytermgui import pretty
100    >>> tim.setup_displayhook()
101    >>> # Any function output will now be prettified
102    ```
103
104    ...or alternatively, you can import `print` from `pytermgui.pretty`,
105    and have it automatically set up, and replace your namespace's `print`
106    function with `tim.pprint`:
107
108    ```python3
109    >>> from pytermgui.pretty import print
110    ... # Under the hood, the above is called and `tim.pprint` is set
111    ... # for the `print` name
112    >>> # Any function output will now be prettified
113    ```
114
115    Args:
116        indent: The indentation value used for multi-line objects. This is ignored when
117            the given object has a `len() < 2`, and `expand_all is not set.`
118        force_tim: Turn all ANSI-sequences into tim before pretty printing.
119        expand_all: Force-expand containers, even when they would normally be collapsed.
120    """
121
122    def _hook(value: Any) -> None:
123        if value is None:
124            return
125
126        pprint(value, force_markup=force_markup, indent=indent, expand_all=expand_all)
127
128        # Sets up "_" as a way to access return value,
129        # inkeeping with sys.displayhook
130        builtins._ = value  # type: ignore
131
132    if IPYTHON is not None:
133        IPYTHON.display_formatter.formatters["text/plain"] = PTGFormatter(
134            force_markup=force_markup, indent=indent, expand_all=expand_all
135        )
136
137    else:
138        sys.displayhook = _hook
139
140    if not NO_WELCOME:
141        with get_terminal().no_record():
142            print()
143            tim.print("[113 bold]Successfully set up prettification!")
144            tim.print("[245 italic]> All function returns will now be pretty-printed,")
145            print()
146            pprint("[245 italic]Including [/italic 210]Markup!")
147            print()
148
149    get_terminal().displayhook_installed = True

Sets up pprint to print all REPL output. IPython is also supported.

This functions sets up a hook that will call pprint after every interactive return. The given arguments are passed directly to pprint, so for more information you can check out that function.

Usage is pretty simple:

>>> from pytermgui import pretty
>>> tim.setup_displayhook()
>>> # Any function output will now be prettified

...or alternatively, you can import print from pytermgui.pretty, and have it automatically set up, and replace your namespace's print function with tim.pprint:

>>> from pytermgui.pretty import print
... # Under the hood, the above is called and `tim.pprint` is set
... # for the `print` name
>>> # Any function output will now be prettified
Args
  • indent: The indentation value used for multi-line objects. This is ignored when the given object has a len() < 2, and expand_all is not set.
  • force_tim: Turn all ANSI-sequences into tim before pretty printing.
  • expand_all: Force-expand containers, even when they would normally be collapsed.