From 19c92b55f80d0d1dcaeb7efdeff1f423c8ac61d3 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 3 Feb 2020 08:49:14 +0100 Subject: [PATCH 1/3] Inline FunctionMixin with Function `Generator` was removed in 7eb28f9eb, and this pleases mypy to correctly complain that `FunctionMixin` has no `config` (within `_prunetraceback`). --- src/_pytest/python.py | 73 +++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 5e3b5f2867e..20b3f731d88 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -773,45 +773,6 @@ def newinstance(self): return self.obj -class FunctionMixin(PyobjMixin): - """ mixin for the code common to Function and Generator. - """ - - def setup(self): - """ perform setup for this test function. """ - if isinstance(self.parent, Instance): - self.parent.newinstance() - self.obj = self._getobj() - - def _prunetraceback(self, excinfo): - if hasattr(self, "_obj") and not self.config.getoption("fulltrace", False): - code = _pytest._code.Code(get_real_func(self.obj)) - path, firstlineno = code.path, code.firstlineno - traceback = excinfo.traceback - ntraceback = traceback.cut(path=path, firstlineno=firstlineno) - if ntraceback == traceback: - ntraceback = ntraceback.cut(path=path) - if ntraceback == traceback: - ntraceback = ntraceback.filter(filter_traceback) - if not ntraceback: - ntraceback = traceback - - excinfo.traceback = ntraceback.filter() - # issue364: mark all but first and last frames to - # only show a single-line message for each frame - if self.config.getoption("tbstyle", "auto") == "auto": - if len(excinfo.traceback) > 2: - for entry in excinfo.traceback[1:-1]: - entry.set_repr_style("short") - - def repr_failure(self, excinfo, outerr=None): - assert outerr is None, "XXX outerr usage is deprecated" - style = self.config.getoption("tbstyle", "auto") - if style == "auto": - style = "long" - return self._repr_failure_py(excinfo, style=style) - - def hasinit(obj): init = getattr(obj, "__init__", None) if init: @@ -1397,7 +1358,7 @@ def write_docstring(tw, doc, indent=" "): tw.write(indent + line + "\n") -class Function(FunctionMixin, nodes.Item): +class Function(PyobjMixin, nodes.Item): """ a Function Item is responsible for setting up and executing a Python test function. """ @@ -1502,9 +1463,39 @@ def runtest(self): self.ihook.pytest_pyfunc_call(pyfuncitem=self) def setup(self): - super().setup() + if isinstance(self.parent, Instance): + self.parent.newinstance() + self.obj = self._getobj() fixtures.fillfixtures(self) + def _prunetraceback(self, excinfo): + if hasattr(self, "_obj") and not self.config.getoption("fulltrace", False): + code = _pytest._code.Code(get_real_func(self.obj)) + path, firstlineno = code.path, code.firstlineno + traceback = excinfo.traceback + ntraceback = traceback.cut(path=path, firstlineno=firstlineno) + if ntraceback == traceback: + ntraceback = ntraceback.cut(path=path) + if ntraceback == traceback: + ntraceback = ntraceback.filter(filter_traceback) + if not ntraceback: + ntraceback = traceback + + excinfo.traceback = ntraceback.filter() + # issue364: mark all but first and last frames to + # only show a single-line message for each frame + if self.config.getoption("tbstyle", "auto") == "auto": + if len(excinfo.traceback) > 2: + for entry in excinfo.traceback[1:-1]: + entry.set_repr_style("short") + + def repr_failure(self, excinfo, outerr=None): + assert outerr is None, "XXX outerr usage is deprecated" + style = self.config.getoption("tbstyle", "auto") + if style == "auto": + style = "long" + return self._repr_failure_py(excinfo, style=style) + class FunctionDefinition(Function): """ From 2343f70ce9cd1138bd287ea4e21fa14c73bdd6b8 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 3 Feb 2020 08:55:02 +0100 Subject: [PATCH 2/3] typing: _prunetraceback --- src/_pytest/python.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 20b3f731d88..02dd3d80fdf 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -21,6 +21,7 @@ from _pytest import fixtures from _pytest import nodes from _pytest._code import filter_traceback +from _pytest._code.code import ExceptionInfo from _pytest.compat import ascii_escaped from _pytest.compat import get_default_arg_names from _pytest.compat import get_real_func @@ -1468,7 +1469,7 @@ def setup(self): self.obj = self._getobj() fixtures.fillfixtures(self) - def _prunetraceback(self, excinfo): + def _prunetraceback(self, excinfo: ExceptionInfo) -> None: if hasattr(self, "_obj") and not self.config.getoption("fulltrace", False): code = _pytest._code.Code(get_real_func(self.obj)) path, firstlineno = code.path, code.firstlineno From 5be918c2b16125d9f0f185bdc01b1bbf2b4ebef5 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 3 Feb 2020 08:55:24 +0100 Subject: [PATCH 3/3] minor --- src/_pytest/python.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 02dd3d80fdf..466f260f79d 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -504,9 +504,7 @@ def _importtestmodule(self): try: mod = self.fspath.pyimport(ensuresyspath=importmode) except SyntaxError: - raise self.CollectError( - _pytest._code.ExceptionInfo.from_current().getrepr(style="short") - ) + raise self.CollectError(ExceptionInfo.from_current().getrepr(style="short")) except self.fspath.ImportMismatchError: e = sys.exc_info()[1] raise self.CollectError( @@ -519,8 +517,6 @@ def _importtestmodule(self): "unique basename for your test file modules" % e.args ) except ImportError: - from _pytest._code.code import ExceptionInfo - exc_info = ExceptionInfo.from_current() if self.config.getoption("verbose") < 2: exc_info.traceback = exc_info.traceback.filter(filter_traceback) @@ -1463,7 +1459,7 @@ def runtest(self): """ execute the underlying test function. """ self.ihook.pytest_pyfunc_call(pyfuncitem=self) - def setup(self): + def setup(self) -> None: if isinstance(self.parent, Instance): self.parent.newinstance() self.obj = self._getobj()