Skip to content

Commit 9e1e7fc

Browse files
committed
Use a nice string repr for ConftestImportFailure
The default message is often hard to read: E _pytest.config.ConftestImportFailure: (local('D:\\projects\\pytest\\.tmp\\root\\foo\\conftest.py'), (<class 'RuntimeError'>, RuntimeError('some error',), <traceback object at 0x000001CCC3E39348>)) Using a shorter message is better: E _pytest.config.ConftestImportFailure: RuntimeError: some error (from D:\projects\pytest\.tmp\root\foo\conftest.py) And we don't really lose any information due to exception chaining.
1 parent 5eaebc1 commit 9e1e7fc

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/_pytest/config/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,15 @@ class ExitCode(enum.IntEnum):
8888

8989
class ConftestImportFailure(Exception):
9090
def __init__(self, path, excinfo):
91-
Exception.__init__(self, path, excinfo)
91+
super().__init__(path, excinfo)
9292
self.path = path
9393
self.excinfo = excinfo # type: Tuple[Type[Exception], Exception, TracebackType]
9494

95+
def __str__(self):
96+
return "{}: {} (from {})".format(
97+
self.excinfo[0].__name__, self.excinfo[1], self.path
98+
)
99+
95100

96101
def main(args=None, plugins=None) -> Union[int, ExitCode]:
97102
""" return exit code, after performing an in-process test run.

testing/test_config.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from _pytest.compat import importlib_metadata
1111
from _pytest.config import _iter_rewritable_modules
1212
from _pytest.config import Config
13+
from _pytest.config import ConftestImportFailure
1314
from _pytest.config import ExitCode
1415
from _pytest.config.exceptions import UsageError
1516
from _pytest.config.findpaths import determine_setup
@@ -1471,3 +1472,19 @@ def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_false_positives
14711472
assert res.ret == 0
14721473
msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported"
14731474
assert msg not in res.stdout.str()
1475+
1476+
1477+
def test_conftest_import_error_repr(tmpdir):
1478+
"""
1479+
ConftestImportFailure should use a short error message and readable path to the failed
1480+
conftest.py file
1481+
"""
1482+
path = tmpdir.join("foo/conftest.py")
1483+
with pytest.raises(
1484+
ConftestImportFailure,
1485+
match=re.escape("RuntimeError: some error (from {})".format(path)),
1486+
):
1487+
try:
1488+
raise RuntimeError("some error")
1489+
except Exception:
1490+
raise ConftestImportFailure(path, sys.exc_info())

0 commit comments

Comments
 (0)