[svn r57321] merging the event branch:
* moving in test, misc, code, io directories and py/__init__.py * py/bin/_find.py does not print to stderr anymore * a few fixes to conftest files in other dirs some more fixes and adjustments pending --HG-- branch : trunk
This commit is contained in:
1
py/code/testing/__init__.py
Normal file
1
py/code/testing/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
#
|
||||
85
py/code/testing/test_code.py
Normal file
85
py/code/testing/test_code.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from __future__ import generators
|
||||
import py
|
||||
import new
|
||||
|
||||
def test_newcode():
|
||||
source = "i = 3"
|
||||
co = compile(source, '', 'exec')
|
||||
code = py.code.Code(co)
|
||||
newco = code.new()
|
||||
assert co == newco
|
||||
|
||||
def test_ne():
|
||||
code1 = py.code.Code(compile('foo = "bar"', '', 'exec'))
|
||||
assert code1 == code1
|
||||
code2 = py.code.Code(compile('foo = "baz"', '', 'exec'))
|
||||
assert code2 != code1
|
||||
|
||||
def test_newcode_unknown_args():
|
||||
code = py.code.Code(compile("", '', 'exec'))
|
||||
py.test.raises(TypeError, 'code.new(filename="hello")')
|
||||
|
||||
def test_newcode_withfilename():
|
||||
source = py.code.Source("""
|
||||
def f():
|
||||
def g():
|
||||
pass
|
||||
""")
|
||||
co = compile(str(source)+'\n', 'nada', 'exec')
|
||||
obj = 'hello'
|
||||
newco = py.code.Code(co).new(rec=True, co_filename=obj)
|
||||
def walkcode(co):
|
||||
for x in co.co_consts:
|
||||
if isinstance(x, type(co)):
|
||||
for y in walkcode(x):
|
||||
yield y
|
||||
yield co
|
||||
|
||||
names = []
|
||||
for code in walkcode(newco):
|
||||
assert newco.co_filename == obj
|
||||
assert newco.co_filename is obj
|
||||
names.append(code.co_name)
|
||||
assert 'f' in names
|
||||
assert 'g' in names
|
||||
|
||||
def test_newcode_with_filename():
|
||||
source = "i = 3"
|
||||
co = compile(source, '', 'exec')
|
||||
code = py.code.Code(co)
|
||||
class MyStr(str):
|
||||
pass
|
||||
filename = MyStr("hello")
|
||||
filename.__source__ = py.code.Source(source)
|
||||
newco = code.new(rec=True, co_filename=filename)
|
||||
assert newco.co_filename is filename
|
||||
s = py.code.Source(newco)
|
||||
assert str(s) == source
|
||||
|
||||
|
||||
def test_new_code_object_carries_filename_through():
|
||||
class mystr(str):
|
||||
pass
|
||||
filename = mystr("dummy")
|
||||
co = compile("hello\n", filename, 'exec')
|
||||
assert not isinstance(co.co_filename, mystr)
|
||||
c2 = new.code(co.co_argcount, co.co_nlocals, co.co_stacksize,
|
||||
co.co_flags, co.co_code, co.co_consts,
|
||||
co.co_names, co.co_varnames,
|
||||
filename,
|
||||
co.co_name, co.co_firstlineno, co.co_lnotab,
|
||||
co.co_freevars, co.co_cellvars)
|
||||
assert c2.co_filename is filename
|
||||
|
||||
def test_code_gives_back_name_for_not_existing_file():
|
||||
name = 'abc-123'
|
||||
co_code = compile("pass\n", name, 'exec')
|
||||
assert co_code.co_filename == name
|
||||
code = py.code.Code(co_code)
|
||||
assert str(code.path) == name
|
||||
assert code.fullsource is None
|
||||
|
||||
def test_code_with_class():
|
||||
class A:
|
||||
pass
|
||||
py.test.raises(TypeError, "py.code.Code(A)")
|
||||
584
py/code/testing/test_excinfo.py
Normal file
584
py/code/testing/test_excinfo.py
Normal file
@@ -0,0 +1,584 @@
|
||||
import py
|
||||
from py.__.code.excinfo import FormattedExcinfo, ReprExceptionInfo
|
||||
|
||||
class TWMock:
|
||||
def __init__(self):
|
||||
self.lines = []
|
||||
def sep(self, sep, line=None):
|
||||
self.lines.append((sep, line))
|
||||
def line(self, line):
|
||||
self.lines.append(line)
|
||||
def markup(self, text, **kw):
|
||||
return text
|
||||
|
||||
fullwidth = 80
|
||||
|
||||
def test_excinfo_simple():
|
||||
try:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
info = py.code.ExceptionInfo()
|
||||
assert info.type == ValueError
|
||||
|
||||
def test_excinfo_getstatement():
|
||||
def g():
|
||||
raise ValueError
|
||||
def f():
|
||||
g()
|
||||
try:
|
||||
f()
|
||||
except ValueError:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
linenumbers = [f.func_code.co_firstlineno-1+3,
|
||||
f.func_code.co_firstlineno-1+1,
|
||||
g.func_code.co_firstlineno-1+1,]
|
||||
l = list(excinfo.traceback)
|
||||
foundlinenumbers = [x.lineno for x in l]
|
||||
print l[0].frame.statement
|
||||
assert foundlinenumbers == linenumbers
|
||||
#for x in info:
|
||||
# print "%s:%d %s" %(x.path.relto(root), x.lineno, x.statement)
|
||||
#xxx
|
||||
|
||||
# testchain for getentries test below
|
||||
def f():
|
||||
#
|
||||
raise ValueError
|
||||
#
|
||||
def g():
|
||||
#
|
||||
__tracebackhide__ = True
|
||||
f()
|
||||
#
|
||||
def h():
|
||||
#
|
||||
g()
|
||||
#
|
||||
|
||||
class TestTraceback_f_g_h:
|
||||
def setup_method(self, method):
|
||||
try:
|
||||
h()
|
||||
except ValueError:
|
||||
self.excinfo = py.code.ExceptionInfo()
|
||||
|
||||
def test_traceback_entries(self):
|
||||
tb = self.excinfo.traceback
|
||||
entries = list(tb)
|
||||
assert len(tb) == 4 # maybe fragile test
|
||||
assert len(entries) == 4 # maybe fragile test
|
||||
names = ['f', 'g', 'h']
|
||||
for entry in entries:
|
||||
try:
|
||||
names.remove(entry.frame.code.name)
|
||||
except ValueError:
|
||||
pass
|
||||
assert not names
|
||||
|
||||
def test_traceback_entry_getsource(self):
|
||||
tb = self.excinfo.traceback
|
||||
s = str(tb[-1].getsource() )
|
||||
assert s.startswith("def f():")
|
||||
assert s.endswith("raise ValueError")
|
||||
|
||||
def test_traceback_entry_getsource_in_construct(self):
|
||||
source = py.code.Source("""\
|
||||
def xyz():
|
||||
try:
|
||||
raise ValueError
|
||||
except somenoname:
|
||||
pass
|
||||
xyz()
|
||||
""")
|
||||
try:
|
||||
exec source.compile()
|
||||
except NameError:
|
||||
tb = py.code.ExceptionInfo().traceback
|
||||
print tb[-1].getsource()
|
||||
s = str(tb[-1].getsource())
|
||||
assert s.startswith("def xyz():\n try:")
|
||||
assert s.endswith("except somenoname:")
|
||||
|
||||
def test_traceback_cut(self):
|
||||
co = py.code.Code(f)
|
||||
path, firstlineno = co.path, co.firstlineno
|
||||
traceback = self.excinfo.traceback
|
||||
newtraceback = traceback.cut(path=path, firstlineno=firstlineno)
|
||||
assert len(newtraceback) == 1
|
||||
newtraceback = traceback.cut(path=path, lineno=firstlineno+2)
|
||||
assert len(newtraceback) == 1
|
||||
|
||||
def test_traceback_filter(self):
|
||||
traceback = self.excinfo.traceback
|
||||
ntraceback = traceback.filter()
|
||||
assert len(ntraceback) == len(traceback) - 1
|
||||
|
||||
def test_traceback_recursion_index(self):
|
||||
def f(n):
|
||||
if n < 10:
|
||||
n += 1
|
||||
f(n)
|
||||
excinfo = py.test.raises(RuntimeError, f, 8)
|
||||
traceback = excinfo.traceback
|
||||
recindex = traceback.recursionindex()
|
||||
assert recindex == 3
|
||||
|
||||
def test_traceback_no_recursion_index(self):
|
||||
def do_stuff():
|
||||
raise RuntimeError
|
||||
def reraise_me():
|
||||
import sys
|
||||
exc, val, tb = sys.exc_info()
|
||||
raise exc, val, tb
|
||||
def f(n):
|
||||
try:
|
||||
do_stuff()
|
||||
except:
|
||||
reraise_me()
|
||||
excinfo = py.test.raises(RuntimeError, f, 8)
|
||||
traceback = excinfo.traceback
|
||||
recindex = traceback.recursionindex()
|
||||
assert recindex is None
|
||||
|
||||
def test_traceback_getcrashentry(self):
|
||||
def i():
|
||||
__tracebackhide__ = True
|
||||
raise ValueError
|
||||
def h():
|
||||
i()
|
||||
def g():
|
||||
__tracebackhide__ = True
|
||||
h()
|
||||
def f():
|
||||
g()
|
||||
|
||||
excinfo = py.test.raises(ValueError, f)
|
||||
tb = excinfo.traceback
|
||||
entry = tb.getcrashentry()
|
||||
co = py.code.Code(h)
|
||||
assert entry.frame.code.path == co.path
|
||||
assert entry.lineno == co.firstlineno + 1
|
||||
assert entry.frame.code.name == 'h'
|
||||
|
||||
def test_traceback_getcrashentry_empty(self):
|
||||
def g():
|
||||
__tracebackhide__ = True
|
||||
raise ValueError
|
||||
def f():
|
||||
__tracebackhide__ = True
|
||||
g()
|
||||
|
||||
excinfo = py.test.raises(ValueError, f)
|
||||
tb = excinfo.traceback
|
||||
entry = tb.getcrashentry()
|
||||
co = py.code.Code(g)
|
||||
assert entry.frame.code.path == co.path
|
||||
assert entry.lineno == co.firstlineno + 2
|
||||
assert entry.frame.code.name == 'g'
|
||||
|
||||
def hello(x):
|
||||
x + 5
|
||||
|
||||
def test_tbentry_reinterpret():
|
||||
try:
|
||||
hello("hello")
|
||||
except TypeError:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
tbentry = excinfo.traceback[-1]
|
||||
msg = tbentry.reinterpret()
|
||||
assert msg.startswith("TypeError: ('hello' + 5)")
|
||||
|
||||
def test_excinfo_exconly():
|
||||
excinfo = py.test.raises(ValueError, h)
|
||||
assert excinfo.exconly().startswith('ValueError')
|
||||
|
||||
def test_excinfo_repr():
|
||||
excinfo = py.test.raises(ValueError, h)
|
||||
s = repr(excinfo)
|
||||
assert s == "<ExceptionInfo ValueError tblen=4>"
|
||||
|
||||
def test_excinfo_str():
|
||||
excinfo = py.test.raises(ValueError, h)
|
||||
s = str(excinfo)
|
||||
print s
|
||||
assert s.startswith(__file__[:-1]) # pyc file
|
||||
assert s.endswith("ValueError")
|
||||
assert len(s.split(":")) == 3
|
||||
|
||||
def test_excinfo_errisinstance():
|
||||
excinfo = py.test.raises(ValueError, h)
|
||||
assert excinfo.errisinstance(ValueError)
|
||||
|
||||
def test_excinfo_no_sourcecode():
|
||||
try:
|
||||
exec "raise ValueError()"
|
||||
except ValueError:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
s = str(excinfo.traceback[-1])
|
||||
assert s == " File '<string>':1 in <module>\n ???\n"
|
||||
|
||||
def test_entrysource_Queue_example():
|
||||
import Queue
|
||||
try:
|
||||
Queue.Queue().get(timeout=0.001)
|
||||
except Queue.Empty:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
entry = excinfo.traceback[-1]
|
||||
source = entry.getsource()
|
||||
assert source is not None
|
||||
s = str(source).strip()
|
||||
assert s.startswith("def get")
|
||||
|
||||
def test_codepath_Queue_example():
|
||||
py.test.skip("try harder to get at the paths of code objects.")
|
||||
import Queue
|
||||
try:
|
||||
Queue.Queue().get(timeout=0.001)
|
||||
except Queue.Empty:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
entry = excinfo.traceback[-1]
|
||||
path = entry.path
|
||||
assert isinstance(path, py.path.local)
|
||||
assert path.basename == "Queue.py"
|
||||
assert path.check()
|
||||
|
||||
class TestFormattedExcinfo:
|
||||
def setup_method(self, method):
|
||||
self.tmpdir = py.test.ensuretemp("%s_%s" %(
|
||||
self.__class__.__name__, method.__name__))
|
||||
|
||||
def importasmod(self, source):
|
||||
source = py.code.Source(source)
|
||||
modpath = self.tmpdir.join("mod.py")
|
||||
self.tmpdir.ensure("__init__.py")
|
||||
modpath.write(source)
|
||||
return modpath.pyimport()
|
||||
|
||||
def excinfo_from_exec(self, source):
|
||||
source = py.code.Source(source).strip()
|
||||
try:
|
||||
exec source.compile()
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
return py.code.ExceptionInfo()
|
||||
assert 0, "did not raise"
|
||||
|
||||
def test_repr_source(self):
|
||||
pr = FormattedExcinfo()
|
||||
source = py.code.Source("""
|
||||
def f(x):
|
||||
pass
|
||||
""").strip()
|
||||
pr.flow_marker = "|"
|
||||
lines = pr.get_source(source, 0)
|
||||
assert len(lines) == 2
|
||||
assert lines[0] == "| def f(x):"
|
||||
assert lines[1] == " pass"
|
||||
|
||||
def test_repr_source_excinfo(self):
|
||||
""" check if indentation is right """
|
||||
pr = FormattedExcinfo()
|
||||
excinfo = self.excinfo_from_exec("""
|
||||
def f():
|
||||
assert 0
|
||||
f()
|
||||
""")
|
||||
pr = FormattedExcinfo()
|
||||
source = pr._getentrysource(excinfo.traceback[-1])
|
||||
lines = pr.get_source(source, 1, excinfo)
|
||||
print lines
|
||||
assert lines == [
|
||||
' def f():',
|
||||
'> assert 0',
|
||||
'E assert 0'
|
||||
]
|
||||
|
||||
|
||||
def test_repr_source_not_existing(self):
|
||||
pr = FormattedExcinfo()
|
||||
co = compile("raise ValueError()", "", "exec")
|
||||
try:
|
||||
exec co
|
||||
except ValueError:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
repr = pr.repr_excinfo(excinfo)
|
||||
assert repr.reprtraceback.reprentries[1].lines[0] == "> ???"
|
||||
|
||||
def test_repr_local(self):
|
||||
p = FormattedExcinfo(showlocals=True)
|
||||
loc = {'y': 5, 'z': 7, 'x': 3, '__builtins__': __builtins__}
|
||||
reprlocals = p.repr_locals(loc)
|
||||
assert reprlocals.lines
|
||||
print reprlocals.lines
|
||||
assert reprlocals.lines[0] == '__builtins__ = <builtins>'
|
||||
assert reprlocals.lines[1] == 'x = 3'
|
||||
assert reprlocals.lines[2] == 'y = 5'
|
||||
assert reprlocals.lines[3] == 'z = 7'
|
||||
|
||||
def test_repr_tracebackentry_lines(self):
|
||||
mod = self.importasmod("""
|
||||
def func1():
|
||||
raise ValueError("hello\\nworld")
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.func1)
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
p = FormattedExcinfo()
|
||||
reprtb = p.repr_traceback_entry(excinfo.traceback[-1])
|
||||
print reprtb
|
||||
|
||||
# test as intermittent entry
|
||||
lines = reprtb.lines
|
||||
assert lines[0] == ' def func1():'
|
||||
assert lines[1] == '> raise ValueError("hello\\nworld")'
|
||||
|
||||
# test as last entry
|
||||
p = FormattedExcinfo(showlocals=True)
|
||||
repr_entry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
lines = repr_entry.lines
|
||||
assert lines[0] == ' def func1():'
|
||||
assert lines[1] == '> raise ValueError("hello\\nworld")'
|
||||
assert lines[2] == 'E ValueError: hello'
|
||||
assert lines[3] == 'E world'
|
||||
assert not lines[4:]
|
||||
|
||||
loc = repr_entry.reprlocals is not None
|
||||
loc = repr_entry.reprfileloc
|
||||
assert loc.path == mod.__file__
|
||||
assert loc.lineno == 3
|
||||
#assert loc.message == "ValueError: hello"
|
||||
|
||||
def test_repr_tracebackentry_lines(self):
|
||||
mod = self.importasmod("""
|
||||
def func1(m, x, y, z):
|
||||
raise ValueError("hello\\nworld")
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.func1, "m"*90, 5, 13, "z"*120)
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
entry = excinfo.traceback[-1]
|
||||
p = FormattedExcinfo(funcargs=True)
|
||||
reprfuncargs = p.repr_args(entry)
|
||||
assert reprfuncargs.args[0] == ('m', repr("m"*90))
|
||||
assert reprfuncargs.args[1] == ('x', '5')
|
||||
assert reprfuncargs.args[2] == ('y', '13')
|
||||
assert reprfuncargs.args[3] == ('z', repr("z" * 120))
|
||||
|
||||
p = FormattedExcinfo(funcargs=True)
|
||||
repr_entry = p.repr_traceback_entry(entry)
|
||||
assert repr_entry.reprfuncargs.args == reprfuncargs.args
|
||||
tw = TWMock()
|
||||
repr_entry.toterminal(tw)
|
||||
assert tw.lines[0] == "m = " + repr('m' * 90)
|
||||
assert tw.lines[1] == "x = 5, y = 13"
|
||||
assert tw.lines[2] == "z = " + repr('z' * 120)
|
||||
|
||||
def test_repr_tracebackentry_short(self):
|
||||
mod = self.importasmod("""
|
||||
def func1():
|
||||
raise ValueError("hello")
|
||||
def entry():
|
||||
func1()
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.entry)
|
||||
p = FormattedExcinfo(style="short")
|
||||
reprtb = p.repr_traceback_entry(excinfo.traceback[-2])
|
||||
lines = reprtb.lines
|
||||
basename = py.path.local(mod.__file__).basename
|
||||
assert lines[0] == ' File "%s", line 5, in entry' % basename
|
||||
assert lines[1] == ' func1()'
|
||||
|
||||
# test last entry
|
||||
p = FormattedExcinfo(style="short")
|
||||
reprtb = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
lines = reprtb.lines
|
||||
assert lines[0] == ' File "%s", line 3, in func1' % basename
|
||||
assert lines[1] == ' raise ValueError("hello")'
|
||||
assert lines[2] == 'E ValueError: hello'
|
||||
|
||||
def test_repr_tracebackentry_no(self):
|
||||
mod = self.importasmod("""
|
||||
def func1():
|
||||
raise ValueError("hello")
|
||||
def entry():
|
||||
func1()
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.entry)
|
||||
p = FormattedExcinfo(style="no")
|
||||
p.repr_traceback_entry(excinfo.traceback[-2])
|
||||
|
||||
p = FormattedExcinfo(style="no")
|
||||
reprentry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
lines = reprentry.lines
|
||||
assert lines[0] == 'E ValueError: hello'
|
||||
assert not lines[1:]
|
||||
|
||||
def test_repr_traceback_tbfilter(self):
|
||||
mod = self.importasmod("""
|
||||
def f(x):
|
||||
raise ValueError(x)
|
||||
def entry():
|
||||
f(0)
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.entry)
|
||||
p = FormattedExcinfo(tbfilter=True)
|
||||
reprtb = p.repr_traceback(excinfo)
|
||||
assert len(reprtb.reprentries) == 2
|
||||
p = FormattedExcinfo(tbfilter=False)
|
||||
reprtb = p.repr_traceback(excinfo)
|
||||
assert len(reprtb.reprentries) == 3
|
||||
|
||||
def test_repr_traceback_and_excinfo(self):
|
||||
mod = self.importasmod("""
|
||||
def f(x):
|
||||
raise ValueError(x)
|
||||
def entry():
|
||||
f(0)
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.entry)
|
||||
|
||||
for style in ("long", "short"):
|
||||
p = FormattedExcinfo(style=style)
|
||||
reprtb = p.repr_traceback(excinfo)
|
||||
assert len(reprtb.reprentries) == 2
|
||||
assert reprtb.style == style
|
||||
assert not reprtb.extraline
|
||||
repr = p.repr_excinfo(excinfo)
|
||||
assert repr.reprtraceback
|
||||
assert len(repr.reprtraceback.reprentries) == len(reprtb.reprentries)
|
||||
assert repr.reprcrash.path.endswith("mod.py")
|
||||
assert repr.reprcrash.message == "ValueError: 0"
|
||||
|
||||
def test_repr_excinfo_addouterr(self):
|
||||
mod = self.importasmod("""
|
||||
def entry():
|
||||
raise ValueError()
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.entry)
|
||||
repr = excinfo.getrepr()
|
||||
repr.addsection("title", "content")
|
||||
twmock = TWMock()
|
||||
repr.toterminal(twmock)
|
||||
assert twmock.lines[-1] == "content"
|
||||
assert twmock.lines[-2] == ("-", "title")
|
||||
|
||||
def test_repr_excinfo_reprcrash(self):
|
||||
mod = self.importasmod("""
|
||||
def entry():
|
||||
raise ValueError()
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.entry)
|
||||
repr = excinfo.getrepr()
|
||||
assert repr.reprcrash.path.endswith("mod.py")
|
||||
assert repr.reprcrash.lineno == 3
|
||||
assert repr.reprcrash.message == "ValueError"
|
||||
assert str(repr.reprcrash).endswith("mod.py:3: ValueError")
|
||||
|
||||
def test_repr_traceback_recursion(self):
|
||||
mod = self.importasmod("""
|
||||
def rec2(x):
|
||||
return rec1(x+1)
|
||||
def rec1(x):
|
||||
return rec2(x-1)
|
||||
def entry():
|
||||
rec1(42)
|
||||
""")
|
||||
excinfo = py.test.raises(RuntimeError, mod.entry)
|
||||
|
||||
for style in ("short", "long", "no"):
|
||||
p = FormattedExcinfo(style="short")
|
||||
reprtb = p.repr_traceback(excinfo)
|
||||
assert reprtb.extraline == "!!! Recursion detected (same locals & position)"
|
||||
assert str(reprtb)
|
||||
|
||||
def test_tb_entry_AssertionError(self):
|
||||
# probably this test is a bit redundant
|
||||
# as py/magic/testing/test_assertion.py
|
||||
# already tests correctness of
|
||||
# assertion-reinterpretation logic
|
||||
mod = self.importasmod("""
|
||||
def somefunc():
|
||||
x = 1
|
||||
assert x == 2
|
||||
""")
|
||||
py.magic.invoke(assertion=True)
|
||||
try:
|
||||
excinfo = py.test.raises(AssertionError, mod.somefunc)
|
||||
finally:
|
||||
py.magic.revoke(assertion=True)
|
||||
|
||||
p = FormattedExcinfo()
|
||||
reprentry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
|
||||
lines = reprentry.lines
|
||||
assert lines[-1] == "E assert 1 == 2"
|
||||
|
||||
def test_reprexcinfo_getrepr(self):
|
||||
mod = self.importasmod("""
|
||||
def f(x):
|
||||
raise ValueError(x)
|
||||
def entry():
|
||||
f(0)
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.entry)
|
||||
|
||||
for style in ("short", "long", "no"):
|
||||
for showlocals in (True, False):
|
||||
repr = excinfo.getrepr(style=style, showlocals=showlocals)
|
||||
assert isinstance(repr, ReprExceptionInfo)
|
||||
assert repr.reprtraceback.style == style
|
||||
|
||||
def test_toterminal_long(self):
|
||||
mod = self.importasmod("""
|
||||
def g(x):
|
||||
raise ValueError(x)
|
||||
def f():
|
||||
g(3)
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.f)
|
||||
excinfo.traceback = excinfo.traceback.filter()
|
||||
repr = excinfo.getrepr()
|
||||
tw = TWMock()
|
||||
repr.toterminal(tw)
|
||||
assert tw.lines[0] == ""
|
||||
tw.lines.pop(0)
|
||||
assert tw.lines[0] == " def f():"
|
||||
assert tw.lines[1] == "> g(3)"
|
||||
assert tw.lines[2] == ""
|
||||
assert tw.lines[3].endswith("mod.py:5: ")
|
||||
assert tw.lines[4] == ("_ ", None)
|
||||
assert tw.lines[5] == ""
|
||||
assert tw.lines[6] == " def g(x):"
|
||||
assert tw.lines[7] == "> raise ValueError(x)"
|
||||
assert tw.lines[8] == "E ValueError: 3"
|
||||
assert tw.lines[9] == ""
|
||||
assert tw.lines[10].endswith("mod.py:3: ValueError")
|
||||
|
||||
|
||||
def test_format_excinfo(self):
|
||||
mod = self.importasmod("""
|
||||
def g(x):
|
||||
raise ValueError(x)
|
||||
def f():
|
||||
g(3)
|
||||
""")
|
||||
excinfo = py.test.raises(ValueError, mod.f)
|
||||
def format_and_str(kw):
|
||||
tw = py.io.TerminalWriter(stringio=True)
|
||||
repr = excinfo.getrepr(**kw)
|
||||
repr.toterminal(tw)
|
||||
assert tw.stringio.getvalue()
|
||||
|
||||
for combo in self.allcombos():
|
||||
yield format_and_str, combo
|
||||
|
||||
def allcombos(self):
|
||||
for style in ("long", "short", "no"):
|
||||
for showlocals in (True, False):
|
||||
for tbfilter in (True, False):
|
||||
for funcargs in (True, False):
|
||||
kw = {'style': style,
|
||||
'showlocals': showlocals,
|
||||
'funcargs': funcargs,
|
||||
'tbfilter': tbfilter
|
||||
}
|
||||
yield kw
|
||||
|
||||
15
py/code/testing/test_frame.py
Normal file
15
py/code/testing/test_frame.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import sys
|
||||
import py
|
||||
|
||||
def test_frame_getsourcelineno_myself():
|
||||
def func():
|
||||
return sys._getframe(0)
|
||||
f = func()
|
||||
f = py.code.Frame(f)
|
||||
source, lineno = f.code.fullsource, f.lineno
|
||||
assert source[lineno].startswith(" return sys._getframe(0)")
|
||||
|
||||
def test_code_from_func():
|
||||
co = py.code.Code(test_frame_getsourcelineno_myself)
|
||||
assert co.firstlineno
|
||||
assert co.path
|
||||
34
py/code/testing/test_safe_repr.py
Normal file
34
py/code/testing/test_safe_repr.py
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
import py
|
||||
from py.__.code import safe_repr
|
||||
|
||||
def test_simple_repr():
|
||||
assert safe_repr._repr(1) == '1'
|
||||
assert safe_repr._repr(None) == 'None'
|
||||
|
||||
class BrokenRepr:
|
||||
def __init__(self, ex):
|
||||
self.ex = ex
|
||||
foo = 0
|
||||
def __repr__(self):
|
||||
raise self.ex
|
||||
|
||||
def test_exception():
|
||||
assert 'Exception' in safe_repr._repr(BrokenRepr(Exception("broken")))
|
||||
|
||||
class BrokenReprException(Exception):
|
||||
__str__ = None
|
||||
__repr__ = None
|
||||
|
||||
def test_broken_exception():
|
||||
assert 'Exception' in safe_repr._repr(BrokenRepr(BrokenReprException("really broken")))
|
||||
|
||||
def test_string_exception():
|
||||
assert 'unknown' in safe_repr._repr(BrokenRepr("string"))
|
||||
|
||||
def test_big_repr():
|
||||
assert len(safe_repr._repr(range(1000))) <= \
|
||||
len('[' + safe_repr.SafeRepr().maxlist * "1000" + ']')
|
||||
|
||||
|
||||
|
||||
316
py/code/testing/test_source.py
Normal file
316
py/code/testing/test_source.py
Normal file
@@ -0,0 +1,316 @@
|
||||
from py.code import Source
|
||||
import py
|
||||
import sys
|
||||
|
||||
def test_source_str_function():
|
||||
x = Source("3")
|
||||
assert str(x) == "3"
|
||||
|
||||
x = Source(" 3")
|
||||
assert str(x) == "3"
|
||||
|
||||
x = Source("""
|
||||
3
|
||||
""", rstrip=False)
|
||||
assert str(x) == "\n3\n "
|
||||
|
||||
x = Source("""
|
||||
3
|
||||
""", rstrip=True)
|
||||
assert str(x) == "\n3"
|
||||
|
||||
def test_unicode():
|
||||
x = Source(unicode("4"))
|
||||
assert str(x) == "4"
|
||||
|
||||
|
||||
def test_source_from_function():
|
||||
source = py.code.Source(test_source_str_function)
|
||||
assert str(source).startswith('def test_source_str_function():')
|
||||
|
||||
def test_source_from_inner_function():
|
||||
def f():
|
||||
pass
|
||||
source = py.code.Source(f, deindent=False)
|
||||
assert str(source).startswith(' def f():')
|
||||
source = py.code.Source(f)
|
||||
assert str(source).startswith('def f():')
|
||||
|
||||
def test_source_putaround_simple():
|
||||
source = Source("raise ValueError")
|
||||
source = source.putaround(
|
||||
"try:", """\
|
||||
except ValueError:
|
||||
x = 42
|
||||
else:
|
||||
x = 23""")
|
||||
assert str(source)=="""\
|
||||
try:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
x = 42
|
||||
else:
|
||||
x = 23"""
|
||||
|
||||
def test_source_putaround():
|
||||
source = Source()
|
||||
source = source.putaround("""
|
||||
if 1:
|
||||
x=1
|
||||
""")
|
||||
assert str(source).strip() == "if 1:\n x=1"
|
||||
|
||||
def test_source_strips():
|
||||
source = Source("")
|
||||
assert source == Source()
|
||||
assert str(source) == ''
|
||||
assert source.strip() == source
|
||||
|
||||
def test_source_strip_multiline():
|
||||
source = Source()
|
||||
source.lines = ["", " hello", " "]
|
||||
source2 = source.strip()
|
||||
assert source2.lines == [" hello"]
|
||||
|
||||
def test_syntaxerror_rerepresentation():
|
||||
ex = py.test.raises(SyntaxError, py.code.compile, 'x x')
|
||||
assert ex.value.lineno == 1
|
||||
assert ex.value.offset == 3
|
||||
assert ex.value.text.strip(), 'x x'
|
||||
|
||||
def test_isparseable():
|
||||
assert Source("hello").isparseable()
|
||||
assert Source("if 1:\n pass").isparseable()
|
||||
assert Source(" \nif 1:\n pass").isparseable()
|
||||
assert not Source("if 1:\n").isparseable()
|
||||
assert not Source(" \nif 1:\npass").isparseable()
|
||||
|
||||
class TestAccesses:
|
||||
source = Source("""\
|
||||
def f(x):
|
||||
pass
|
||||
def g(x):
|
||||
pass
|
||||
""")
|
||||
def test_getrange(self):
|
||||
x = self.source[0:2]
|
||||
assert x.isparseable()
|
||||
assert len(x.lines) == 2
|
||||
assert str(x) == "def f(x):\n pass"
|
||||
|
||||
def test_getline(self):
|
||||
x = self.source[0]
|
||||
assert x == "def f(x):"
|
||||
|
||||
def test_len(self):
|
||||
assert len(self.source) == 4
|
||||
|
||||
def test_iter(self):
|
||||
l = [x for x in self.source]
|
||||
assert len(l) == 4
|
||||
|
||||
class TestSourceParsingAndCompiling:
|
||||
source = Source("""\
|
||||
def f(x):
|
||||
assert (x ==
|
||||
3 +
|
||||
4)
|
||||
""").strip()
|
||||
|
||||
def test_compile(self):
|
||||
co = py.code.compile("x=3")
|
||||
exec co
|
||||
assert x == 3
|
||||
|
||||
def test_compile_unicode(self):
|
||||
co = py.code.compile(unicode('u"\xc3\xa5"', 'utf8'), mode='eval')
|
||||
val = eval(co)
|
||||
assert isinstance(val, unicode)
|
||||
|
||||
def test_compile_and_getsource_simple(self):
|
||||
co = py.code.compile("x=3")
|
||||
exec co
|
||||
source = py.code.Source(co)
|
||||
assert str(source) == "x=3"
|
||||
|
||||
def test_getstatement(self):
|
||||
#print str(self.source)
|
||||
ass = str(self.source[1:])
|
||||
for i in range(1, 4):
|
||||
#print "trying start in line %r" % self.source[i]
|
||||
s = self.source.getstatement(i)
|
||||
#x = s.deindent()
|
||||
assert str(s) == ass
|
||||
|
||||
def test_getstatementrange_within_constructs(self):
|
||||
source = Source("""\
|
||||
try:
|
||||
try:
|
||||
raise ValueError
|
||||
except SomeThing:
|
||||
pass
|
||||
finally:
|
||||
42
|
||||
""")
|
||||
assert len(source) == 7
|
||||
assert source.getstatementrange(0) == (0, 7)
|
||||
assert source.getstatementrange(1) == (1, 5)
|
||||
assert source.getstatementrange(2) == (2, 3)
|
||||
assert source.getstatementrange(3) == (1, 5)
|
||||
assert source.getstatementrange(4) == (4, 5)
|
||||
assert source.getstatementrange(5) == (0, 7)
|
||||
assert source.getstatementrange(6) == (6, 7)
|
||||
|
||||
def test_getstatementrange_bug(self):
|
||||
source = Source("""\
|
||||
try:
|
||||
x = (
|
||||
y +
|
||||
z)
|
||||
except:
|
||||
pass
|
||||
""")
|
||||
assert len(source) == 6
|
||||
assert source.getstatementrange(2) == (1, 4)
|
||||
|
||||
def test_getstatementrange_bug2(self):
|
||||
py.test.skip("fix me (issue19)")
|
||||
source = Source("""\
|
||||
assert (
|
||||
33
|
||||
==
|
||||
[
|
||||
X(3,
|
||||
b=1, c=2
|
||||
),
|
||||
]
|
||||
)
|
||||
""")
|
||||
assert len(source) == 9
|
||||
assert source.getstatementrange(5) == (0, 9)
|
||||
|
||||
def test_compile_and_getsource(self):
|
||||
co = self.source.compile()
|
||||
exec co
|
||||
f(7)
|
||||
excinfo = py.test.raises(AssertionError, "f(6)")
|
||||
frame = excinfo.traceback[-1].frame
|
||||
stmt = frame.code.fullsource.getstatement(frame.lineno)
|
||||
#print "block", str(block)
|
||||
assert str(stmt).strip().startswith('assert')
|
||||
|
||||
def test_compilefuncs_and_path_sanity(self):
|
||||
def check(comp, name):
|
||||
co = comp(self.source, name)
|
||||
if not name:
|
||||
expected = "<codegen %s:%d>" %(mypath, mylineno+2+1)
|
||||
else:
|
||||
expected = "<codegen %r %s:%d>" % (name, mypath, mylineno+2+1)
|
||||
fn = co.co_filename
|
||||
assert fn == expected
|
||||
|
||||
mycode = py.code.Code(self.test_compilefuncs_and_path_sanity)
|
||||
mylineno = mycode.firstlineno
|
||||
mypath = mycode.path
|
||||
|
||||
for comp in py.code.compile, py.code.Source.compile:
|
||||
for name in '', None, 'my':
|
||||
yield check, comp, name
|
||||
|
||||
def test_offsetless_synerr(self):
|
||||
py.test.raises(SyntaxError, py.code.compile, "lambda a,a: 0", mode='eval')
|
||||
|
||||
def test_getstartingblock_singleline():
|
||||
class A:
|
||||
def __init__(self, *args):
|
||||
frame = sys._getframe(1)
|
||||
self.source = py.code.Frame(frame).statement
|
||||
|
||||
x = A('x', 'y')
|
||||
|
||||
l = [i for i in x.source.lines if i.strip()]
|
||||
assert len(l) == 1
|
||||
|
||||
def test_getstartingblock_multiline():
|
||||
class A:
|
||||
def __init__(self, *args):
|
||||
frame = sys._getframe(1)
|
||||
self.source = py.code.Frame(frame).statement
|
||||
|
||||
x = A('x',
|
||||
'y' \
|
||||
,
|
||||
'z')
|
||||
|
||||
l = [i for i in x.source.lines if i.strip()]
|
||||
assert len(l) == 4
|
||||
|
||||
def test_getline_finally():
|
||||
#py.test.skip("inner statements cannot be located yet.")
|
||||
def c(): pass
|
||||
excinfo = py.test.raises(TypeError, """
|
||||
teardown = None
|
||||
try:
|
||||
c(1)
|
||||
finally:
|
||||
if teardown:
|
||||
teardown()
|
||||
""")
|
||||
source = excinfo.traceback[-1].statement
|
||||
assert str(source).strip() == 'c(1)'
|
||||
|
||||
def test_getfuncsource_dynamic():
|
||||
source = """
|
||||
def f():
|
||||
raise ValueError
|
||||
|
||||
def g(): pass
|
||||
"""
|
||||
co = py.code.compile(source)
|
||||
exec co
|
||||
assert str(py.code.Source(f)).strip() == 'def f():\n raise ValueError'
|
||||
assert str(py.code.Source(g)).strip() == 'def g(): pass'
|
||||
|
||||
|
||||
def test_getfuncsource_with_multine_string():
|
||||
def f():
|
||||
c = '''while True:
|
||||
pass
|
||||
'''
|
||||
assert str(py.code.Source(f)).strip() == "def f():\n c = '''while True:\n pass\n'''"
|
||||
|
||||
|
||||
def test_deindent():
|
||||
from py.__.code.source import deindent as deindent
|
||||
assert deindent(['\tfoo', '\tbar', ]) == ['foo', 'bar']
|
||||
|
||||
def f():
|
||||
c = '''while True:
|
||||
pass
|
||||
'''
|
||||
import inspect
|
||||
lines = deindent(inspect.getsource(f).splitlines())
|
||||
assert lines == ["def f():", " c = '''while True:", " pass", "'''"]
|
||||
|
||||
source = """
|
||||
def f():
|
||||
def g():
|
||||
pass
|
||||
"""
|
||||
lines = deindent(source.splitlines())
|
||||
assert lines == ['', 'def f():', ' def g():', ' pass', ' ']
|
||||
|
||||
def test_source_of_class_at_eof_without_newline():
|
||||
py.test.skip("CPython's inspect.getsource is buggy")
|
||||
# this test fails because the implicit inspect.getsource(A) below
|
||||
# does not return the "x = 1" last line.
|
||||
tmpdir = py.test.ensuretemp("source_write_read")
|
||||
source = py.code.Source('''
|
||||
class A(object):
|
||||
def method(self):
|
||||
x = 1
|
||||
''')
|
||||
path = tmpdir.join("a.py")
|
||||
path.write(source)
|
||||
s2 = py.code.Source(tmpdir.join("a.py").pyimport().A)
|
||||
assert str(source).strip() == str(s2).strip()
|
||||
Reference in New Issue
Block a user