Skip to content

Instantly share code, notes, and snippets.

@mypy-play
Created September 29, 2022 21:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mypy-play/3f14bad29e24938e01011f40c34d48b5 to your computer and use it in GitHub Desktop.
Save mypy-play/3f14bad29e24938e01011f40c34d48b5 to your computer and use it in GitHub Desktop.
Shared via mypy Playground
import builtins
from collections.abc import Callable
from typing import Any, Generic, TypeVar, overload
T = TypeVar('T')
def indent(s: str, spaces: int | str = 4) -> str:
if isinstance(spaces, int):
spaces = ' ' * spaces
return ''.join(spaces+line for line in s.splitlines(True))
class _LogWrapper(Generic[T]):
"""Wraps an object with arbitrary str and/or repr conversions.
Intended for logging, to ensure that expensive string-ifying operations are only
performed when log messages are actually generated, and are not performed otherwise.
Example:
.. code-block::
import numpy as np
data = np.arange(100).reshape((10, 10))
import logging
logger = logging.getLogger('my.logger')
logger.debug('This is the data: %r', _LogWrapper(data, repr=lambda o: indent(repr(o), 2)))
"""
obj: T
repr: Callable[[T], builtins.str]
str: Callable[[T], builtins.str]
@overload
def __init__(
self: _LogWrapper[None],
obj: None = ...,
*,
repr: Callable[[None], builtins.str] = ...,
str: Callable[[None], builtins.str] = ...,
) -> None: ...
@overload
def __init__(
self: _LogWrapper[T],
obj: T = ...,
*,
repr: Callable[[T], builtins.str] = ...,
str: Callable[[T], builtins.str] = ...,
) -> None: ...
def __init__(
self: _LogWrapper[T] | _LogWrapper[None],
obj: T | None = None,
*,
repr: Callable[[T], builtins.str] | Callable[[None], builtins.str] = builtins.str,
str: Callable[[T], builtins.str] | Callable[[None], builtins.str] = builtins.str,
) -> None:
self.obj = obj
self.repr = repr
self.str = str
def __repr__(self) -> builtins.str:
return self.repr(self.obj)
def __str__(self) -> builtins.str:
return self.str(self.obj)
import logging
import json
logger = logging.getLogger('my.logger')
x = [list(range(i*10, i*10 + 10)) for i in range(10)]
logger.debug(
'This is the data: %r',
_LogWrapper(x, repr=lambda o: indent(json.dumps(o, indent=2), 2))
)
reveal_type(
_LogWrapper(str=lambda o: '< ... there is nothing here ... >')
)
reveal_type(
_LogWrapper(x, repr=lambda o: indent(json.dumps(o, indent=2), 2))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment