Skip to content

liblaf.pretty

Public API for liblaf.pretty.

Import pformat when you want a width-aware Rich renderable, pprint or pp when you want to print immediately, and the registration helpers when you need to teach the formatter about custom types.

Modules:

  • common

    Shared sentinels and identity helpers used by the formatting pipeline.

  • custom

    Customization helpers for teaching liblaf.pretty new formatting rules.

  • literals

    Styled Rich text fragments reused throughout the formatter.

  • stages

    Internal pipeline stages that turn wrapped objects into Rich renderables.

Classes:

  • PrettyConfig

    Environment-backed defaults for the pretty printer.

  • PrettyContext

    Helper object passed to custom formatters and pipeline stages.

  • PrettyHandler

    Protocol implemented by pretty-printer callbacks.

  • PrettyOptions

    Resolved options for a single formatting pass.

  • PrettyOverrides

    Keyword overrides accepted by the public formatting functions.

Functions:

  • pformat

    Build a width-aware Rich renderable for obj.

  • pprint

    Format obj and print it through a Rich console.

Attributes:

config module-attribute

pp module-attribute

pp = pprint

register_func module-attribute

register_func = register_func

register_lazy module-attribute

register_lazy = register_lazy

register_type module-attribute

register_type = register_type

PrettyConfig

Bases: BaseConfig


              flowchart TD
              liblaf.pretty.PrettyConfig[PrettyConfig]
              liblaf.conf._config.BaseConfig[BaseConfig]

                              liblaf.conf._config.BaseConfig --> liblaf.pretty.PrettyConfig
                


              click liblaf.pretty.PrettyConfig href "" "liblaf.pretty.PrettyConfig"
              click liblaf.conf._config.BaseConfig href "" "liblaf.conf._config.BaseConfig"
            

Environment-backed defaults for the pretty printer.

Values are loaded from PRETTY_* variables and can be overridden per call with pformat or pprint. PRETTY_INDENT accepts the same markup and ANSI inputs as the per-call indent override.

Methods:

  • dump

    Materialize the current configuration as PrettyOptions.

  • load_env

    Refresh every field from its configured environment variable.

  • override

    Temporarily override one or more values within a context manager.

  • set

    Update fields or groups from a mapping and keyword arguments.

  • to_dict

    Serialize the current config tree to nested dictionaries.

  • to_namespace

    Serialize the current config tree to nested namespaces.

Attributes:

env_prefix class-attribute

env_prefix: str = 'PRETTY_'

hide_defaults class-attribute instance-attribute

hide_defaults: Field[bool] = field_bool(default=True)

indent class-attribute instance-attribute

indent: Field[Text] = field_text(default=INDENT)

max_array class-attribute instance-attribute

max_array: Field[int] = field_int(default=5)

max_dict class-attribute instance-attribute

max_dict: Field[int] = field_int(default=4)

max_level class-attribute instance-attribute

max_level: Field[int] = field_int(default=6)

max_list class-attribute instance-attribute

max_list: Field[int] = field_int(default=6)

max_long class-attribute instance-attribute

max_long: Field[int] = field_int(default=40)

max_other class-attribute instance-attribute

max_other: Field[int] = field_int(default=30)

max_string class-attribute instance-attribute

max_string: Field[int] = field_int(default=30)

name class-attribute

name: str

dump

dump() -> PrettyOptions

Materialize the current configuration as PrettyOptions.

The returned object is a snapshot of the current environment-backed values, with indent normalized to [Text][rich.text.Text].

Source code in src/liblaf/pretty/_config.py
def dump(self) -> PrettyOptions:
    """Materialize the current configuration as [`PrettyOptions`][liblaf.pretty.PrettyOptions].

    The returned object is a snapshot of the current environment-backed
    values, with `indent` normalized to [`Text`][rich.text.Text].
    """
    return PrettyOptions(**self.to_dict())

load_env

load_env() -> None

Refresh every field from its configured environment variable.

