Writes like Node's console: log / info / debug /
count / time_* / table / dir to stdout, warn /
error / trace / assert_ to stderr, each line indented two
spaces per open group. Streams are read at each call, so pytest's
capture and contextlib.redirect_stdout see the output. Misused
counters and timers warn with RuntimeWarning (Node's process
warnings).
Functions#
__init__#
__init__() -> Nonedef __init__(self) -> None:
self._indent = 0
self._lock = threading.Lock()
self._counts: dict[str, int] = {}
self._timers: dict[str, int] = {}log#
log(*args) -> None| Parameter | Type | Description |
|---|---|---|
args | object = () |
def log(self, *args: object) -> None:
self._write(sys.stdout, args)info#
info(*args) -> None| Parameter | Type | Description |
|---|---|---|
args | object = () |
def info(self, *args: object) -> None:
self._write(sys.stdout, args)debug#
debug(*args) -> None| Parameter | Type | Description |
|---|---|---|
args | object = () |
def debug(self, *args: object) -> None:
self._write(sys.stdout, args)warn#
warn(*args) -> None| Parameter | Type | Description |
|---|---|---|
args | object = () |
def warn(self, *args: object) -> None:
self._write(sys.stderr, args)error#
error(*args) -> None| Parameter | Type | Description |
|---|---|---|
args | object = () |
def error(self, *args: object) -> None:
self._write(sys.stderr, args)trace#
trace(*args) -> None| Parameter | Type | Description |
|---|---|---|
args | object = () |
def trace(self, *args: object) -> None:
self._write(sys.stderr, args, "Trace: ")assert_#
assert_(condition, *args) -> None| Parameter | Type | Description |
|---|---|---|
condition | bool | |
args | object = () |
def assert_(self, condition: bool, *args: object) -> None:
if condition:
return
if args and isinstance(args[0], str):
self.warn(f"Assertion failed: {args[0]}", *args[1:])
else:
self.warn("Assertion failed", *args)clear#
clear() -> Nonedef clear(self) -> None:
if sys.stdout.isatty():
with self._lock:
sys.stdout.write(_CLEAR)count#
count(label='default') -> None| Parameter | Type | Description |
|---|---|---|
label | str = 'default' |
def count(self, label: str = "default") -> None:
n = self._counts.get(label, 0) + 1
self._counts[label] = n
self.log(f"{label}: {n}")count_reset#
count_reset(label='default') -> None| Parameter | Type | Description |
|---|---|---|
label | str = 'default' |
def count_reset(self, label: str = "default") -> None:
if self._counts.pop(label, None) is None:
warnings.warn(f"Count for '{label}' does not exist", RuntimeWarning, stacklevel=2)dir#
dir(item) -> None| Parameter | Type | Description |
|---|---|---|
item | object |
def dir(self, item: object) -> None:
self._write(sys.stdout, (pprint.pformat(item),))group#
group(*args) -> None| Parameter | Type | Description |
|---|---|---|
args | object = () |
def group(self, *args: object) -> None:
if args:
self.log(*args)
self._indent += 1group_collapsed#
group_collapsed(*args) -> None| Parameter | Type | Description |
|---|---|---|
args | object = () |
def group_collapsed(self, *args: object) -> None:
self.group(*args)group_end#
group_end() -> Nonedef group_end(self) -> None:
self._indent = max(0, self._indent - 1)table#
table(data, properties=None) -> None| Parameter | Type | Description |
|---|---|---|
data | object | |
properties | Sequence[str] | None = None |
def table(self, data: object, properties: Sequence[str] | None = None) -> None:
drawn = format_table(data, properties)
self.log(data if drawn is None else drawn)time#
time(label='default') -> None| Parameter | Type | Description |
|---|---|---|
label | str = 'default' |
def time(self, label: str = "default") -> None:
if label in self._timers:
warnings.warn(
f"Label '{label}' already exists for console.time()", RuntimeWarning, stacklevel=2
)
return
self._timers[label] = time.perf_counter_ns()time_end#
time_end(label='default') -> None| Parameter | Type | Description |
|---|---|---|
label | str = 'default' |
def time_end(self, label: str = "default") -> None:
if self._log_time(label, "time_end", ()):
del self._timers[label]time_log#
time_log(label='default', *args) -> None| Parameter | Type | Description |
|---|---|---|
label | str = 'default' | |
args | object = () |
def time_log(self, label: str = "default", *args: object) -> None:
self._log_time(label, "time_log", args)