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
builtin_repr = repr
from six.moves import reprlib
reprlib = py.builtin._tryimport('repr', 'reprlib')
class SafeRepr(reprlib.Repr):
""" subclass of repr.Repr that limits the resulting size of repr()
and includes information on exceptions raised during the call.
"""subclass of repr.Repr that limits the resulting size of repr()
and includes information on exceptions raised during the call.
"""
def repr(self, x):
return self._callhelper(reprlib.Repr.repr, self, x)
@ -16,48 +15,50 @@ class SafeRepr(reprlib.Repr):
# Strictly speaking wrong on narrow builds
def repr(u):
if "'" not in u:
return py.builtin._totext("'%s'") % u
return u"'%s'" % u
elif '"' not in u:
return py.builtin._totext('"%s"') % u
return u'"%s"' % u
else:
return py.builtin._totext("'%s'") % u.replace("'", r"\'")
s = repr(x[:self.maxstring])
return u"'%s'" % u.replace("'", r"\'")
s = repr(x[: self.maxstring])
if len(s) > self.maxstring:
i = max(0, (self.maxstring-3)//2)
j = max(0, self.maxstring-3-i)
s = repr(x[:i] + x[len(x)-j:])
s = s[:i] + '...' + s[len(s)-j:]
i = max(0, (self.maxstring - 3) // 2)
j = max(0, self.maxstring - 3 - i)
s = repr(x[:i] + x[len(x) - j :])
s = s[:i] + "..." + s[len(s) - j :]
return s
def repr_instance(self, x, level):
return self._callhelper(builtin_repr, x)
return self._callhelper(repr, x)
def _callhelper(self, call, x, *args):
try:
# Try the vanilla repr and make sure that the result is a string
s = call(x, *args)
except py.builtin._sysex:
raise
except:
except Exception:
cls, e, tb = sys.exc_info()
exc_name = getattr(cls, '__name__', 'unknown')
exc_name = getattr(cls, "__name__", "unknown")
try:
exc_info = str(e)
except py.builtin._sysex:
raise
except:
exc_info = 'unknown'
except Exception:
exc_info = "unknown"
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:
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:]
i = max(0, (self.maxsize - 3) // 2)
j = max(0, self.maxsize - 3 - i)
s = s[:i] + "..." + s[len(s) - j :]
return s
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
with a short exception info and 'saferepr' generally takes
care to never raise exceptions itself. This function is a wrapper

View File

@ -1,75 +1,66 @@
# -*- 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):
s = saferepr('x'*50, maxsize=25)
assert len(s) == 25
expected = repr('x'*10 + '...' + 'x'*10)
assert s == expected
def test_maxsize():
s = saferepr("x" * 50, maxsize=25)
assert len(s) == 25
expected = repr("x" * 10 + "..." + "x" * 10)
assert s == expected
def test_maxsize_error_on_instance(self):
class A:
def __repr__(self):
raise ValueError('...')
s = saferepr(('*'*50, A()), maxsize=25)
assert len(s) == 25
assert s[0] == '(' and s[-1] == ')'
def test_maxsize_error_on_instance():
class A:
def __repr__():
raise ValueError("...")
def test_exceptions(self):
class BrokenRepr:
def __init__(self, ex):
self.ex = ex
foo = 0
def __repr__(self):
raise self.ex
class BrokenReprException(Exception):
__str__ = None
__repr__ = None
assert 'Exception' in saferepr(BrokenRepr(Exception("broken")))
s = saferepr(BrokenReprException("really broken"))
assert 'TypeError' in s
assert 'TypeError' in saferepr(BrokenRepr("string"))
s = saferepr(("*" * 50, A()), maxsize=25)
assert len(s) == 25
assert s[0] == "(" and s[-1] == ")"
s2 = saferepr(BrokenRepr(BrokenReprException('omg even worse')))
assert 'NameError' not 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_exceptions():
class BrokenRepr:
def __init__(self, ex):
self.ex = ex
def test_repr_on_newstyle(self):
class Function(object):
def __repr__(self):
return "<%s>" %(self.name)
try:
s = saferepr(Function())
except Exception:
py.test.fail("saferepr failed for newstyle class")
def __repr__(self):
raise self.ex
def test_unicode(self):
val = py.builtin._totext('£€', 'utf-8')
reprval = py.builtin._totext("'£€'", 'utf-8')
assert saferepr(val) == reprval
class BrokenReprException(Exception):
__str__ = None
__repr__ = None
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)
assert "Exception" in saferepr(BrokenRepr(Exception("broken")))
s = saferepr(BrokenReprException("really broken"))
assert "TypeError" in s
assert "TypeError" in saferepr(BrokenRepr("string"))
s2 = saferepr(BrokenRepr(BrokenReprException("omg even worse")))
assert "NameError" not in s2
assert "unknown" in s2
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):
def __repr__(self):
return "<%s>" % (self.name)
assert saferepr(Function())
def test_unicode():
val = u"£€"
reprval = u"'£€'"
assert saferepr(val) == reprval