Source code in .venv/lib/python3.14/site-packages/liblaf/conf/_config.py
def load_env(self) -> None:
    """Refresh every field from its configured environment variable."""
    for name in self._fields:
        var: Var[Any] = self._get_field(name)
        var.load_env()
    for name in self._groups:
        group: BaseConfig = self._get_group(name)
        group.load_env()

override

override(
    changes: Mapping[str, Any] | None = None,
    /,
    **kwargs: Any,
) -> Generator[None]

Temporarily override one or more values within a context manager.

Parameters:

  • changes (Mapping[str, Any] | None, default: None ) –

    Optional mapping of names to temporary values.

  • **kwargs (Any, default: {} ) –

    Additional name-to-value overrides.

Yields:

  • Generator[None]

    None while the overrides are active.

Source code in .venv/lib/python3.14/site-packages/liblaf/conf/_config.py
@contextlib.contextmanager
def override(
    self, changes: Mapping[str, Any] | None = None, /, **kwargs: Any
) -> Generator[None]:
    """Temporarily override one or more values within a context manager.

    Args:
        changes: Optional mapping of names to temporary values.
        **kwargs: Additional name-to-value overrides.

    Yields:
        `None` while the overrides are active.
    """
    if changes is not None:
        kwargs.update(changes)
    with contextlib.ExitStack() as stack:
        for name, value in kwargs.items():
            var: BaseConfig | Var[Any] = self._get_field_or_group(name)
            stack.enter_context(var.override(value))
        yield

set

set(
    changes: Mapping[str, Any] | None = None,
    /,
    **kwargs: Any,
) -> None

Update fields or groups from a mapping and keyword arguments.

Nested groups accept mapping values and forward them to the nested config's own set() method.

Source code in .venv/lib/python3.14/site-packages/liblaf/conf/_config.py
def set(self, changes: Mapping[str, Any] | None = None, /, **kwargs: Any) -> None:
    """Update fields or groups from a mapping and keyword arguments.

    Nested groups accept mapping values and forward them to the nested
    config's own `set()` method.
    """
    if changes is not None:
        kwargs.update(changes)
    for name, value in kwargs.items():
        var: BaseConfig | Var[Any] = self._get_field_or_group(name)
        var.set(value)

to_dict

to_dict() -> dict[str, Any]

Serialize the current config tree to nested dictionaries.

Source code in .venv/lib/python3.14/site-packages/liblaf/conf/_config.py
def to_dict(self) -> dict[str, Any]:
    """Serialize the current config tree to nested dictionaries."""
    result: dict[str, Any] = {}
    for name in self._fields:
        result[name] = self._get_field(name).get()
    for name in self._groups:
        result[name] = self._get_group(name).to_dict()
    return result

to_namespace

to_namespace() -> SimpleNamespace

Serialize the current config tree to nested namespaces.

Source code in .venv/lib/python3.14/site-packages/liblaf/conf/_config.py
def to_namespace(self) -> types.SimpleNamespace:
    """Serialize the current config tree to nested namespaces."""
    result: types.SimpleNamespace = types.SimpleNamespace()
    for name in self._fields:
        setattr(result, name, self._get_field(name).get())
    for name in self._groups:
        setattr(result, name, self._get_group(name).to_namespace())
    return result

PrettyContext

Bases: TraceContext


              flowchart TD
              liblaf.pretty.PrettyContext[PrettyContext]
              liblaf.pretty.stages.wrapped._context.TraceContext[TraceContext]

                              liblaf.pretty.stages.wrapped._context.TraceContext --> liblaf.pretty.PrettyContext
                


              click liblaf.pretty.PrettyContext href "" "liblaf.pretty.PrettyContext"
              click liblaf.pretty.stages.wrapped._context.TraceContext href "" "liblaf.pretty.stages.wrapped._context.TraceContext"
            

Helper object passed to custom formatters and pipeline stages.

Custom handlers usually build output with container, name_value, and positional.

Attributes:

