Source code for pyworldatlas.models._display

"""How results look when printed: short by default, every field on request.

Every result prints as one readable line, such as
``CountryRanking('#1 Canada: 202,080 km')``. Turn on details to see every
field instead, as plain Python dataclasses show them::

    import pyworldatlas
    pyworldatlas.show_details()           # from now on
    with pyworldatlas.show_details():     # only inside this block
        ...

Setting the environment variable ``PYWORLDATLAS_DETAILS=1`` turns details on
from the start. Details change only how results are printed, never their
values, and ``to_dict()`` always returns every field.
"""

from __future__ import annotations

from dataclasses import fields, is_dataclass
import os
from typing import Any

_STATE = {"details": os.environ.get("PYWORLDATLAS_DETAILS", "").strip().casefold() not in {"", "0", "false", "no"}}


[docs] class show_details: # named like a function because it is used like one """Print every field of a result instead of the short one-line form. ``show_details()`` turns details on, ``show_details(False)`` turns them off, and ``with show_details(): ...`` turns them on only inside the block. >>> import pyworldatlas >>> with pyworldatlas.show_details(): ... pass """
[docs] def __init__(self, on: bool = True) -> None: self._previous = _STATE["details"] _STATE["details"] = bool(on)
def __enter__(self) -> show_details: return self def __exit__(self, *exc_info: object) -> None: _STATE["details"] = self._previous
def details_shown() -> bool: """Return whether results currently print every field.""" return _STATE["details"] def friendly_repr(value: Any, short: str) -> str: """Return ``Name(short)``, or ``Name(field=value, ...)`` when details are on. ``short`` is the readable inside of the repr, already quoted where it is text, such as ``"'#1 Canada: 202,080 km'"``. """ name = type(value).__name__ if _STATE["details"] and is_dataclass(value): parts = ", ".join(f"{field.name}={getattr(value, field.name)!r}" for field in fields(value) if field.repr) return f"{name}({parts})" return f"{name}({short})"