Merge pull request #7387 from cool-RR/2020-06-11-raise-from
Fix exception causes all over the codebase
This commit is contained in:
commit
83891d9022
1
AUTHORS
1
AUTHORS
|
@ -233,6 +233,7 @@ Pulkit Goyal
|
|||
Punyashloka Biswal
|
||||
Quentin Pradet
|
||||
Ralf Schmitt
|
||||
Ram Rachum
|
||||
Ralph Giles
|
||||
Ran Benita
|
||||
Raphael Castaneda
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Fixed exception causes all over the codebase, i.e. use `raise new_exception from old_exception` when wrapping an exception.
|
|
@ -215,7 +215,7 @@ class Source:
|
|||
newex.offset = ex.offset
|
||||
newex.lineno = ex.lineno
|
||||
newex.text = ex.text
|
||||
raise newex
|
||||
raise newex from ex
|
||||
else:
|
||||
if flag & ast.PyCF_ONLY_AST:
|
||||
assert isinstance(co, ast.AST)
|
||||
|
|
|
@ -1189,8 +1189,8 @@ class Config:
|
|||
def _getini(self, name: str) -> Any:
|
||||
try:
|
||||
description, type, default = self._parser._inidict[name]
|
||||
except KeyError:
|
||||
raise ValueError("unknown configuration value: {!r}".format(name))
|
||||
except KeyError as e:
|
||||
raise ValueError("unknown configuration value: {!r}".format(name)) from e
|
||||
override_value = self._get_override_ini_value(name)
|
||||
if override_value is None:
|
||||
try:
|
||||
|
@ -1286,14 +1286,14 @@ class Config:
|
|||
if val is None and skip:
|
||||
raise AttributeError(name)
|
||||
return val
|
||||
except AttributeError:
|
||||
except AttributeError as e:
|
||||
if default is not notset:
|
||||
return default
|
||||
if skip:
|
||||
import pytest
|
||||
|
||||
pytest.skip("no {!r} option found".format(name))
|
||||
raise ValueError("no option named {!r}".format(name))
|
||||
raise ValueError("no option named {!r}".format(name)) from e
|
||||
|
||||
def getvalue(self, name, path=None):
|
||||
""" (deprecated, use getoption()) """
|
||||
|
|
|
@ -265,9 +265,9 @@ class Argument:
|
|||
else:
|
||||
try:
|
||||
self.dest = self._short_opts[0][1:]
|
||||
except IndexError:
|
||||
except IndexError as e:
|
||||
self.dest = "???" # Needed for the error repr.
|
||||
raise ArgumentError("need a long or short option", self)
|
||||
raise ArgumentError("need a long or short option", self) from e
|
||||
|
||||
def names(self) -> List[str]:
|
||||
return self._short_opts + self._long_opts
|
||||
|
|
|
@ -26,7 +26,7 @@ def _parse_ini_config(path: py.path.local) -> iniconfig.IniConfig:
|
|||
try:
|
||||
return iniconfig.IniConfig(path)
|
||||
except iniconfig.ParseError as exc:
|
||||
raise UsageError(str(exc))
|
||||
raise UsageError(str(exc)) from exc
|
||||
|
||||
|
||||
def load_config_dict_from_file(
|
||||
|
|
|
@ -28,10 +28,10 @@ def _validate_usepdb_cls(value: str) -> Tuple[str, str]:
|
|||
"""Validate syntax of --pdbcls option."""
|
||||
try:
|
||||
modname, classname = value.split(":")
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
raise argparse.ArgumentTypeError(
|
||||
"{!r} is not in the format 'modname:classname'".format(value)
|
||||
)
|
||||
) from e
|
||||
return (modname, classname)
|
||||
|
||||
|
||||
|
@ -130,7 +130,7 @@ class pytestPDB:
|
|||
value = ":".join((modname, classname))
|
||||
raise UsageError(
|
||||
"--pdbcls: could not import {!r}: {}".format(value, exc)
|
||||
)
|
||||
) from exc
|
||||
else:
|
||||
import pdb
|
||||
|
||||
|
|
|
@ -938,13 +938,13 @@ def _eval_scope_callable(
|
|||
# Type ignored because there is no typing mechanism to specify
|
||||
# keyword arguments, currently.
|
||||
result = scope_callable(fixture_name=fixture_name, config=config) # type: ignore[call-arg] # noqa: F821
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
raise TypeError(
|
||||
"Error evaluating {} while defining fixture '{}'.\n"
|
||||
"Expected a function with the signature (*, fixture_name, config)".format(
|
||||
scope_callable, fixture_name
|
||||
)
|
||||
)
|
||||
) from e
|
||||
if not isinstance(result, str):
|
||||
fail(
|
||||
"Expected {} to return a 'str' while defining fixture '{}', but it returned:\n"
|
||||
|
|
|
@ -487,13 +487,13 @@ def get_log_level_for_setting(config: Config, *setting_names: str) -> Optional[i
|
|||
log_level = log_level.upper()
|
||||
try:
|
||||
return int(getattr(logging, log_level, log_level))
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
# Python logging does not recognise this as a logging level
|
||||
raise pytest.UsageError(
|
||||
"'{}' is not recognized as a logging level name for "
|
||||
"'{}'. Please consider passing the "
|
||||
"logging level num instead.".format(log_level, setting_name)
|
||||
)
|
||||
) from e
|
||||
|
||||
|
||||
# run after terminalreporter/capturemanager are configured
|
||||
|
|
|
@ -73,7 +73,7 @@ def resolve(name: str) -> object:
|
|||
if expected == used:
|
||||
raise
|
||||
else:
|
||||
raise ImportError("import error in {}: {}".format(used, ex))
|
||||
raise ImportError("import error in {}: {}".format(used, ex)) from ex
|
||||
found = annotated_getattr(found, part, used)
|
||||
return found
|
||||
|
||||
|
@ -81,12 +81,12 @@ def resolve(name: str) -> object:
|
|||
def annotated_getattr(obj: object, name: str, ann: str) -> object:
|
||||
try:
|
||||
obj = getattr(obj, name)
|
||||
except AttributeError:
|
||||
except AttributeError as e:
|
||||
raise AttributeError(
|
||||
"{!r} object at {} has no attribute {!r}".format(
|
||||
type(obj).__name__, ann, name
|
||||
)
|
||||
)
|
||||
) from e
|
||||
return obj
|
||||
|
||||
|
||||
|
|
|
@ -551,8 +551,10 @@ class Module(nodes.File, PyCollector):
|
|||
importmode = self.config.getoption("--import-mode")
|
||||
try:
|
||||
mod = import_path(self.fspath, mode=importmode)
|
||||
except SyntaxError:
|
||||
raise self.CollectError(ExceptionInfo.from_current().getrepr(style="short"))
|
||||
except SyntaxError as e:
|
||||
raise self.CollectError(
|
||||
ExceptionInfo.from_current().getrepr(style="short")
|
||||
) from e
|
||||
except ImportPathMismatchError as e:
|
||||
raise self.CollectError(
|
||||
"import file mismatch:\n"
|
||||
|
@ -562,8 +564,8 @@ class Module(nodes.File, PyCollector):
|
|||
" %s\n"
|
||||
"HINT: remove __pycache__ / .pyc files and/or use a "
|
||||
"unique basename for your test file modules" % e.args
|
||||
)
|
||||
except ImportError:
|
||||
) from e
|
||||
except ImportError as e:
|
||||
exc_info = ExceptionInfo.from_current()
|
||||
if self.config.getoption("verbose") < 2:
|
||||
exc_info.traceback = exc_info.traceback.filter(filter_traceback)
|
||||
|
@ -578,7 +580,7 @@ class Module(nodes.File, PyCollector):
|
|||
"Hint: make sure your test modules/packages have valid Python names.\n"
|
||||
"Traceback:\n"
|
||||
"{traceback}".format(fspath=self.fspath, traceback=formatted_tb)
|
||||
)
|
||||
) from e
|
||||
except _pytest.runner.Skipped as e:
|
||||
if e.allow_module_level:
|
||||
raise
|
||||
|
@ -587,7 +589,7 @@ class Module(nodes.File, PyCollector):
|
|||
"To decorate a test function, use the @pytest.mark.skip "
|
||||
"or @pytest.mark.skipif decorators instead, and to skip a "
|
||||
"module use `pytestmark = pytest.mark.{skip,skipif}."
|
||||
)
|
||||
) from e
|
||||
self.config.pluginmanager.consider_module(mod)
|
||||
return mod
|
||||
|
||||
|
@ -836,8 +838,8 @@ class CallSpec2:
|
|||
def getparam(self, name: str) -> object:
|
||||
try:
|
||||
return self.params[name]
|
||||
except KeyError:
|
||||
raise ValueError(name)
|
||||
except KeyError as e:
|
||||
raise ValueError(name) from e
|
||||
|
||||
@property
|
||||
def id(self) -> str:
|
||||
|
@ -1074,8 +1076,8 @@ class Metafunc:
|
|||
except TypeError:
|
||||
try:
|
||||
iter(ids)
|
||||
except TypeError:
|
||||
raise TypeError("ids must be a callable or an iterable")
|
||||
except TypeError as e:
|
||||
raise TypeError("ids must be a callable or an iterable") from e
|
||||
num_ids = len(parameters)
|
||||
|
||||
# num_ids == 0 is a special case: https://github.com/pytest-dev/pytest/issues/1849
|
||||
|
|
|
@ -48,8 +48,8 @@ def _parse_filter(
|
|||
lineno = int(lineno_)
|
||||
if lineno < 0:
|
||||
raise ValueError
|
||||
except (ValueError, OverflowError):
|
||||
raise warnings._OptionError("invalid lineno {!r}".format(lineno_))
|
||||
except (ValueError, OverflowError) as e:
|
||||
raise warnings._OptionError("invalid lineno {!r}".format(lineno_)) from e
|
||||
else:
|
||||
lineno = 0
|
||||
return (action, message, category, module, lineno)
|
||||
|
|
|
@ -1778,5 +1778,5 @@ def test_conftest_import_error_repr(tmpdir):
|
|||
):
|
||||
try:
|
||||
raise RuntimeError("some error")
|
||||
except Exception:
|
||||
raise ConftestImportFailure(path, sys.exc_info())
|
||||
except Exception as e:
|
||||
raise ConftestImportFailure(path, sys.exc_info()) from e
|
||||
|
|
|
@ -534,8 +534,8 @@ def test_outcomeexception_passes_except_Exception() -> None:
|
|||
with pytest.raises(outcomes.OutcomeException):
|
||||
try:
|
||||
raise outcomes.OutcomeException("test")
|
||||
except Exception:
|
||||
raise NotImplementedError()
|
||||
except Exception as e:
|
||||
raise NotImplementedError from e
|
||||
|
||||
|
||||
def test_pytest_exit() -> None:
|
||||
|
|
Loading…
Reference in New Issue