Parameters:

  • depth (int, default: 0 ) –
  • options (PrettyOptions, default: PrettyOptions(max_level=6, max_list=6, max_array=5, max_dict=4, max_string=30, max_long=40, max_other=30, indent=<text '| ' [] 'repr.indent'>, hide_defaults=True) ) –

    Materialize the current configuration as PrettyOptions.

    The returned object is a snapshot of the current environment-backed values, with indent normalized to [Text][rich.text.Text].

  • trace_cache (dict[int, TracedObject], default: <class 'dict'> ) –

    dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

  • types (set[type], default: <dynamic> ) –

    Build an unordered collection of unique elements.

  • registry (PrettyRegistry, default: PrettyRegistry(handlers=[<function _describe_fieldz at 0x7fa40748a350>, <function _describe_rich_repr at 0x7fa40748a4b0>], lazy_handlers={}, type_dispatcher=<function _default_type_dispatcher.<locals>.type_dispatcher at 0x7fa407473480>) ) –
  • wrap_cache (dict[int, WrappedNode], default: <class 'dict'> ) –

    dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

Methods:

  • add_separators

    Add repr-style spacing and trailing commas to a sequence of items.

  • container

    Build a repr-like container node.

  • ellipsis_item

    Return the positional ellipsis item used for truncated containers.

  • finish

    Build the lowering context with disambiguated type names.

  • identifier

    Return the identity record for obj.

  • key_value

    Build a key: value item or an ellipsis placeholder when truncated.

  • leaf

    Build a scalar leaf node from Rich text.

  • name_value

    Build a repr-style name=value item.

  • positional

    Build a positional item or an ellipsis placeholder when truncated.

  • possibly_sorted

    Sort items when possible, otherwise preserve their original order.

  • trace

    Trace wrapped nodes and attach reference information.

  • truncate_dict

    Yield mapping items up to max_dict, then a truncation marker.

  • truncate_list

    Yield list-like items up to max_list, then a truncation marker.

  • wrap_eager

    Wrap obj immediately and memoize the result by object identity.

  • wrap_lazy

    Create a lazily wrapped placeholder for obj.

arepr cached property

arepr: Repr

Return the configured reprlib.Repr instance used for fallback formatting.

The limits mirror the active PrettyOptions.

depth class-attribute instance-attribute

depth: int = 0

options class-attribute instance-attribute

options: PrettyOptions = field(factory=dump)

registry class-attribute instance-attribute

registry: PrettyRegistry = field(default=registry)

trace_cache class-attribute instance-attribute

trace_cache: dict[int, TracedObject] = field(factory=dict)

types class-attribute instance-attribute

types: set[type] = field(factory=set)

wrap_cache class-attribute instance-attribute

wrap_cache: dict[int, WrappedNode] = field(factory=dict)

add_separators staticmethod

add_separators(
    items: Iterable[WrappedItem],
) -> list[WrappedItem]

Add repr-style spacing and trailing commas to a sequence of items.

Source code in src/liblaf/pretty/custom/_context.py
@staticmethod
def add_separators(items: Iterable[WrappedItem]) -> list[WrappedItem]:
    """Add repr-style spacing and trailing commas to a sequence of items."""
    items: list[WrappedItem] = list(items)
    for i, item in enumerate(items):
        if i > 0:
            item.prefix = SPACE
        if i < len(items) - 1:
            item.suffix = COMMA
    return items

container

container(
    obj: Any,
    begin: Text,
    children: Iterable[WrappedItem],
    end: Text,
    indent: Text | None = None,
    *,
    add_separators: bool = True,
    empty: Text | None = None,
    referencable: bool = True,
) -> WrappedContainer

Build a repr-like container node.

