Skip to content

Improve feedback/information with "broken repr" #1118

Description

@blueyed

If the __repr__ of a local object fails, it gets reported as "<broken repr>":

if PY2:
def safe_repr(value):
# type: (Any) -> str
try:
rv = repr(value).decode("utf-8", "replace")
# At this point `rv` contains a bunch of literal escape codes, like
# this (exaggerated example):
#
# u"\\x2f"
#
# But we want to show this string as:
#
# u"/"
try:
# unicode-escape does this job, but can only decode latin1. So we
# attempt to encode in latin1.
return rv.encode("latin1").decode("unicode-escape")
except Exception:
# Since usually strings aren't latin1 this can break. In those
# cases we just give up.
return rv
except Exception:
# If e.g. the call to `repr` already fails
return u"<broken repr>"
else:
def safe_repr(value):
# type: (Any) -> str
try:
return repr(value)
except Exception:
return "<broken repr>"

It would be more helpful if it would include more information there, e.g. at least the class name of the exception.
It could also be something more sophisticated like:

def _try_repr_or_str(obj):
    try:
        return repr(obj)
    except (KeyboardInterrupt, SystemExit):
        raise
    except BaseException:
        return '{}("{}")'.format(type(obj).__name__, obj)


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, type(obj).__name__, id(obj)
    )

(via https://github.com/blueyed/pytest/blob/8eb380425395332ffdf2cd42b8d7cf8ffab2ea2e/src/_pytest/_io/saferepr.py#L6-L24)

This would help with investigating why a repr is broken actually, e.g. with celery/py-amqp#361.

(slightly related: there was some related (still open) PR for raven-python about this already: getsentry/raven-python#1294)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions