def repr_failure(self, excinfo: ExceptionInfo) -> str: if excinfo.errisinstance(SystemExit): # We assume that before doing exit() (which raises SystemExit) we've printed # enough context about what happened so that a stack trace is not useful. # In particular, uncaught exceptions during semantic analysis or type checking # call exit() and they already print out a stack trace. return excinfo.exconly(tryshort=True) elif excinfo.errisinstance(TypecheckAssertionError): # with traceback removed exception_repr = excinfo.getrepr(style='short') exception_repr.reprcrash.message = '' repr_file_location = ReprFileLocation(path=self.fspath, lineno=self.starting_lineno + excinfo.value.lineno, message='') repr_tb_entry = TraceLastReprEntry( filelocrepr=repr_file_location, lines=exception_repr.reprtraceback.reprentries[-1].lines[1:], style='short', reprlocals=None, reprfuncargs=None) exception_repr.reprtraceback.reprentries = [repr_tb_entry] return exception_repr else: return super().repr_failure(excinfo, style='native')
def test_ExceptionChainRepr(): """Test ExceptionChainRepr, especially with regard to being hashable.""" try: raise ValueError() except ValueError: excinfo1 = ExceptionInfo.from_current() excinfo2 = ExceptionInfo.from_current() repr1 = excinfo1.getrepr() repr2 = excinfo2.getrepr() assert repr1 != repr2 assert isinstance(repr1, ExceptionChainRepr) assert hash(repr1) != hash(repr2) assert repr1 is not excinfo1.getrepr()
def main( args: Optional[List[str]] = None, plugins: Optional[Sequence[Union[str, _PluggyPlugin]]] = None, ) -> Union[int, ExitCode]: """Perform an in-process test run. :param args: List of command line arguments. :param plugins: List of plugin objects to be auto-registered during initialization. :returns: An exit code. """ try: try: config = _prepareconfig(args, plugins) except ConftestImportFailure as e: exc_info = ExceptionInfo(e.excinfo) tw = TerminalWriter(sys.stderr) tw.line( "ImportError while loading conftest '{e.path}'.".format(e=e), red=True ) exc_info.traceback = exc_info.traceback.filter( filter_traceback_for_conftest_import_failure ) exc_repr = ( exc_info.getrepr(style="short", chain=False) if exc_info.traceback else exc_info.exconly() ) formatted_tb = str(exc_repr) for line in formatted_tb.splitlines(): tw.line(line.rstrip(), red=True) return ExitCode.USAGE_ERROR else: try: ret = config.hook.pytest_cmdline_main( config=config ) # type: Union[ExitCode, int] try: return ExitCode(ret) except ValueError: return ret finally: config._ensure_unconfigure() except UsageError as e: tw = TerminalWriter(sys.stderr) for msg in e.args: tw.line("ERROR: {}\n".format(msg), red=True) return ExitCode.USAGE_ERROR
def process_from_remote(self, eventcall): # noqa too complex """ this gets called for each object we receive from the other side and if the channel closes. Note that channel callbacks run in the receiver thread of execnet gateways - we need to avoid raising exceptions or doing heavy work. """ try: if eventcall == self.ENDMARK: err = self.channel._getremoteerror() if not self._down: if not err or isinstance(err, EOFError): err = "Not properly terminated" # lost connection? self.notify_inproc("errordown", node=self, error=err) self._down = True return eventname, kwargs = eventcall if eventname in ("collectionstart", ): self.log("ignoring %s(%s)" % (eventname, kwargs)) elif eventname == "workerready": self.notify_inproc(eventname, node=self, **kwargs) elif eventname == "workerfinished": self._down = True self.workeroutput = self.slaveoutput = kwargs["workeroutput"] self.notify_inproc("workerfinished", node=self) elif eventname in ("logstart", "logfinish"): self.notify_inproc(eventname, node=self, **kwargs) elif eventname in ("testreport", "collectreport", "teardownreport"): item_index = kwargs.pop("item_index", None) rep = unserialize_report(eventname, kwargs["data"]) if item_index is not None: rep.item_index = item_index self.notify_inproc(eventname, node=self, rep=rep) elif eventname == "collectionfinish": self.notify_inproc(eventname, node=self, ids=kwargs["ids"]) elif eventname == "runtest_protocol_complete": self.notify_inproc(eventname, node=self, **kwargs) elif eventname == "logwarning": self.notify_inproc( eventname, message=kwargs["message"], code=kwargs["code"], nodeid=kwargs["nodeid"], fslocation=kwargs["nodeid"], ) else: raise ValueError("unknown event: %s" % (eventname, )) except KeyboardInterrupt: # should not land in receiver-thread raise except: # noqa from _pytest._code import ExceptionInfo excinfo = ExceptionInfo() print("!" * 20, excinfo) self.config.notify_exception(excinfo) self.shutdown() self.notify_inproc("errordown", node=self, error=excinfo)
def test(self, msg=None, **kwargs): start = time.time() precise_start = time.perf_counter() exc_info = None with self._capturing_output() as captured: try: yield except (Exception, OutcomeException): exc_info = ExceptionInfo.from_current() precise_stop = time.perf_counter() duration = precise_stop - precise_start stop = time.time() call_info = make_call_info( exc_info, start=start, stop=stop, duration=duration, when="call" ) report = self.ihook.pytest_runtest_makereport(item=self.item, call=call_info) sub_report = SubTestReport._from_test_report(report) sub_report.context = SubTestContext(msg, kwargs.copy()) captured.update_report(sub_report) with self.suspend_capture_ctx(): self.ihook.pytest_runtest_logreport(report=sub_report) if check_interactive_exception(call_info, sub_report): self.ihook.pytest_exception_interact( node=self.item, call=call_info, report=sub_report )
def test_exception_printing_skip() -> None: assert pytest.skip.Exception == pytest.skip.Exception try: pytest.skip("hello") except pytest.skip.Exception: excinfo = ExceptionInfo.from_current() s = excinfo.exconly(tryshort=True) assert s.startswith("Skipped")
def test_tb_entry_str(self): try: assert False except AssertionError: exci = ExceptionInfo.from_current() pattern = r" File '.*test_code.py':\d+ in test_tb_entry_str\n assert False" entry = str(exci.traceback[0]) assert re.match(pattern, entry)
def _addSubTest(self, test_case, test, exc_info): if exc_info is not None: msg = test._message if isinstance(test._message, str) else None call_info = CallInfo(None, ExceptionInfo(exc_info), 0, 0, when="call") sub_report = SubTestReport.from_item_and_call(item=self, call=call_info) sub_report.context = SubTestContext(msg, dict(test.params)) self.ihook.pytest_runtest_logreport(report=sub_report)
def main(args=None, plugins=None) -> "Union[int, _pytest.main.ExitCode]": """ return exit code, after performing an in-process test run. :arg args: list of command line arguments. :arg plugins: list of plugin objects to be auto-registered during initialization. """ from _pytest.main import ExitCode try: try: config = _prepareconfig(args, plugins) except ConftestImportFailure as e: exc_info = ExceptionInfo(e.excinfo) tw = py.io.TerminalWriter(sys.stderr) tw.line( "ImportError while loading conftest '{e.path}'.".format(e=e), red=True ) exc_info.traceback = exc_info.traceback.filter(filter_traceback) exc_repr = ( exc_info.getrepr(style="short", chain=False) if exc_info.traceback else exc_info.exconly() ) formatted_tb = str(exc_repr) for line in formatted_tb.splitlines(): tw.line(line.rstrip(), red=True) return ExitCode.USAGE_ERROR else: try: ret = config.hook.pytest_cmdline_main( config=config ) # type: Union[ExitCode, int] try: return ExitCode(ret) except ValueError: return ret finally: config._ensure_unconfigure() except UsageError as e: tw = py.io.TerminalWriter(sys.stderr) for msg in e.args: tw.line("ERROR: {}\n".format(msg), red=True) return ExitCode.USAGE_ERROR
def test_bad_getsource(self) -> None: try: if False: pass else: assert False except AssertionError: exci = ExceptionInfo.from_current() assert exci.getrepr()
def main(args=None, plugins=None): """ return exit code, after performing an in-process test run. :arg args: list of command line arguments. :arg plugins: list of plugin objects to be auto-registered during initialization. """ from _pytest.main import EXIT_USAGEERROR try: try: config = _prepareconfig(args, plugins) except ConftestImportFailure as e: exc_info = ExceptionInfo(e.excinfo) tw = py.io.TerminalWriter(sys.stderr) tw.line( "ImportError while loading conftest '{e.path}'.".format(e=e), red=True ) exc_info.traceback = exc_info.traceback.filter(filter_traceback) exc_repr = ( exc_info.getrepr(style="short", chain=False) if exc_info.traceback else exc_info.exconly() ) formatted_tb = safe_str(exc_repr) for line in formatted_tb.splitlines(): tw.line(line.rstrip(), red=True) return 4 else: try: return config.hook.pytest_cmdline_main(config=config) finally: config._ensure_unconfigure() except UsageError as e: tw = py.io.TerminalWriter(sys.stderr) for msg in e.args: tw.line("ERROR: {}\n".format(msg), red=True) return EXIT_USAGEERROR
def test_getsource(self) -> None: try: if False: pass else: assert False except AssertionError: exci = ExceptionInfo.from_current() entry = exci.traceback[0] source = entry.getsource() assert source is not None assert len(source) == 6 assert "assert False" in source[5]
def _addSubTest(self, test_case, test, exc_info): if exc_info is not None: msg = test._message if isinstance(test._message, str) else None call_info = make_call_info( ExceptionInfo(exc_info), start=0, stop=0, duration=0, when="call" ) report = self.ihook.pytest_runtest_makereport(item=self, call=call_info) sub_report = SubTestReport._from_test_report(report) sub_report.context = SubTestContext(msg, dict(test.params)) self.ihook.pytest_runtest_logreport(report=sub_report) if check_interactive_exception(call_info, sub_report): self.ihook.pytest_exception_interact( node=self, call=call_info, report=sub_report )
def worker_internal_error(self, node, formatted_error): """ pytest_internalerror() was called on the worker. pytest_internalerror() arguments are an excinfo and an excrepr, which can't be serialized, so we go with a poor man's solution of raising an exception here ourselves using the formatted message. """ self._active_nodes.remove(node) try: assert False, formatted_error except AssertionError: from _pytest._code import ExceptionInfo excinfo = ExceptionInfo.from_current() excrepr = excinfo.getrepr() self.config.hook.pytest_internalerror(excrepr=excrepr, excinfo=excinfo)
def test(self, msg=None, **kwargs): start = monotonic() exc_info = None with self._capturing_output() as captured: try: yield except (Exception, OutcomeException): exc_info = ExceptionInfo.from_current() stop = monotonic() call_info = CallInfo(None, exc_info, start, stop, when="call") sub_report = SubTestReport.from_item_and_call(item=self.item, call=call_info) sub_report.context = SubTestContext(msg, kwargs.copy()) captured.update_report(sub_report) with self.suspend_capture_ctx(): self.ihook.pytest_runtest_logreport(report=sub_report)
def test_from_current_with_missing(self) -> None: with pytest.raises(AssertionError, match="no current exception"): ExceptionInfo.from_current()