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

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:
 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

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.