# -*- coding: utf-8 -*- import _pytest import py import pytest from _pytest._code.code import FormattedExcinfo, ReprExceptionInfo queue = py.builtin._tryimport('queue', 'Queue') failsonjython = pytest.mark.xfail("sys.platform.startswith('java')") from test_source import astonly try: import importlib except ImportError: invalidate_import_caches = None else: invalidate_import_caches = getattr(importlib, "invalidate_caches", None) import pytest pytest_version_info = tuple(map(int, pytest.__version__.split(".")[:3])) class TWMock: def __init__(self): self.lines = [] def sep(self, sep, line=None): self.lines.append((sep, line)) def line(self, line, **kw): self.lines.append(line) def markup(self, text, **kw): return text fullwidth = 80 def test_excinfo_simple(): try: raise ValueError except ValueError: info = _pytest._code.ExceptionInfo() assert info.type == ValueError def test_excinfo_getstatement(): def g(): raise ValueError def f(): g() try: f() except ValueError: excinfo = _pytest._code.ExceptionInfo() linenumbers = [_pytest._code.getrawcode(f).co_firstlineno - 1 + 3, _pytest._code.getrawcode(f).co_firstlineno - 1 + 1, _pytest._code.getrawcode(g).co_firstlineno - 1 + 1, ] l = list(excinfo.traceback) foundlinenumbers = [x.lineno for x in l] 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 = _pytest._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") @astonly @failsonjython def test_traceback_entry_getsource_in_construct(self): source = _pytest._code.Source("""\ def xyz(): try: raise ValueError except somenoname: pass xyz() """) try: exec (source.compile()) except NameError: tb = _pytest._code.ExceptionInfo().traceback print (tb[-1].getsource()) s = str(tb[-1].getsource()) assert s.startswith("def xyz():\n try:") assert s.strip().endswith("except somenoname:") def test_traceback_cut(self): co = _pytest._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_cut_excludepath(self, testdir): p = testdir.makepyfile("def f(): raise ValueError") excinfo = pytest.raises(ValueError, "p.pyimport().f()") basedir = py.path.local(pytest.__file__).dirpath() newtraceback = excinfo.traceback.cut(excludepath=basedir) for x in newtraceback: if hasattr(x, 'path'): assert not py.path.local(x.path).relto(basedir) assert newtraceback[-1].frame.code.path == p 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 = pytest.raises(RuntimeError, f, 8) traceback = excinfo.traceback recindex = traceback.recursionindex() assert recindex == 3 def test_traceback_only_specific_recursion_errors(self, monkeypatch): def f(n): if n == 0: raise RuntimeError("hello") f(n-1) excinfo = pytest.raises(RuntimeError, f, 100) monkeypatch.delattr(excinfo.traceback.__class__, "recursionindex") repr = excinfo.getrepr() assert "RuntimeError: hello" in str(repr.reprcrash) def test_traceback_no_recursion_index(self): def do_stuff(): raise RuntimeError def reraise_me(): import sys exc, val, tb = sys.exc_info() py.builtin._reraise(exc, val, tb) def f(n): try: do_stuff() except: reraise_me() excinfo = pytest.raises(RuntimeError, f, 8) traceback = excinfo.traceback recindex = traceback.recursionindex() assert recindex is None def test_traceback_messy_recursion(self): #XXX: simplified locally testable version decorator = pytest.importorskip('decorator').decorator def log(f, *k, **kw): print('%s %s' % (k, kw)) f(*k, **kw) log = decorator(log) def fail(): raise ValueError('') fail = log(log(fail)) excinfo = pytest.raises(ValueError, fail) assert excinfo.traceback.recursionindex() 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 = pytest.raises(ValueError, f) tb = excinfo.traceback entry = tb.getcrashentry() co = _pytest._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 = pytest.raises(ValueError, f) tb = excinfo.traceback entry = tb.getcrashentry() co = _pytest._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 = _pytest._code.ExceptionInfo() tbentry = excinfo.traceback[-1] msg = tbentry.reinterpret() assert msg.startswith("TypeError: ('hello' + 5)") def test_excinfo_exconly(): excinfo = pytest.raises(ValueError, h) assert excinfo.exconly().startswith('ValueError') excinfo = pytest.raises(ValueError, "raise ValueError('hello\\nworld')") msg = excinfo.exconly(tryshort=True) assert msg.startswith('ValueError') assert msg.endswith("world") def test_excinfo_repr(): excinfo = pytest.raises(ValueError, h) s = repr(excinfo) assert s == "" def test_excinfo_str(): excinfo = pytest.raises(ValueError, h) s = str(excinfo) assert s.startswith(__file__[:-9]) # pyc file and $py.class assert s.endswith("ValueError") assert len(s.split(":")) >= 3 # on windows it's 4 def test_excinfo_errisinstance(): excinfo = pytest.raises(ValueError, h) assert excinfo.errisinstance(ValueError) def test_excinfo_no_sourcecode(): try: exec ("raise ValueError()") except ValueError: excinfo = _pytest._code.ExceptionInfo() s = str(excinfo.traceback[-1]) if py.std.sys.version_info < (2,5): assert s == " File '':1 in ?\n ???\n" else: assert s == " File '':1 in \n ???\n" def test_excinfo_no_python_sourcecode(tmpdir): #XXX: simplified locally testable version tmpdir.join('test.txt').write("{{ h()}}:") jinja2 = pytest.importorskip('jinja2') loader = jinja2.FileSystemLoader(str(tmpdir)) env = jinja2.Environment(loader=loader) template = env.get_template('test.txt') excinfo = pytest.raises(ValueError, template.render, h=h) for item in excinfo.traceback: print(item) #XXX: for some reason jinja.Template.render is printed in full item.source # shouldnt fail if item.path.basename == 'test.txt': assert str(item.source) == '{{ h()}}:' def test_entrysource_Queue_example(): try: queue.Queue().get(timeout=0.001) except queue.Empty: excinfo = _pytest._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(): try: queue.Queue().get(timeout=0.001) except queue.Empty: excinfo = _pytest._code.ExceptionInfo() entry = excinfo.traceback[-1] path = entry.path assert isinstance(path, py.path.local) assert path.basename.lower() == "queue.py" assert path.check() class TestFormattedExcinfo: def pytest_funcarg__importasmod(self, request): def importasmod(source): source = _pytest._code.Source(source) tmpdir = request.getfuncargvalue("tmpdir") modpath = tmpdir.join("mod.py") tmpdir.ensure("__init__.py") modpath.write(source) if invalidate_import_caches is not None: invalidate_import_caches() return modpath.pyimport() return importasmod def excinfo_from_exec(self, source): source = _pytest._code.Source(source).strip() try: exec (source.compile()) except KeyboardInterrupt: raise except: return _pytest._code.ExceptionInfo() assert 0, "did not raise" def test_repr_source(self): pr = FormattedExcinfo() source = _pytest._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) 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 = _pytest._code.ExceptionInfo() repr = pr.repr_excinfo(excinfo) assert repr.reprtraceback.reprentries[1].lines[0] == "> ???" def test_repr_many_line_source_not_existing(self): pr = FormattedExcinfo() co = compile(""" a = 1 raise ValueError() """, "", "exec") try: exec (co) except ValueError: excinfo = _pytest._code.ExceptionInfo() repr = pr.repr_excinfo(excinfo) assert repr.reprtraceback.reprentries[1].lines[0] == "> ???" def test_repr_source_failing_fullsource(self): pr = FormattedExcinfo() class FakeCode(object): class raw: co_filename = '?' path = '?' firstlineno = 5 def fullsource(self): return None fullsource = property(fullsource) class FakeFrame(object): code = FakeCode() f_locals = {} f_globals = {} class FakeTracebackEntry(_pytest._code.Traceback.Entry): def __init__(self, tb): self.lineno = 5+3 @property def frame(self): return FakeFrame() class Traceback(_pytest._code.Traceback): Entry = FakeTracebackEntry class FakeExcinfo(_pytest._code.ExceptionInfo): typename = "Foo" def __init__(self): pass def exconly(self, tryshort): return "EXC" def errisinstance(self, cls): return False excinfo = FakeExcinfo() class FakeRawTB(object): tb_next = None tb = FakeRawTB() excinfo.traceback = Traceback(tb) fail = IOError() # noqa repr = pr.repr_excinfo(excinfo) assert repr.reprtraceback.reprentries[0].lines[0] == "> ???" fail = py.error.ENOENT # noqa repr = pr.repr_excinfo(excinfo) assert repr.reprtraceback.reprentries[0].lines[0] == "> ???" def test_repr_local(self): p = FormattedExcinfo(showlocals=True) loc = {'y': 5, 'z': 7, 'x': 3, '@x': 2, '__builtins__': {}} reprlocals = p.repr_locals(loc) assert reprlocals.lines assert reprlocals.lines[0] == '__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, importasmod): mod = importasmod(""" def func1(): raise ValueError("hello\\nworld") """) excinfo = pytest.raises(ValueError, mod.func1) excinfo.traceback = excinfo.traceback.filter() p = FormattedExcinfo() reprtb = p.repr_traceback_entry(excinfo.traceback[-1]) # 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_lines2(self, importasmod): mod = importasmod(""" def func1(m, x, y, z): raise ValueError("hello\\nworld") """) excinfo = pytest.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_lines_var_kw_args(self, importasmod): mod = importasmod(""" def func1(x, *y, **z): raise ValueError("hello\\nworld") """) excinfo = pytest.raises(ValueError, mod.func1, 'a', 'b', c='d') excinfo.traceback = excinfo.traceback.filter() entry = excinfo.traceback[-1] p = FormattedExcinfo(funcargs=True) reprfuncargs = p.repr_args(entry) assert reprfuncargs.args[0] == ('x', repr('a')) assert reprfuncargs.args[1] == ('y', repr(('b',))) assert reprfuncargs.args[2] == ('z', repr({'c': 'd'})) 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] == "x = 'a', y = ('b',), z = {'c': 'd'}" def test_repr_tracebackentry_short(self, importasmod): mod = importasmod(""" def func1(): raise ValueError("hello") def entry(): func1() """) excinfo = pytest.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] == ' func1()' assert basename in str(reprtb.reprfileloc.path) assert reprtb.reprfileloc.lineno == 5 # test last entry p = FormattedExcinfo(style="short") reprtb = p.repr_traceback_entry(excinfo.traceback[-1], excinfo) lines = reprtb.lines assert lines[0] == ' raise ValueError("hello")' assert lines[1] == 'E ValueError: hello' assert basename in str(reprtb.reprfileloc.path) assert reprtb.reprfileloc.lineno == 3 def test_repr_tracebackentry_no(self, importasmod): mod = importasmod(""" def func1(): raise ValueError("hello") def entry(): func1() """) excinfo = pytest.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, importasmod): mod = importasmod(""" def f(x): raise ValueError(x) def entry(): f(0) """) excinfo = pytest.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_traceback_short_no_source(self, importasmod, monkeypatch): mod = importasmod(""" def func1(): raise ValueError("hello") def entry(): func1() """) excinfo = pytest.raises(ValueError, mod.entry) from _pytest._code.code import Code monkeypatch.setattr(Code, 'path', 'bogus') excinfo.traceback[0].frame.code.path = "bogus" p = FormattedExcinfo(style="short") reprtb = p.repr_traceback_entry(excinfo.traceback[-2]) lines = reprtb.lines last_p = FormattedExcinfo(style="short") last_reprtb = last_p.repr_traceback_entry(excinfo.traceback[-1], excinfo) last_lines = last_reprtb.lines monkeypatch.undo() assert lines[0] == ' func1()' assert last_lines[0] == ' raise ValueError("hello")' assert last_lines[1] == 'E ValueError: hello' def test_repr_traceback_and_excinfo(self, importasmod): mod = importasmod(""" def f(x): raise ValueError(x) def entry(): f(0) """) excinfo = pytest.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_traceback_with_invalid_cwd(self, importasmod, monkeypatch): mod = importasmod(""" def f(x): raise ValueError(x) def entry(): f(0) """) excinfo = pytest.raises(ValueError, mod.entry) p = FormattedExcinfo() def raiseos(): raise OSError(2) monkeypatch.setattr(py.std.os, 'getcwd', raiseos) assert p._makepath(__file__) == __file__ p.repr_traceback(excinfo) def test_repr_excinfo_addouterr(self, importasmod): mod = importasmod(""" def entry(): raise ValueError() """) excinfo = pytest.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, importasmod): mod = importasmod(""" def entry(): raise ValueError() """) excinfo = pytest.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, importasmod): mod = importasmod(""" def rec2(x): return rec1(x+1) def rec1(x): return rec2(x-1) def entry(): rec1(42) """) excinfo = pytest.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, importasmod): # probably this test is a bit redundant # as py/magic/testing/test_assertion.py # already tests correctness of # assertion-reinterpretation logic mod = importasmod(""" def somefunc(): x = 1 assert x == 2 """) excinfo = pytest.raises(AssertionError, mod.somefunc) 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, importasmod): mod = importasmod(""" def f(x): raise ValueError(x) def entry(): f(0) """) excinfo = pytest.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_reprexcinfo_unicode(self): from _pytest._code.code import TerminalRepr class MyRepr(TerminalRepr): def toterminal(self, tw): tw.line(py.builtin._totext("я", "utf-8")) x = py.builtin._totext(MyRepr()) assert x == py.builtin._totext("я", "utf-8") def test_toterminal_long(self, importasmod): mod = importasmod(""" def g(x): raise ValueError(x) def f(): g(3) """) excinfo = pytest.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_toterminal_long_missing_source(self, importasmod, tmpdir): mod = importasmod(""" def g(x): raise ValueError(x) def f(): g(3) """) excinfo = pytest.raises(ValueError, mod.f) tmpdir.join('mod.py').remove() 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] == "> ???" assert tw.lines[1] == "" assert tw.lines[2].endswith("mod.py:5: ") assert tw.lines[3] == ("_ ", None) assert tw.lines[4] == "" assert tw.lines[5] == "> ???" assert tw.lines[6] == "E ValueError: 3" assert tw.lines[7] == "" assert tw.lines[8].endswith("mod.py:3: ValueError") def test_toterminal_long_incomplete_source(self, importasmod, tmpdir): mod = importasmod(""" def g(x): raise ValueError(x) def f(): g(3) """) excinfo = pytest.raises(ValueError, mod.f) tmpdir.join('mod.py').write('asdf') 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] == "> ???" assert tw.lines[1] == "" assert tw.lines[2].endswith("mod.py:5: ") assert tw.lines[3] == ("_ ", None) assert tw.lines[4] == "" assert tw.lines[5] == "> ???" assert tw.lines[6] == "E ValueError: 3" assert tw.lines[7] == "" assert tw.lines[8].endswith("mod.py:3: ValueError") def test_toterminal_long_filenames(self, importasmod): mod = importasmod(""" def f(): raise ValueError() """) excinfo = pytest.raises(ValueError, mod.f) tw = TWMock() path = py.path.local(mod.__file__) old = path.dirpath().chdir() try: repr = excinfo.getrepr(abspath=False) repr.toterminal(tw) line = tw.lines[-1] x = py.path.local().bestrelpath(path) if len(x) < len(str(path)): assert line == "mod.py:3: ValueError" repr = excinfo.getrepr(abspath=True) repr.toterminal(tw) line = tw.lines[-1] assert line == "%s:3: ValueError" %(path,) finally: old.chdir() @pytest.mark.parametrize('reproptions', [ {'style': style, 'showlocals': showlocals, 'funcargs': funcargs, 'tbfilter': tbfilter } for style in ("long", "short", "no") for showlocals in (True, False) for tbfilter in (True, False) for funcargs in (True, False)]) def test_format_excinfo(self, importasmod, reproptions): mod = importasmod(""" def g(x): raise ValueError(x) def f(): g(3) """) excinfo = pytest.raises(ValueError, mod.f) tw = py.io.TerminalWriter(stringio=True) repr = excinfo.getrepr(**reproptions) repr.toterminal(tw) assert tw.stringio.getvalue() def test_native_style(self): excinfo = self.excinfo_from_exec(""" assert 0 """) repr = excinfo.getrepr(style='native') assert "assert 0" in str(repr.reprcrash) s = str(repr) assert s.startswith('Traceback (most recent call last):\n File') assert s.endswith('\nAssertionError: assert 0') assert 'exec (source.compile())' in s # python 2.4 fails to get the source line for the assert if py.std.sys.version_info >= (2, 5): assert s.count('assert 0') == 2 def test_traceback_repr_style(self, importasmod): mod = importasmod(""" def f(): g() def g(): h() def h(): i() def i(): raise ValueError() """) excinfo = pytest.raises(ValueError, mod.f) excinfo.traceback = excinfo.traceback.filter() excinfo.traceback[1].set_repr_style("short") excinfo.traceback[2].set_repr_style("short") r = excinfo.getrepr(style="long") tw = TWMock() r.toterminal(tw) for line in tw.lines: print (line) assert tw.lines[0] == "" assert tw.lines[1] == " def f():" assert tw.lines[2] == "> g()" assert tw.lines[3] == "" assert tw.lines[4].endswith("mod.py:3: ") assert tw.lines[5] == ("_ ", None) assert tw.lines[6].endswith("in g") assert tw.lines[7] == " h()" assert tw.lines[8].endswith("in h") assert tw.lines[9] == " i()" assert tw.lines[10] == ("_ ", None) assert tw.lines[11] == "" assert tw.lines[12] == " def i():" assert tw.lines[13] == "> raise ValueError()" assert tw.lines[14] == "E ValueError" assert tw.lines[15] == "" assert tw.lines[16].endswith("mod.py:9: ValueError")