Source code for pycommons.io.console

"""The `logger` routine for writing a log string to stdout."""
import datetime
from contextlib import AbstractContextManager, nullcontext
from typing import Callable, Final

#: the "now" function
__DTN: Final[Callable[[], datetime.datetime]] = datetime.datetime.now


[docs] def logger(message: str, note: str = "", lock: AbstractContextManager = nullcontext()) -> None: """ Write a message to the console log. The line starts with the current date and time, includes the note, and then the message string after an ": ". This function can use a `lock` context to prevent multiple processes or threads to write to the console at the same time. :param message: the message :param note: a note to put between the time and the message :param lock: the lock to prevent multiple threads to write log output at the same time >>> from io import StringIO >>> from contextlib import redirect_stdout >>> sio = StringIO() >>> dt1 = datetime.datetime.now() >>> with redirect_stdout(sio): ... logger("hello world!") >>> line = sio.getvalue().strip() >>> print(line[26:]) : hello world! >>> dt2 = datetime.datetime.now() >>> dtx = datetime.datetime.strptime(line[:26], "%Y-%m-%d %H:%M:%S.%f") >>> dt1 <= dtx <= dt2 True >>> sio = StringIO() >>> with redirect_stdout(sio): ... logger("hello world!", "note") >>> line = sio.getvalue().strip() >>> print(line[26:]) note: hello world! >>> from contextlib import AbstractContextManager >>> class T: ... def __enter__(self): ... print("x") ... def __exit__(self, exc_type, exc_val, exc_tb): ... print("y") >>> sio = StringIO() >>> with redirect_stdout(sio): ... logger("hello world!", "", T()) >>> sio.seek(0) 0 >>> lines = sio.readlines() >>> print(lines[0].rstrip()) x >>> print(lines[1][26:].rstrip()) : hello world! >>> print(lines[2].rstrip()) y >>> sio = StringIO() >>> with redirect_stdout(sio): ... logger("hello world!", "note", T()) >>> sio.seek(0) 0 >>> lines = sio.readlines() >>> print(lines[0].rstrip()) x >>> print(lines[1][26:].rstrip()) note: hello world! >>> print(lines[2].rstrip()) y """ text: Final[str] = f"{__DTN()}{note}: {message}" with lock: print(text, flush=True) # noqa