def assembled_report(reportdict): from _pytest._code.code import ( ReprEntry, ReprEntryNative, ReprExceptionInfo, ReprFileLocation, ReprFuncArgs, ReprLocals, ReprTraceback, ) if reportdict["longrepr"]: if ("reprcrash" in reportdict["longrepr"] and "reprtraceback" in reportdict["longrepr"]): reprtraceback = reportdict["longrepr"]["reprtraceback"] reprcrash = reportdict["longrepr"]["reprcrash"] unserialized_entries = [] reprentry = None for entry_data in reprtraceback["reprentries"]: data = entry_data["data"] entry_type = entry_data["type"] if entry_type == "ReprEntry": reprfuncargs = None reprfileloc = None reprlocals = None if data["reprfuncargs"]: reprfuncargs = ReprFuncArgs(**data["reprfuncargs"]) if data["reprfileloc"]: reprfileloc = ReprFileLocation( **data["reprfileloc"]) if data["reprlocals"]: reprlocals = ReprLocals( data["reprlocals"]["lines"]) reprentry = ReprEntry( lines=data["lines"], reprfuncargs=reprfuncargs, reprlocals=reprlocals, filelocrepr=reprfileloc, style=data["style"], ) elif entry_type == "ReprEntryNative": reprentry = ReprEntryNative(data["lines"]) else: report_unserialization_failure(entry_type, name, reportdict) unserialized_entries.append(reprentry) reprtraceback["reprentries"] = unserialized_entries exception_info = ReprExceptionInfo( reprtraceback=ReprTraceback(**reprtraceback), reprcrash=ReprFileLocation(**reprcrash), ) for section in reportdict["longrepr"]["sections"]: exception_info.addsection(*section) reportdict["longrepr"] = exception_info return reportdict
def _from_json(cls, reportdict): """ This was originally the serialize_report() function from xdist (ca03269). Factory method that returns either a TestReport or CollectReport, depending on the calling class. It's the callers responsibility to know which class to pass here. Experimental method. """ if reportdict["longrepr"]: if ("reprcrash" in reportdict["longrepr"] and "reprtraceback" in reportdict["longrepr"]): reprtraceback = reportdict["longrepr"]["reprtraceback"] reprcrash = reportdict["longrepr"]["reprcrash"] unserialized_entries = [] reprentry = None for entry_data in reprtraceback["reprentries"]: data = entry_data["data"] entry_type = entry_data["type"] if entry_type == "ReprEntry": reprfuncargs = None reprfileloc = None reprlocals = None if data["reprfuncargs"]: reprfuncargs = ReprFuncArgs(**data["reprfuncargs"]) if data["reprfileloc"]: reprfileloc = ReprFileLocation( **data["reprfileloc"]) if data["reprlocals"]: reprlocals = ReprLocals( data["reprlocals"]["lines"]) reprentry = ReprEntry( lines=data["lines"], reprfuncargs=reprfuncargs, reprlocals=reprlocals, filelocrepr=reprfileloc, style=data["style"], ) elif entry_type == "ReprEntryNative": reprentry = ReprEntryNative(data["lines"]) else: _report_unserialization_failure( entry_type, cls, reportdict) unserialized_entries.append(reprentry) reprtraceback["reprentries"] = unserialized_entries exception_info = ReprExceptionInfo( reprtraceback=ReprTraceback(**reprtraceback), reprcrash=ReprFileLocation(**reprcrash), ) for section in reportdict["longrepr"]["sections"]: exception_info.addsection(*section) reportdict["longrepr"] = exception_info return cls(**reportdict)
def assembled_report(reportdict): from _pytest._code.code import ( ReprEntry, ReprEntryNative, ReprExceptionInfo, ReprFileLocation, ReprFuncArgs, ReprLocals, ReprTraceback ) if reportdict['longrepr']: if 'reprcrash' in reportdict['longrepr'] and 'reprtraceback' in reportdict['longrepr']: reprtraceback = reportdict['longrepr']['reprtraceback'] reprcrash = reportdict['longrepr']['reprcrash'] unserialized_entries = [] reprentry = None for entry_data in reprtraceback['reprentries']: data = entry_data['data'] entry_type = entry_data['type'] if entry_type == 'ReprEntry': reprfuncargs = None reprfileloc = None reprlocals = None if data['reprfuncargs']: reprfuncargs = ReprFuncArgs( **data['reprfuncargs']) if data['reprfileloc']: reprfileloc = ReprFileLocation( **data['reprfileloc']) if data['reprlocals']: reprlocals = ReprLocals( data['reprlocals']['lines']) reprentry = ReprEntry( lines=data['lines'], reprfuncargs=reprfuncargs, reprlocals=reprlocals, filelocrepr=reprfileloc, style=data['style'] ) elif entry_type == 'ReprEntryNative': reprentry = ReprEntryNative(data['lines']) else: report_unserialization_failure( entry_type, name, reportdict) unserialized_entries.append(reprentry) reprtraceback['reprentries'] = unserialized_entries exception_info = ReprExceptionInfo( reprtraceback=ReprTraceback(**reprtraceback), reprcrash=ReprFileLocation(**reprcrash), ) for section in reportdict['longrepr']['sections']: exception_info.addsection(*section) reportdict['longrepr'] = exception_info return reportdict
def gather_report(self): """ """ assert (self.post_done == True) # ----------------------------------------------------------------- for nodeid, report_list in self.mpi_reports.items(): # print("nodeid::", nodeid) assert (len(report_list) > 0) # > Initialize with the first reporter i_rank_report_init, report_init = report_list[0] greport = TestReport( nodeid, report_init.location, report_init.keywords, report_init.outcome, report_init.longrepr, # longrepr report_init.when) # print("report_init.location::", report_init.location) # print("report_init.longrepr::", type(report_init.longrepr), report_init.longrepr) collect_longrepr = [] # > We need to rebuild a TestReport object, location can be false # > Report appears in rank increasing order if greport.outcome != 'skipped': # Skipped test are only know by proc 0 -> no merge required for i_rank_report, test_report in report_list: if (test_report.outcome == 'failed'): greport.outcome = test_report.outcome if (test_report.longrepr): fake_trace_back = ReprTraceback([ ReprEntryNative( f"\n\n----------------------- On rank [{test_report._i_rank}/{test_report._n_rank}] / Global [{i_rank_report}/{self.comm.Get_size()}] ----------------------- \n\n" ) ], None, None) collect_longrepr.append( (fake_trace_back, ReprFileLocation(*report_init.location), None)) collect_longrepr.append( (test_report.longrepr, ReprFileLocation(*report_init.location), None)) if (len(collect_longrepr) > 0): greport.longrepr = ExceptionChainRepr(collect_longrepr) self.reports_gather[nodeid] = [greport]
def deserialize_repr_entry(entry_data): data = entry_data["data"] entry_type = entry_data["type"] if entry_type == "ReprEntry": reprfuncargs = None reprfileloc = None reprlocals = None if data["reprfuncargs"]: reprfuncargs = ReprFuncArgs(**data["reprfuncargs"]) if data["reprfileloc"]: reprfileloc = ReprFileLocation(**data["reprfileloc"]) if data["reprlocals"]: reprlocals = ReprLocals(data["reprlocals"]["lines"]) reprentry: Union[ReprEntry, ReprEntryNative] = ReprEntry( lines=data["lines"], reprfuncargs=reprfuncargs, reprlocals=reprlocals, reprfileloc=reprfileloc, style=data["style"], ) elif entry_type == "ReprEntryNative": reprentry = ReprEntryNative(data["lines"]) else: _report_unserialization_failure(entry_type, TestReport, reportdict) return reprentry
def repr_failure(self, excinfo): import doctest failures = ( None ) # type: Optional[List[Union[doctest.DocTestFailure, doctest.UnexpectedException]]] if excinfo.errisinstance( (doctest.DocTestFailure, doctest.UnexpectedException)): failures = [excinfo.value] elif excinfo.errisinstance(MultipleDoctestFailures): failures = excinfo.value.failures if failures is not None: reprlocation_lines = [] for failure in failures: example = failure.example test = failure.test filename = test.filename if test.lineno is None: lineno = None else: lineno = test.lineno + example.lineno + 1 message = type(failure).__name__ reprlocation = ReprFileLocation(filename, lineno, message) checker = _get_checker() report_choice = _get_report_choice( self.config.getoption("doctestreport")) if lineno is not None: assert failure.test.docstring is not None lines = failure.test.docstring.splitlines(False) # add line numbers to the left of the error message assert test.lineno is not None lines = [ "%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines) ] # trim docstring error lines to 10 lines = lines[max(example.lineno - 9, 0):example.lineno + 1] else: lines = [ "EXAMPLE LOCATION UNKNOWN, not showing all tests of that example" ] indent = ">>>" for line in example.source.splitlines(): lines.append("??? {} {}".format(indent, line)) indent = "..." if isinstance(failure, doctest.DocTestFailure): lines += checker.output_difference( example, failure.got, report_choice).split("\n") else: inner_excinfo = ExceptionInfo(failure.exc_info) lines += [ "UNEXPECTED EXCEPTION: %s" % repr(inner_excinfo.value) ] lines += traceback.format_exception(*failure.exc_info) reprlocation_lines.append((reprlocation, lines)) return ReprFailDoctest(reprlocation_lines) else: return super().repr_failure(excinfo)
def repr_failure( self, excinfo: ExceptionInfo[BaseException], style: Optional["_TracebackStyle"] = None ) -> Union[str, TerminalRepr]: 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 = "" # type: ignore repr_file_location = ReprFileLocation( path=self.fspath, lineno=self.starting_lineno + excinfo.value.lineno, message="" # type: ignore ) repr_tb_entry = TraceLastReprEntry( exception_repr.reprtraceback.reprentries[-1].lines[1:], None, None, repr_file_location, "short") exception_repr.reprtraceback.reprentries = [repr_tb_entry] return exception_repr else: return super().repr_failure(excinfo, style="native")
def repr_failure(self, excinfo, style=None): if not excinfo.errisinstance(MypyAssertionError): return super().repr_failure(excinfo, style=style) # pragma: no cover reprfileloc_key = ("filelocrepr" if PYTEST_VERSION_INFO < (5, 4) else "reprfileloc") exception_repr = excinfo.getrepr(style="short") exception_repr.reprcrash.message = "" exception_repr.reprtraceback.reprentries = [ ReprEntry( lines=mismatch.lines, style="short", reprlocals=None, reprfuncargs=None, **{ reprfileloc_key: ReprFileLocation( path=self.parent.fspath, lineno=mismatch.lineno, message=mismatch.error_message, ) }, ) for mismatch in excinfo.value.errors ] return exception_repr
def assembled_report(reportdict): from _pytest._code.code import (ReprEntry, ReprExceptionInfo, ReprFileLocation, ReprFuncArgs, ReprLocals, ReprTraceback) if reportdict['longrepr']: if 'reprcrash' and 'reprtraceback' in reportdict['longrepr']: reprtraceback = reportdict['longrepr']['reprtraceback'] reprcrash = reportdict['longrepr']['reprcrash'] unserialized_entries = [] for entry in reprtraceback['reprentries']: reprfuncargs, reprfileloc, reprlocals = None, None, None if entry['reprfuncargs']: reprfuncargs = ReprFuncArgs(**entry['reprfuncargs']) if entry['reprfileloc']: reprfileloc = ReprFileLocation(**entry['reprfileloc']) if entry['reprlocals']: reprlocals = ReprLocals(entry['reprlocals']['lines']) reprentry = ReprEntry(lines=entry['lines'], reprfuncargs=reprfuncargs, reprlocals=reprlocals, filelocrepr=reprfileloc, style=entry['style']) unserialized_entries.append(reprentry) reprtraceback['reprentries'] = unserialized_entries exception_info = ReprExceptionInfo( reprtraceback=ReprTraceback(**reprtraceback), reprcrash=ReprFileLocation(**reprcrash), ) for section in reportdict['longrepr']['sections']: exception_info.addsection(*section) reportdict['longrepr'] = exception_info return reportdict
def repr_failure(self, excinfo): import doctest if excinfo.errisinstance( (doctest.DocTestFailure, doctest.UnexpectedException)): doctestfailure = excinfo.value example = doctestfailure.example test = doctestfailure.test filename = test.filename if test.lineno is None: lineno = None else: lineno = test.lineno + example.lineno + 1 message = excinfo.type.__name__ reprlocation = ReprFileLocation(filename, lineno, message) checker = _get_checker() report_choice = _get_report_choice( self.config.getoption("doctestreport")) if lineno is not None: lines = doctestfailure.test.docstring.splitlines(False) # add line numbers to the left of the error message lines = [ "%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines) ] # trim docstring error lines to 10 lines = lines[example.lineno - 9:example.lineno + 1] else: lines = [ 'EXAMPLE LOCATION UNKNOWN, not showing all tests of that example' ] indent = '>>>' for line in example.source.splitlines(): lines.append('??? %s %s' % (indent, line)) indent = '...' if excinfo.errisinstance(doctest.DocTestFailure): lines += checker.output_difference(example, doctestfailure.got, report_choice).split("\n") else: inner_excinfo = ExceptionInfo(excinfo.value.exc_info) lines += [ "UNEXPECTED EXCEPTION: %s" % repr(inner_excinfo.value) ] lines += traceback.format_exception(*excinfo.value.exc_info) return ReprFailDoctest(reprlocation, lines) else: return super(DoctestItem, self).repr_failure(excinfo)
def __init__(self, failures): max_length = max( len(line) for _, error_description in failures for line in error_description.splitlines()) thick_sep_line = '=' * max_length thin_sep_line = '-' * max_length self._fulldescr = '\n' + '\n\n'.join([ '\n'.join([ thick_sep_line, f'FAIL: {test_name}', thin_sep_line, error_description ]) for test_name, error_description in failures ]) self.reprcrash = ReprFileLocation(path='', lineno=0, message='\n'.join([ f'{test_name} failed' for test_name, _ in failures ]))
def value(self, name, what): from _pytest._code.code import (ReprEntry, ReprEntryNative, ReprExceptionInfo, ReprFileLocation, ReprFuncArgs, ReprLocals, ReprTraceback) if not isinstance(what, str): unserialized_entries = [] reprentry = None for entry_data in what.reprtraceback.reprentries: data = entry_data['data'] entry_type = entry_data['type'] if entry_type == 'ReprEntry': reprfuncargs = None reprfileloc = None reprlocals = None if data['reprfuncargs']: reprfuncargs = ReprFuncArgs(**data['reprfuncargs']) if data['reprfileloc']: reprfileloc = ReprFileLocation(**data['reprfileloc']) if data['reprlocals']: reprlocals = ReprLocals(data['reprlocals']['lines']) reprentry = ReprEntry(lines=data['lines'], reprfuncargs=reprfuncargs, reprlocals=reprlocals, filelocrepr=reprfileloc, style=data['style']) elif entry_type == 'ReprEntryNative': reprentry = ReprEntryNative(data['lines']) else: report_unserialization_failure(entry_type, name, reportdict) unserialized_entries.append(reprentry) what.reprtraceback.reprentries = unserialized_entries return element_maker(self.name or name, self.namespace)(legalize_xml(unicodify(what)))
def repr_failure( # type: ignore[override] self, excinfo: ExceptionInfo[BaseException], ) -> Union[str, TerminalRepr]: import doctest failures: Optional[Sequence[Union[doctest.DocTestFailure, doctest.UnexpectedException]]] = None if isinstance(excinfo.value, (doctest.DocTestFailure, doctest.UnexpectedException)): failures = [excinfo.value] elif isinstance(excinfo.value, MultipleDoctestFailures): failures = excinfo.value.failures if failures is None: return super().repr_failure(excinfo) reprlocation_lines = [] for failure in failures: example = failure.example test = failure.test filename = test.filename if test.lineno is None: lineno = None else: lineno = test.lineno + example.lineno + 1 message = type(failure).__name__ # TODO: ReprFileLocation doesn't expect a None lineno. reprlocation = ReprFileLocation(filename, lineno, message) # type: ignore[arg-type] checker = _get_checker() report_choice = _get_report_choice( self.config.getoption("doctestreport")) if lineno is not None: assert failure.test.docstring is not None lines = failure.test.docstring.splitlines(False) # add line numbers to the left of the error message assert test.lineno is not None lines = [ "%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines) ] # trim docstring error lines to 10 lines = lines[max(example.lineno - 9, 0):example.lineno + 1] else: lines = [ "EXAMPLE LOCATION UNKNOWN, not showing all tests of that example" ] indent = ">>>" for line in example.source.splitlines(): lines.append(f"??? {indent} {line}") indent = "..." if isinstance(failure, doctest.DocTestFailure): lines += checker.output_difference(example, failure.got, report_choice).split("\n") else: inner_excinfo = ExceptionInfo.from_exc_info(failure.exc_info) lines += [ "UNEXPECTED EXCEPTION: %s" % repr(inner_excinfo.value) ] lines += [ x.strip("\n") for x in traceback.format_exception(*failure.exc_info) ] reprlocation_lines.append((reprlocation, lines)) return ReprFailDoctest(reprlocation_lines)
def deserialize_repr_crash(repr_crash_dict: Optional[Dict[str, Any]]): if repr_crash_dict is not None: return ReprFileLocation(**repr_crash_dict) else: return None
def deserialize_repr_crash(repr_crash_dict): return ReprFileLocation(**repr_crash_dict)