From 5eaebc1900e2c5c0fb911ff9c325efa80441d030 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 16 May 2020 15:46:06 -0300 Subject: [PATCH] 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 --- src/_pytest/config/__init__.py | 57 ++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 8a2c16d5d..d45feb624 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -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