Display traceback from Import errors using pytest's short representation
Also omit pytest's own modules and internal libraries (py and pluggy) in low verbosity Fix #1976
This commit is contained in:
parent
7d66e4eae1
commit
a1d446b8e8
|
@ -22,11 +22,16 @@ from _pytest.compat import (
|
|||
getlocation, enum,
|
||||
)
|
||||
|
||||
cutdir2 = py.path.local(_pytest.__file__).dirpath()
|
||||
cutdir1 = py.path.local(pluggy.__file__.rstrip("oc"))
|
||||
cutdir2 = py.path.local(_pytest.__file__).dirpath()
|
||||
cutdir3 = py.path.local(py.__file__).dirpath()
|
||||
|
||||
|
||||
def filter_traceback(entry):
|
||||
"""Return True if a TracebackEntry instance should be removed from tracebacks:
|
||||
* dynamically generated code (no code to show up for it);
|
||||
* internal traceback from pytest or its internal libraries, py and pluggy.
|
||||
"""
|
||||
# entry.path might sometimes return a str object when the entry
|
||||
# points to dynamically generated code
|
||||
# see https://bitbucket.org/pytest-dev/py/issues/71
|
||||
|
@ -37,7 +42,7 @@ def filter_traceback(entry):
|
|||
# entry.path might point to an inexisting file, in which case it will
|
||||
# alsso return a str object. see #1133
|
||||
p = py.path.local(entry.path)
|
||||
return p != cutdir1 and not p.relto(cutdir2)
|
||||
return p != cutdir1 and not p.relto(cutdir2) and not p.relto(cutdir3)
|
||||
|
||||
|
||||
|
||||
|
@ -424,14 +429,16 @@ class Module(pytest.File, PyCollector):
|
|||
% e.args
|
||||
)
|
||||
except ImportError:
|
||||
import traceback
|
||||
stream = py.io.TextIO()
|
||||
traceback.print_exc(file=stream)
|
||||
formatted_tb = stream.getvalue()
|
||||
from _pytest._code.code import ExceptionInfo
|
||||
exc_info = ExceptionInfo()
|
||||
if self.config.getoption('verbose') < 2:
|
||||
exc_info.traceback = exc_info.traceback.filter(filter_traceback)
|
||||
exc_repr = exc_info.getrepr(style='short') if exc_info.traceback else exc_info.exconly()
|
||||
formatted_tb = py._builtin._totext(exc_repr)
|
||||
raise self.CollectError(
|
||||
"ImportError while importing test module '{fspath}'.\n"
|
||||
"Hint: make sure your test modules/packages have valid Python names.\n"
|
||||
"Original traceback:\n"
|
||||
"Traceback:\n"
|
||||
"{traceback}".format(fspath=self.fspath, traceback=formatted_tb)
|
||||
)
|
||||
except _pytest.runner.Skipped as e:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import sys
|
||||
from textwrap import dedent
|
||||
|
||||
|
@ -71,8 +72,12 @@ class TestModule:
|
|||
"Hint: make sure your test modules/packages have valid Python names.",
|
||||
])
|
||||
|
||||
def test_show_full_traceback_import_error(self, testdir):
|
||||
"""Import errors when collecting modules should display the full traceback (#1976)."""
|
||||
@pytest.mark.parametrize('verbose', [0, 1, 2])
|
||||
def test_show_traceback_import_error(self, testdir, verbose):
|
||||
"""Import errors when collecting modules should display the traceback (#1976).
|
||||
|
||||
With low verbosity we omit pytest and internal modules, otherwise show all traceback entries.
|
||||
"""
|
||||
testdir.makepyfile(
|
||||
foo_traceback_import_error="""
|
||||
from bar_traceback_import_error import NOT_AVAILABLE
|
||||
|
@ -82,15 +87,23 @@ class TestModule:
|
|||
testdir.makepyfile("""
|
||||
import foo_traceback_import_error
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
args = ('-v',) * verbose
|
||||
result = testdir.runpytest(*args)
|
||||
result.stdout.fnmatch_lines([
|
||||
"ImportError while importing test module*",
|
||||
"Original traceback:",
|
||||
"Traceback:",
|
||||
"*from bar_traceback_import_error import NOT_AVAILABLE",
|
||||
"*cannot import name *NOT_AVAILABLE*",
|
||||
])
|
||||
assert result.ret == 2
|
||||
|
||||
stdout = result.stdout.str()
|
||||
for name in ('_pytest', os.path.join('py', '_path')):
|
||||
if verbose == 2:
|
||||
assert name in stdout
|
||||
else:
|
||||
assert name not in stdout
|
||||
|
||||
|
||||
class TestClass:
|
||||
def test_class_with_init_warning(self, testdir):
|
||||
|
|
Loading…
Reference in New Issue