Source code for _pytest._io.saferepr
import pprint
import reprlib
from typing import Any
[docs]def _try_repr_or_str(obj):
try:
return repr(obj)
except (KeyboardInterrupt, SystemExit):
raise
except BaseException:
return '{}("{}")'.format(type(obj).__name__, obj)
[docs]def _format_repr_exception(exc: BaseException, obj: Any) -> str:
try:
exc_info = _try_repr_or_str(exc)
except (KeyboardInterrupt, SystemExit):
raise
except BaseException as exc:
exc_info = "unpresentable exception ({})".format(_try_repr_or_str(exc))
return "<[{} raised in repr()] {} object at 0x{:x}>".format(
exc_info, obj.__class__.__name__, id(obj)
)
[docs]def _ellipsize(s: str, maxsize: int) -> str:
if len(s) > maxsize:
i = max(0, (maxsize - 3) // 2)
j = max(0, maxsize - 3 - i)
return s[:i] + "..." + s[len(s) - j :]
return s
[docs]class SafeRepr(reprlib.Repr):
"""subclass of repr.Repr that limits the resulting size of repr()
and includes information on exceptions raised during the call.
"""
def __init__(self, maxsize: int) -> None:
super().__init__()
self.maxstring = maxsize
self.maxsize = maxsize
[docs] def repr(self, x: Any) -> str:
try:
s = super().repr(x)
except (KeyboardInterrupt, SystemExit):
raise
except BaseException as exc:
s = _format_repr_exception(exc, x)
return _ellipsize(s, self.maxsize)
[docs] def repr_instance(self, x: Any, level: int) -> str:
try:
s = repr(x)
except (KeyboardInterrupt, SystemExit):
raise
except BaseException as exc:
s = _format_repr_exception(exc, x)
return _ellipsize(s, self.maxsize)
[docs]def safeformat(obj: Any) -> str:
"""return a pretty printed string for the given object.
Failing __repr__ functions of user instances will be represented
with a short exception info.
"""
try:
return pprint.pformat(obj)
except Exception as exc:
return _format_repr_exception(exc, obj)
[docs]def saferepr(obj: Any, maxsize: int = 240) -> str:
"""return a size-limited safe repr-string for the given object.
Failing __repr__ functions of user instances will be represented
with a short exception info and 'saferepr' generally takes
care to never raise exceptions itself. This function is a wrapper
around the Repr/reprlib functionality of the standard 2.6 lib.
"""
return SafeRepr(maxsize).repr(obj)
[docs]class AlwaysDispatchingPrettyPrinter(pprint.PrettyPrinter):
"""PrettyPrinter that always dispatches (regardless of width)."""
[docs] def _format(self, object, stream, indent, allowance, context, level):
p = self._dispatch.get(type(object).__repr__, None)
objid = id(object)
if objid in context or p is None:
return super()._format(object, stream, indent, allowance, context, level)
context[objid] = 1
p(self, object, stream, indent, allowance, context, level + 1)
del context[objid]
[docs]def _pformat_dispatch(object, indent=1, width=80, depth=None, *, compact=False):
return AlwaysDispatchingPrettyPrinter(
indent=indent, width=width, depth=depth, compact=compact
).pformat(object)