Remove one of the tracebacks from conftest import failures

This removes the KeyError from the traceback chain when an
conftest fails to import:

    return self._conftestpath2mod[key]
    E   KeyError: WindowsPath('D:/projects/pytest/.tmp/root/foo/conftest.py')

    During handling of the above exception, another exception occurred:
    ...
        raise RuntimeError("some error")
    E   RuntimeError: some error

    During handling of the above exception, another exception occurred:
    ...
    E   _pytest.config.ConftestImportFailure: (...)

By slightly changing the code, we can remove the first chain, which is often
very confusing to users and doesn't help with anything.

Fix #7223
This commit is contained in:
Bruno Oliveira 2020-05-16 15:46:06 -03:00
parent d4dfe863c9
commit 5eaebc1900
1 changed files with 30 additions and 27 deletions

View File

@ -1,5 +1,6 @@
""" command line options, ini-file and conftest.py processing. """
import argparse
import contextlib
import copy
import enum
import inspect
@ -511,34 +512,36 @@ class PytestPluginManager(PluginManager):
# Using Path().resolve() is better than py.path.realpath because
# it resolves to the correct path/drive in case-insensitive file systems (#5792)
key = Path(str(conftestpath)).resolve()
try:
return self._conftestpath2mod[key]
except KeyError:
pkgpath = conftestpath.pypkgpath()
if pkgpath is None:
_ensure_removed_sysmodule(conftestpath.purebasename)
try:
mod = conftestpath.pyimport()
if (
hasattr(mod, "pytest_plugins")
and self._configured
and not self._using_pyargs
):
_fail_on_non_top_pytest_plugins(conftestpath, self._confcutdir)
except Exception:
raise ConftestImportFailure(conftestpath, sys.exc_info())
self._conftest_plugins.add(mod)
self._conftestpath2mod[key] = mod
dirpath = conftestpath.dirpath()
if dirpath in self._dirpath2confmods:
for path, mods in self._dirpath2confmods.items():
if path and path.relto(dirpath) or path == dirpath:
assert mod not in mods
mods.append(mod)
self.trace("loading conftestmodule {!r}".format(mod))
self.consider_conftest(mod)
return mod
with contextlib.suppress(KeyError):
return self._conftestpath2mod[key]
pkgpath = conftestpath.pypkgpath()
if pkgpath is None:
_ensure_removed_sysmodule(conftestpath.purebasename)
try:
mod = conftestpath.pyimport()
if (
hasattr(mod, "pytest_plugins")
and self._configured
and not self._using_pyargs
):
_fail_on_non_top_pytest_plugins(conftestpath, self._confcutdir)
except Exception as e:
raise ConftestImportFailure(conftestpath, sys.exc_info()) from e
self._conftest_plugins.add(mod)
self._conftestpath2mod[key] = mod
dirpath = conftestpath.dirpath()
if dirpath in self._dirpath2confmods:
for path, mods in self._dirpath2confmods.items():
if path and path.relto(dirpath) or path == dirpath:
assert mod not in mods
mods.append(mod)
self.trace("loading conftestmodule {!r}".format(mod))
self.consider_conftest(mod)
return mod
#
# API for bootstrapping plugin loading