Pretty¶
liblaf.pretty builds repr-like Rich renderables for Python objects. It is a
good fit for interactive debugging, logs, doctests, and snapshots where you
want readable output without giving up Rich styling or width-aware wrapping.
Start With pformat()¶
from rich.console import Console
from liblaf.pretty import pformat
rendered = pformat({"alpha": [1, 2, 3]})
console = Console(
width=12,
color_system=None,
soft_wrap=True,
no_color=True,
markup=False,
emoji=False,
highlight=False,
)
print(rendered.to_plain(console=console), end="")
pformat() returns a Rich renderable, not a string. Use console.print() to
render it normally, or .to_plain(console=...) when you want deterministic
plain text for logs, tests, or snapshots.
.to_plain() creates a safe default Console when you omit one, but for
width-sensitive output it is still best to pass an explicit Console(width=...).
If you already have a Rich console, pprint() and pp() format and print in
one step.
Formatting Options¶
The public formatting functions accept these keyword overrides:
| Keyword | Default | Meaning |
|---|---|---|
max_level |
6 |
Maximum nesting depth before values collapse to .... |
max_list |
6 |
Maximum visible items in list-like containers. |
max_array |
5 |
Maximum array items forwarded to repr-style handlers. |
max_dict |
4 |
Maximum visible key-value pairs in dictionaries. |
max_string |
30 |
Maximum string repr length before truncation. |
max_long |
40 |
Maximum integer repr length before truncation. |
max_other |
30 |
Maximum repr length for other scalar values. |
indent |
"| " |
Indentation used when layouts break across lines. |
hide_defaults |
True |
Hide default-valued fields from fieldz and __rich_repr__ output. |
Each value can also come from PRETTY_* environment variables. For example,
PRETTY_MAX_LIST=1 has the same effect as pformat(obj, max_list=1).
indent accepts str and [Text][rich.text.Text]. String values are parsed as
Rich markup, and ANSI escapes are preserved.
Width is chosen when Rich renders the result through a Console, not when you
call pformat().
Built In¶
liblaf.pretty ships with a few integrations before you register anything:
- builtin containers such as
dict,list,tuple,set, andfrozenset fieldz-compatible models, including commonattrspatterns- objects with
__rich_repr__ - fallback repr output for everything else
hide_defaults=True applies to both fieldz-compatible models and
__rich_repr__ output:
import attrs
from rich.console import Console
from liblaf.pretty import pformat
@attrs.define
class Point:
x: int = 1
y: int = 2
console = Console(width=80, color_system=None, soft_wrap=True)
print(pformat(Point()).to_plain(console=console))
print(pformat(Point(), hide_defaults=False).to_plain(console=console), end="")
Objects with __rich_repr__ can mix named and positional items. Falsey names
fall back to positional output, so ("", value) and (None, value) render the
same way as explicit positional items.
Reference Tracking¶
The formatter avoids infinite recursion and can annotate repeated references for
referencable objects such as mappings, sets, frozensets, and custom containers.
The first occurrence is annotated, and later occurrences render as
<Type @ hexid> references.
Scalar values and sequence literals still render safely, but lists and tuples repeat their value instead of emitting a shared-reference marker.
Environment Defaults¶
Per-call keyword overrides are usually the clearest choice, but you can also
set environment defaults with PRETTY_* variables:
PRETTY_INDENT accepts the same plain-text, Rich-markup, ANSI-colored strings,
and Text values as the indent= keyword argument.
Extending The Formatter¶
The extension surface is intentionally small:
- Implement
__pretty__(self, ctx)when you own the class. - Use
register_type()for a concrete type and its subclasses. - Use
register_func()for structural matching. - Use
register_lazy()for optional dependencies that should only activate after their module is already imported.
PrettyContext is the builder object passed into custom formatters. It creates
wrapped nodes, handles truncation helpers, and keeps identity stable so shared
references can be detected later in the pipeline.
For a practical walkthrough, see Custom Formatters.
Pipeline¶
The public API is small:
pformat()builds a lowered Rich renderable.pprint()andpp()print that renderable through aConsole.PrettyContextand the registration helpers power custom integrations.
The lower-level stages.wrapped, stages.traced, and stages.lowered modules
are part of the internal pipeline and are mostly useful when you are extending
the formatter itself.
See the API reference for signatures and source-backed docstrings.