fix issue94 make reporting more robust against bogus source code
(and internally be more careful when presenting unexpected byte sequences) also make py.code.Source accept a list of lines directly. --HG-- branch : trunk
This commit is contained in:
parent
93f91c9607
commit
578cba20d4
|
@ -17,6 +17,9 @@ Changes between 1.3.0 and 1.3.1
|
||||||
declarative approach with the @py.test.mark.xfail cannot
|
declarative approach with the @py.test.mark.xfail cannot
|
||||||
be used as it would mark all configurations as xfail.
|
be used as it would mark all configurations as xfail.
|
||||||
|
|
||||||
|
- fix issue94: make reporting more robust against bogus source code
|
||||||
|
(and internally be more careful when presenting unexpected byte sequences)
|
||||||
|
|
||||||
- improve and refine letter reporting in the progress bar:
|
- improve and refine letter reporting in the progress bar:
|
||||||
. pass
|
. pass
|
||||||
f failed test
|
f failed test
|
||||||
|
|
|
@ -26,6 +26,8 @@ class Source(object):
|
||||||
partlines = []
|
partlines = []
|
||||||
if isinstance(part, Source):
|
if isinstance(part, Source):
|
||||||
partlines = part.lines
|
partlines = part.lines
|
||||||
|
elif isinstance(part, (tuple, list)):
|
||||||
|
partlines = [x.rstrip("\n") for x in part]
|
||||||
elif isinstance(part, py.builtin._basestring):
|
elif isinstance(part, py.builtin._basestring):
|
||||||
partlines = part.split('\n')
|
partlines = part.split('\n')
|
||||||
if rstrip:
|
if rstrip:
|
||||||
|
@ -172,7 +174,9 @@ class Source(object):
|
||||||
try:
|
try:
|
||||||
#compile(source+'\n', "x", "exec")
|
#compile(source+'\n', "x", "exec")
|
||||||
syntax_checker(source+'\n')
|
syntax_checker(source+'\n')
|
||||||
except SyntaxError:
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -110,7 +110,7 @@ class TmpTestdir:
|
||||||
def _makefile(self, ext, args, kwargs):
|
def _makefile(self, ext, args, kwargs):
|
||||||
items = list(kwargs.items())
|
items = list(kwargs.items())
|
||||||
if args:
|
if args:
|
||||||
source = "\n".join(map(str, args))
|
source = "\n".join(map(str, args)) + "\n"
|
||||||
basename = self.request.function.__name__
|
basename = self.request.function.__name__
|
||||||
items.insert(0, (basename, source))
|
items.insert(0, (basename, source))
|
||||||
ret = None
|
ret = None
|
||||||
|
@ -294,8 +294,10 @@ class TmpTestdir:
|
||||||
ret = popen.wait()
|
ret = popen.wait()
|
||||||
f1.close()
|
f1.close()
|
||||||
f2.close()
|
f2.close()
|
||||||
out = p1.read("rb").decode("utf-8").splitlines()
|
out = p1.read("rb")
|
||||||
err = p2.read("rb").decode("utf-8").splitlines()
|
out = getdecoded(out).splitlines()
|
||||||
|
err = p2.read("rb")
|
||||||
|
err = getdecoded(err).splitlines()
|
||||||
def dump_lines(lines, fp):
|
def dump_lines(lines, fp):
|
||||||
try:
|
try:
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
@ -360,6 +362,13 @@ class TmpTestdir:
|
||||||
child.timeout = expect_timeout
|
child.timeout = expect_timeout
|
||||||
return child
|
return child
|
||||||
|
|
||||||
|
def getdecoded(out):
|
||||||
|
try:
|
||||||
|
return out.decode("utf-8")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return "INTERNAL not-utf8-decodeable, truncated string:\n%s" % (
|
||||||
|
py.io.saferepr(out),)
|
||||||
|
|
||||||
class PseudoPlugin:
|
class PseudoPlugin:
|
||||||
def __init__(self, vars):
|
def __init__(self, vars):
|
||||||
self.__dict__.update(vars)
|
self.__dict__.update(vars)
|
||||||
|
|
|
@ -36,6 +36,19 @@ def test_source_from_function():
|
||||||
source = py.code.Source(test_source_str_function)
|
source = py.code.Source(test_source_str_function)
|
||||||
assert str(source).startswith('def test_source_str_function():')
|
assert str(source).startswith('def test_source_str_function():')
|
||||||
|
|
||||||
|
def test_source_from_method():
|
||||||
|
class TestClass:
|
||||||
|
def test_method(self):
|
||||||
|
pass
|
||||||
|
source = py.code.Source(TestClass().test_method)
|
||||||
|
assert source.lines == ["def test_method(self):",
|
||||||
|
" pass"]
|
||||||
|
|
||||||
|
def test_source_from_lines():
|
||||||
|
lines = ["a \n", "b\n", "c"]
|
||||||
|
source = py.code.Source(lines)
|
||||||
|
assert source.lines == ['a ', 'b', 'c']
|
||||||
|
|
||||||
def test_source_from_inner_function():
|
def test_source_from_inner_function():
|
||||||
def f():
|
def f():
|
||||||
pass
|
pass
|
||||||
|
@ -92,6 +105,7 @@ def test_isparseable():
|
||||||
assert Source(" \nif 1:\n pass").isparseable()
|
assert Source(" \nif 1:\n pass").isparseable()
|
||||||
assert not Source("if 1:\n").isparseable()
|
assert not Source("if 1:\n").isparseable()
|
||||||
assert not Source(" \nif 1:\npass").isparseable()
|
assert not Source(" \nif 1:\npass").isparseable()
|
||||||
|
assert not Source(chr(0)).isparseable()
|
||||||
|
|
||||||
class TestAccesses:
|
class TestAccesses:
|
||||||
source = Source("""\
|
source = Source("""\
|
||||||
|
|
Loading…
Reference in New Issue