Parameters:

  • obj (Any) –

    Original object represented by the container.

  • begin (Text) –

    Opening punctuation, usually styled Rich text such as ( or [.

  • children (Iterable[WrappedItem]) –

    Wrapped child items to render inside the container.

  • end (Text) –

    Closing punctuation.

  • indent (Text | None, default: None ) –

    Indentation used for wrapped layouts. Defaults to the active formatter option.

  • add_separators (bool, default: True ) –

    When True, add repr-style spaces and commas between children before building the container.

  • empty (Text | None, default: None ) –

    Alternate rendering for empty containers such as set().

  • referencable (bool, default: True ) –

    Whether repeated appearances of obj should be rendered as shared references later in the pipeline.

Returns:

Note

Containers are referencable by default. Repeated appearances of the same container can therefore render as shared-reference tags later in the pipeline.

Source code in src/liblaf/pretty/custom/_context.py
def container(
    self,
    obj: Any,
    begin: Text,
    children: Iterable[WrappedItem],
    end: Text,
    indent: Text | None = None,
    *,
    add_separators: bool = True,
    empty: Text | None = None,
    referencable: bool = True,
) -> WrappedContainer:
    """Build a repr-like container node.

    Args:
        obj: Original object represented by the container.
        begin: Opening punctuation, usually styled Rich text such as `(` or `[`.
        children: Wrapped child items to render inside the container.
        end: Closing punctuation.
        indent: Indentation used for wrapped layouts. Defaults to the active
            formatter option.
        add_separators: When `True`, add repr-style spaces and commas between
            children before building the container.
        empty: Alternate rendering for empty containers such as `set()`.
        referencable: Whether repeated appearances of `obj` should be rendered as
            shared references later in the pipeline.

    Returns:
        A wrapped container ready for tracing and lowering.

    Note:
        Containers are referencable by default. Repeated appearances of the
        same container can therefore render as shared-reference tags later
        in the pipeline.
    """
    if indent is None:
        indent: Text = self.options.indent
    if add_separators:
        children: list[WrappedItem] = self.add_separators(children)
    kwargs: dict[str, Any] = {}
    if empty is not None:
        kwargs["empty"] = empty
    return WrappedContainer(
        begin=begin,
        children=children,
        end=end,
        indent=indent,
        identifier=self.identifier(obj),
        referencable=referencable,
        **kwargs,
    )

ellipsis_item

ellipsis_item() -> WrappedItem

Return the positional ellipsis item used for truncated containers.

Source code in src/liblaf/pretty/custom/_context.py
def ellipsis_item(self) -> WrappedItem:
    """Return the positional ellipsis item used for truncated containers."""
    return WrappedPositionalItem.ellipsis()

finish

finish() -> LowerContext

Build the lowering context with disambiguated type names.

Source code in src/liblaf/pretty/stages/wrapped/_context.py
def finish(self) -> LowerContext:
    """Build the lowering context with disambiguated type names."""
    return LowerContext(typenames=disambiguate_typenames(self.types))

identifier

identifier(obj: Any) -> ObjectIdentifier

Return the identity record for obj.

Source code in src/liblaf/pretty/custom/_context.py
def identifier(self, obj: Any) -> ObjectIdentifier:
    """Return the identity record for `obj`."""
    return ObjectIdentifier.from_obj(obj)

key_value

key_value(key: Any, value: Any) -> WrappedItem

Build a key: value item or an ellipsis placeholder when truncated.

Source code in src/liblaf/pretty/custom/_context.py
def key_value(self, key: Any, value: Any) -> WrappedItem:
    """Build a `key: value` item or an ellipsis placeholder when truncated."""
    if key is TRUNCATED or value is TRUNCATED:
        return self.ellipsis_item()
    return WrappedKeyValueItem(key=self.wrap_lazy(key), value=self.wrap_lazy(value))

leaf

leaf(
    obj: Any, text: Text, *, referencable: bool = True
) -> WrappedLeaf

Build a scalar leaf node from Rich text.

Set referencable=False for scalar summaries that should always render inline instead of turning into shared-reference tags.

Source code in src/liblaf/pretty/custom/_context.py
def leaf(self, obj: Any, text: Text, *, referencable: bool = True) -> WrappedLeaf:
    """Build a scalar leaf node from Rich text.

    Set `referencable=False` for scalar summaries that should always render
    inline instead of turning into shared-reference tags.
    """
    return WrappedLeaf(
        value=text, identifier=self.identifier(obj), referencable=referencable
    )

name_value

name_value(
    name: str | Text | None, value: Any
) -> WrappedItem

Build a repr-style name=value item.

Falsey names fall back to positional.

Source code in src/liblaf/pretty/custom/_context.py
def name_value(self, name: str | Text | None, value: Any) -> WrappedItem:
    """Build a repr-style `name=value` item.

    Falsey names fall back to [`positional`][liblaf.pretty.custom.PrettyContext.positional].
    """
    if not name:
        return self.positional(value)
    if isinstance(name, str):
        name = Text(name, "repr.attrib_name")
    return WrappedNameValueItem(name=name, value=self.wrap_lazy(value))

positional

positional(value: Any) -> WrappedItem

Build a positional item or an ellipsis placeholder when truncated.

Source code in src/liblaf/pretty/custom/_context.py
def positional(self, value: Any) -> WrappedItem:
    """Build a positional item or an ellipsis placeholder when truncated."""
    if value is TRUNCATED:
        return self.ellipsis_item()
    return WrappedPositionalItem(value=self.wrap_lazy(value))

possibly_sorted staticmethod

possibly_sorted[T](
    items: Iterable[T],
    *,
    key: Callable[[T], Any] | None = None,
    reverse: bool = False,
) -> Iterable[T]

Sort items when possible, otherwise preserve their original order.

This keeps set- and dict-like output stable when the items are orderable, while still handling unorderable objects gracefully.

Source code in src/liblaf/pretty/custom/_context.py
@staticmethod
def possibly_sorted[T](
    items: Iterable[T],
    *,
    key: Callable[[T], Any] | None = None,
    reverse: bool = False,
) -> Iterable[T]:
    """Sort items when possible, otherwise preserve their original order.

    This keeps set- and dict-like output stable when the items are
    orderable, while still handling unorderable objects gracefully.
    """
    try:
        return sorted(items, key=key, reverse=reverse)
    except Exception:  # noqa: BLE001
        return items

trace

trace(root: WrappedNode) -> TracedNode

Trace wrapped nodes and attach reference information.

Source code in src/liblaf/pretty/custom/_context.py
def trace(self, root: WrappedNode) -> TracedNode:
    """Trace wrapped nodes and attach reference information."""
    children, traced_root = root.trace(self)
    queue: deque[WrappedChild] = deque(children)
    while queue:
        wrapped, self.depth, attach = queue.popleft()
        children, traced = wrapped.trace(self)
        queue.extend(children)
        attach(traced)
    return traced_root

truncate_dict

truncate_dict[K, V](
    items: Iterable[tuple[K, V]],
) -> Generator[tuple[K, V]]

Yield mapping items up to max_dict, then a truncation marker.

Source code in src/liblaf/pretty/custom/_context.py
def truncate_dict[K, V](
    self, items: Iterable[tuple[K, V]]
) -> Generator[tuple[K, V]]:
    """Yield mapping items up to `max_dict`, then a truncation marker."""
    for i, item in enumerate(items):
        if i >= self.options.max_dict:
            yield TRUNCATED, TRUNCATED
            break
        yield item

truncate_list

truncate_list[T](items: Iterable[T]) -> Generator[T]

Yield list-like items up to max_list, then a truncation marker.

Source code in src/liblaf/pretty/custom/_context.py
def truncate_list[T](self, items: Iterable[T]) -> Generator[T]:
    """Yield list-like items up to `max_list`, then a truncation marker."""
    for i, item in enumerate(items):
        if i >= self.options.max_list:
            yield TRUNCATED
            break
        yield item

wrap_eager

wrap_eager(obj: Any) -> WrappedNode

Wrap obj immediately and memoize the result by object identity.

This preserves shared references for referencable objects and avoids rebuilding the same wrapped node repeatedly during one pass.

Source code in src/liblaf/pretty/custom/_context.py
def wrap_eager(self, obj: Any) -> WrappedNode:
    """Wrap `obj` immediately and memoize the result by object identity.

    This preserves shared references for referencable objects and avoids
    rebuilding the same wrapped node repeatedly during one pass.
    """
    id_: int = id(obj)
    if (wrapped := self.wrap_cache.get(id_)) is not None:
        return wrapped
    wrapped: WrappedNode = self.registry(obj, self)
    self.wrap_cache[id_] = wrapped
    return wrapped

wrap_lazy

wrap_lazy(obj: Any) -> WrappedLazy

Create a lazily wrapped placeholder for obj.

Lazy children delay the actual wrapping work until the trace step asks for them.

Source code in src/liblaf/pretty/custom/_context.py
def wrap_lazy(self, obj: Any) -> WrappedLazy:
    """Create a lazily wrapped placeholder for `obj`.

    Lazy children delay the actual wrapping work until the trace step asks
    for them.
    """
    return WrappedLazy(
        factory=lambda: self.wrap_eager(obj), identifier=self.identifier(obj)
    )

PrettyHandler

Bases: Protocol


              flowchart TD
              liblaf.pretty.PrettyHandler[PrettyHandler]

              

              click liblaf.pretty.PrettyHandler href "" "liblaf.pretty.PrettyHandler"
            

Protocol implemented by pretty-printer callbacks.

Handlers receive the object plus the active PrettyContext and either return a wrapped node or None to decline.

Methods:

__call__

__call__(obj: T, ctx: PrettyContext) -> WrappedNode | None
Source code in src/liblaf/pretty/custom/_registry.py
def __call__(self, obj: T, ctx: PrettyContext, /) -> WrappedNode | None: ...

PrettyOptions

Resolved options for a single formatting pass.

These values are usually created from config plus per-call PrettyOverrides.

Attributes:

Parameters:

  • max_level (int) –
  • max_list (int) –
  • max_array (int) –
  • max_dict (int) –
  • max_string (int) –
  • max_long (int) –
  • max_other (int) –
  • indent (Text) –
  • hide_defaults (bool) –

hide_defaults instance-attribute

hide_defaults: bool

indent class-attribute instance-attribute

indent: Text = field(converter=_as_text)

max_array instance-attribute

max_array: int

max_dict instance-attribute

max_dict: int

max_level instance-attribute

max_level: int

max_list instance-attribute

max_list: int

max_long instance-attribute

max_long: int

max_other instance-attribute

max_other: int

max_string instance-attribute

max_string: int

PrettyOverrides typed-dict

PrettyOverrides(
    *,
    max_level: int = ...,
    max_list: int = ...,
    max_array: int = ...,
    max_dict: int = ...,
    max_string: int = ...,
    max_long: int = ...,
    max_other: int = ...,
    indent: str | Text = ...,
    hide_defaults: bool = ...,
)

Bases: TypedDict


              flowchart TD
              liblaf.pretty.PrettyOverrides[PrettyOverrides]

              

              click liblaf.pretty.PrettyOverrides href "" "liblaf.pretty.PrettyOverrides"
            

Keyword overrides accepted by the public formatting functions.

Attributes:

Parameters:

  • max_level (int) –
  • max_list (int) –
  • max_array (int) –
  • max_dict (int) –
  • max_string (int) –
  • max_long (int) –
  • max_other (int) –
  • indent (str | Text) –
  • hide_defaults (bool) –

Parameters:

  • max_level (int, default: ... ) –
  • max_list (int, default: ... ) –
  • max_array (int, default: ... ) –
  • max_dict (int, default: ... ) –
  • max_string (int, default: ... ) –
  • max_long (int, default: ... ) –
  • max_other (int, default: ... ) –
  • indent (str | Text, default: ... ) –
  • hide_defaults (bool, default: ... ) –

pformat

pformat(
    obj: Any,
    *,
    max_level: int = ...,
    max_list: int = ...,
    max_array: int = ...,
    max_dict: int = ...,
    max_string: int = ...,
    max_long: int = ...,
    max_other: int = ...,
    indent: str | Text = ...,
    hide_defaults: bool = ...,
) -> LoweredNode

Build a width-aware Rich renderable for obj.

pformat() resolves the active configuration, wraps obj, traces shared and cyclic references, and lowers the result into a Rich renderable. The returned object is rendered later by Rich, so the final line breaks still depend on the target console width.

Parameters:

  • obj (Any) –

    Object to format.

  • max_level (int, default: ... ) –
  • max_list (int, default: ... ) –
  • max_array (int, default: ... ) –
  • max_dict (int, default: ... ) –
  • max_string (int, default: ... ) –
  • max_long (int, default: ... ) –
  • max_other (int, default: ... ) –
  • indent (str | Text, default: ... ) –
  • hide_defaults (bool, default: ... ) –

Returns:

  • LoweredNode

    A lowered renderable that can be passed to console.print(...) or converted

  • LoweredNode

    to deterministic plain text with to_plain(console=...).

Source code in src/liblaf/pretty/_api.py
def pformat(obj: Any, **kwargs: Unpack[PrettyOverrides]) -> LoweredNode:
    """Build a width-aware Rich renderable for `obj`.

    `pformat()` resolves the active configuration, wraps `obj`, traces shared
    and cyclic references, and lowers the result into a Rich renderable. The
    returned object is rendered later by Rich, so the final line breaks still
    depend on the target console width.

    Args:
        obj: Object to format.
        **kwargs: Per-call overrides layered on top of
            [`config`][liblaf.pretty.config].

    Returns:
        A lowered renderable that can be passed to `console.print(...)` or converted
        to deterministic plain text with `to_plain(console=...)`.
    """
    options: PrettyOptions = PrettyOptions(**{**config.to_dict(), **kwargs})
    pretty_ctx: PrettyContext = PrettyContext(options=options)
    wrapped: WrappedNode = pretty_ctx.wrap_lazy(obj)
    traced: TracedNode = pretty_ctx.trace(wrapped)
    lower_ctx: LowerContext = pretty_ctx.finish()
    lowered: LoweredNode = traced.lower(lower_ctx)
    return lowered

pprint

pprint(
    obj: Any,
    *,
    console: Console | None = None,
    max_level: int = ...,
    max_list: int = ...,
    max_array: int = ...,
    max_dict: int = ...,
    max_string: int = ...,
    max_long: int = ...,
    max_other: int = ...,
    indent: str | Text = ...,
    hide_defaults: bool = ...,
) -> None

Format obj and print it through a Rich console.

This is the side-effecting companion to pformat.

Parameters:

  • obj (Any) –

    Object to format.

  • console (Console | None, default: None ) –

    Console to render into. When omitted, the active global Rich console is used.

  • max_level (int, default: ... ) –
  • max_list (int, default: ... ) –
  • max_array (int, default: ... ) –
  • max_dict (int, default: ... ) –
  • max_string (int, default: ... ) –
  • max_long (int, default: ... ) –
  • max_other (int, default: ... ) –
  • indent (str | Text, default: ... ) –
  • hide_defaults (bool, default: ... ) –
Source code in src/liblaf/pretty/_api.py
def pprint(
    obj: Any, *, console: Console | None = None, **kwargs: Unpack[PrettyOverrides]
) -> None:
    """Format `obj` and print it through a Rich console.

    This is the side-effecting companion to [`pformat`][liblaf.pretty.pformat].

    Args:
        obj: Object to format.
        console: Console to render into. When omitted, the active global Rich console
            is used.
        **kwargs: Per-call overrides forwarded to [`pformat`][liblaf.pretty.pformat].
    """
    if console is None:
        console: Console = rich.get_console()
    lowered: LoweredNode = pformat(obj, **kwargs)
    console.print(lowered)