Fix linting errors and py references in saferepr.py

This commit is contained in:
Anthony Sottile 2019-01-20 10:50:18 -08:00
parent dbb6c18c44
commit 095ce2ca7f
2 changed files with 80 additions and 88 deletions

View File

@ -1,14 +1,13 @@
import py
import sys import sys
builtin_repr = repr from six.moves import reprlib
reprlib = py.builtin._tryimport('repr', 'reprlib')
class SafeRepr(reprlib.Repr): class SafeRepr(reprlib.Repr):
"""subclass of repr.Repr that limits the resulting size of repr() """subclass of repr.Repr that limits the resulting size of repr()
and includes information on exceptions raised during the call. and includes information on exceptions raised during the call.
""" """
def repr(self, x): def repr(self, x):
return self._callhelper(reprlib.Repr.repr, self, x) return self._callhelper(reprlib.Repr.repr, self, x)
@ -16,46 +15,48 @@ class SafeRepr(reprlib.Repr):
# Strictly speaking wrong on narrow builds # Strictly speaking wrong on narrow builds
def repr(u): def repr(u):
if "'" not in u: if "'" not in u:
return py.builtin._totext("'%s'") % u return u"'%s'" % u
elif '"' not in u: elif '"' not in u:
return py.builtin._totext('"%s"') % u return u'"%s"' % u
else: else:
return py.builtin._totext("'%s'") % u.replace("'", r"\'") return u"'%s'" % u.replace("'", r"\'")
s = repr(x[: self.maxstring]) s = repr(x[: self.maxstring])
if len(s) > self.maxstring: if len(s) > self.maxstring:
i = max(0, (self.maxstring - 3) // 2) i = max(0, (self.maxstring - 3) // 2)
j = max(0, self.maxstring - 3 - i) j = max(0, self.maxstring - 3 - i)
s = repr(x[:i] + x[len(x) - j :]) s = repr(x[:i] + x[len(x) - j :])
s = s[:i] + '...' + s[len(s)-j:] s = s[:i] + "..." + s[len(s) - j :]
return s return s
def repr_instance(self, x, level): def repr_instance(self, x, level):
return self._callhelper(builtin_repr, x) return self._callhelper(repr, x)
def _callhelper(self, call, x, *args): def _callhelper(self, call, x, *args):
try: try:
# Try the vanilla repr and make sure that the result is a string # Try the vanilla repr and make sure that the result is a string
s = call(x, *args) s = call(x, *args)
except py.builtin._sysex: except Exception:
raise
except:
cls, e, tb = sys.exc_info() cls, e, tb = sys.exc_info()
exc_name = getattr(cls, '__name__', 'unknown') exc_name = getattr(cls, "__name__", "unknown")
try: try:
exc_info = str(e) exc_info = str(e)
except py.builtin._sysex: except Exception:
raise exc_info = "unknown"
except:
exc_info = 'unknown'
return '<[%s("%s") raised in repr()] %s object at 0x%x>' % ( return '<[%s("%s") raised in repr()] %s object at 0x%x>' % (
exc_name, exc_info, x.__class__.__name__, id(x)) exc_name,
exc_info,
x.__class__.__name__,
id(x),
)
else: else:
if len(s) > self.maxsize: if len(s) > self.maxsize:
i = max(0, (self.maxsize - 3) // 2) i = max(0, (self.maxsize - 3) // 2)
j = max(0, self.maxsize - 3 - i) j = max(0, self.maxsize - 3 - i)
s = s[:i] + '...' + s[len(s)-j:] s = s[:i] + "..." + s[len(s) - j :]
return s return s
def saferepr(obj, maxsize=240): def saferepr(obj, maxsize=240):
"""return a size-limited safe repr-string for the given object. """return a size-limited safe repr-string for the given object.
Failing __repr__ functions of user instances will be represented Failing __repr__ functions of user instances will be represented

View File

@ -1,75 +1,66 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from _pytest._io.saferepr import saferepr
from __future__ import generators
import py
import sys
saferepr = py.io.saferepr def test_simple_repr():
assert saferepr(1) == "1"
assert saferepr(None) == "None"
class TestSafeRepr:
def test_simple_repr(self):
assert saferepr(1) == '1'
assert saferepr(None) == 'None'
def test_maxsize(self): def test_maxsize():
s = saferepr('x'*50, maxsize=25) s = saferepr("x" * 50, maxsize=25)
assert len(s) == 25 assert len(s) == 25
expected = repr('x'*10 + '...' + 'x'*10) expected = repr("x" * 10 + "..." + "x" * 10)
assert s == expected assert s == expected
def test_maxsize_error_on_instance(self):
def test_maxsize_error_on_instance():
class A: class A:
def __repr__(self): def __repr__():
raise ValueError('...') raise ValueError("...")
s = saferepr(('*'*50, A()), maxsize=25) s = saferepr(("*" * 50, A()), maxsize=25)
assert len(s) == 25 assert len(s) == 25
assert s[0] == '(' and s[-1] == ')' assert s[0] == "(" and s[-1] == ")"
def test_exceptions(self):
def test_exceptions():
class BrokenRepr: class BrokenRepr:
def __init__(self, ex): def __init__(self, ex):
self.ex = ex self.ex = ex
foo = 0
def __repr__(self): def __repr__(self):
raise self.ex raise self.ex
class BrokenReprException(Exception): class BrokenReprException(Exception):
__str__ = None __str__ = None
__repr__ = None __repr__ = None
assert 'Exception' in saferepr(BrokenRepr(Exception("broken")))
assert "Exception" in saferepr(BrokenRepr(Exception("broken")))
s = saferepr(BrokenReprException("really broken")) s = saferepr(BrokenReprException("really broken"))
assert 'TypeError' in s assert "TypeError" in s
assert 'TypeError' in saferepr(BrokenRepr("string")) assert "TypeError" in saferepr(BrokenRepr("string"))
s2 = saferepr(BrokenRepr(BrokenReprException('omg even worse'))) s2 = saferepr(BrokenRepr(BrokenReprException("omg even worse")))
assert 'NameError' not in s2 assert "NameError" not in s2
assert 'unknown' in s2 assert "unknown" in s2
def test_big_repr(self):
from py._io.saferepr import SafeRepr
assert len(saferepr(range(1000))) <= \
len('[' + SafeRepr().maxlist * "1000" + ']')
def test_repr_on_newstyle(self): def test_big_repr():
from _pytest._io.saferepr import SafeRepr
assert len(saferepr(range(1000))) <= len("[" + SafeRepr().maxlist * "1000" + "]")
def test_repr_on_newstyle():
class Function(object): class Function(object):
def __repr__(self): def __repr__(self):
return "<%s>" % (self.name) return "<%s>" % (self.name)
try:
s = saferepr(Function())
except Exception:
py.test.fail("saferepr failed for newstyle class")
def test_unicode(self): assert saferepr(Function())
val = py.builtin._totext('£€', 'utf-8')
reprval = py.builtin._totext("'£€'", 'utf-8')
def test_unicode():
val = u"£€"
reprval = u"'£€'"
assert saferepr(val) == reprval assert saferepr(val) == reprval
def test_unicode_handling():
value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
def f():
raise Exception(value)
excinfo = py.test.raises(Exception, f)
s = str(excinfo)
if sys.version_info[0] < 3:
u = unicode(excinfo)