Skip to content
Permalink
Browse files

saferepr: Avoid indirect function calls

The DRY savings they provide are rather small, while they make it harder
to type-check, and IMO harder to understand.
  • Loading branch information...
bluetech committed Jul 14, 2019
1 parent c7aacc9 commit b47e1679e02029b847a9932e68cdf5db207991b8
Showing with 30 additions and 23 deletions.
  1. +30 −23 src/_pytest/_io/saferepr.py
@@ -2,19 +2,23 @@
import reprlib


def _call_and_format_exception(call, x, *args):
def _format_repr_exception(exc, obj):
exc_name = type(exc).__name__
try:
# Try the vanilla repr and make sure that the result is a string
return call(x, *args)
except Exception as exc:
exc_name = type(exc).__name__
try:
exc_info = str(exc)
except Exception:
exc_info = "unknown"
return '<[{}("{}") raised in repr()] {} object at 0x{:x}>'.format(
exc_name, exc_info, x.__class__.__name__, id(x)
)
exc_info = str(exc)
except Exception:
exc_info = "unknown"
return '<[{}("{}") raised in repr()] {} object at 0x{:x}>'.format(
exc_name, exc_info, obj.__class__.__name__, id(obj)
)


def _ellipsize(s, maxsize):
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


class SafeRepr(reprlib.Repr):
@@ -28,26 +32,29 @@ def __init__(self, maxsize):
self.maxsize = maxsize

def repr(self, x):
return self._callhelper(reprlib.Repr.repr, self, x)
try:
s = super().repr(x)
except Exception as exc:
s = _format_repr_exception(exc, x)
return _ellipsize(s, self.maxsize)

def repr_instance(self, x, level):
return self._callhelper(repr, x)

def _callhelper(self, call, x, *args):
s = _call_and_format_exception(call, x, *args)
if len(s) > self.maxsize:
i = max(0, (self.maxsize - 3) // 2)
j = max(0, self.maxsize - 3 - i)
s = s[:i] + "..." + s[len(s) - j :]
return s
try:
s = repr(x)
except Exception as exc:
s = _format_repr_exception(exc, x)
return _ellipsize(s, self.maxsize)


def safeformat(obj):
"""return a pretty printed string for the given object.
Failing __repr__ functions of user instances will be represented
with a short exception info.
"""
return _call_and_format_exception(pprint.pformat, obj)
try:
return pprint.pformat(obj)
except Exception as exc:
return _format_repr_exception(exc, obj)


def saferepr(obj, maxsize=240):

0 comments on commit b47e167

Please sign in to comment.
You can’t perform that action at this time.