def _printError(self, kind, err, test, isFailure=True): """Output a human-readable error report to the stream. kind -- the (string) type of incident the precipitated this call err -- exc_info()-style traceback triple test -- the test that precipitated this call """ if isFailure or self._showAdvisories: # Don't bind third item to a local var; that can create circular # refs which are expensive to collect. See the sys.exc_info() docs. exception_type, exception_value = err[:2] extracted_tb = extract_tb(err[2]) formatted_traceback = ''.join(format_list(extracted_tb)) # TODO: Canonicalize the path to remove /kitsune/../kitsune # nonsense. Don't relativize, though, as that hurts the ability to # paste into running editors. writeln = self.stream.writeln write = self.stream.write with self.bar.dodging(): writeln('\n' + (self._codes['bold'] if isFailure else '') + '%s: %s' % (kind, nose_selector(test))) if isFailure: # Then show traceback # File name and line num in a format vi can take: try: address = test_address(test) except TypeError: # Explodes if the function passed to @with_setup # applied to a test generator has an error. address = None if address: # None if no such callable found. No sense # trying to find the test frame if there's no # such thing. file, line = frame_of_test(address, exception_type, exception_value, extracted_tb)[:2] writeln(' ' * len(kind) + ' %s +%s %s' % (os.environ.get('EDITOR', 'vi'), line, human_path(src(file), self._cwd))) write(self._codes['sgr0']) # end bold # Traceback: # TODO: Think about using self._exc_info_to_string, which # does some pretty whizzy skipping of unittest frames. write(formatted_traceback) # Exception: write(''.join(format_exception_only(exception_type, exception_value))) else: write(self._codes['sgr0']) # end bold
def format_traceback(extracted_tb, exc_type, exc_value, cwd='', term=None, function_color=12, dim_color=8, editor='vi'): """Return an iterable of formatted Unicode traceback frames. Also include a pseudo-frame at the end representing the exception itself. Format things more compactly than the stock formatter, and make every frame an editor shortcut. """ def format_shortcut(editor, file, line, function=None): """Return a pretty-printed editor shortcut.""" return template % dict(editor=editor, line=line, file=file, function=(u' # ' + function) if function else u'', funcemph=term.color(function_color), # Underline is also nice and doesn't make us # worry about appearance on different background # colors. plain=term.normal, fade=term.color(dim_color) + term.bold) extracted_tb = _unicode_decode_extracted_tb(extracted_tb) if not term: term = Terminal() if extracted_tb: # Shorten file paths: for i, (file, line, function, text) in enumerate(extracted_tb): extracted_tb[i] = human_path(src(file), cwd), line, function, text line_width = len(unicode(max(the_line for _, the_line, _, _ in extracted_tb))) template = (u' %(fade)s%(editor)s +%(line)-' + unicode(line_width) + u's ' '%(file)s%(plain)s' '%(funcemph)s%(function)s%(plain)s\n') # Stack frames: for i, (file, line, function, text) in enumerate(extracted_tb): text = (text and text.strip()) or u'' yield (format_shortcut(editor, file, line, function) + (u' %s\n' % text)) # Exception: if exc_type is SyntaxError: # Format a SyntaxError to look like our other traceback lines. # SyntaxErrors have a format different from other errors and include a # file path which looks out of place in our newly highlit, editor- # shortcutted world. exc_lines = [format_shortcut(editor, exc_value.filename, exc_value.lineno)] formatted_exception = format_exception_only(SyntaxError, exc_value)[1:] else: exc_lines = [] formatted_exception = format_exception_only(exc_type, exc_value) exc_lines.extend([_decode(f) for f in formatted_exception]) yield u''.join(exc_lines)
def test_human_path(self): chdir(dirname(__file__)) eq_(human_path(__file__, getcwd()), basename(__file__))
def format_traceback(extracted_tb, exc_type, exc_value, cwd='', term=None, function_color=12, dim_color=8, editor='vi', template=DEFAULT_EDITOR_SHORTCUT_TEMPLATE): """Return an iterable of formatted Unicode traceback frames. Also include a pseudo-frame at the end representing the exception itself. Format things more compactly than the stock formatter, and make every frame an editor shortcut. """ def format_shortcut(editor, path, line_number, function=None): """Return a pretty-printed editor shortcut.""" return template.format(editor=editor, line_number=line_number or 0, path=path, function=function or u'', hash_if_function=u' # ' if function else u'', function_format=term.color(function_color), # Underline is also nice and doesn't make us # worry about appearance on different background # colors. normal=term.normal, dim_format=term.color(dim_color) + term.bold, line_number_max_width=line_number_max_width, term=term) template += '\n' # Newlines are awkward to express on the command line. extracted_tb = _unicode_decode_extracted_tb(extracted_tb) if not term: term = Terminal() if extracted_tb: # Shorten file paths: for i, (file, line_number, function, text) in enumerate(extracted_tb): extracted_tb[i] = human_path(src(file), cwd), line_number, function, text line_number_max_width = len(unicode(max(the_line for _, the_line, _, _ in extracted_tb))) # Stack frames: for i, (path, line_number, function, text) in enumerate(extracted_tb): text = (text and text.strip()) or u'' yield (format_shortcut(editor, path, line_number, function) + (u' %s\n' % text)) # Exception: if exc_type is SyntaxError: # Format a SyntaxError to look like our other traceback lines. # SyntaxErrors have a format different from other errors and include a # file path which looks out of place in our newly highlit, editor- # shortcutted world. if hasattr(exc_value, 'filename') and hasattr(exc_value, 'lineno'): exc_lines = [format_shortcut(editor, exc_value.filename, exc_value.lineno)] formatted_exception = format_exception_only(SyntaxError, exc_value)[1:] else: # The logcapture plugin may format exceptions as strings, # stripping them of the full filename and lineno exc_lines = [] formatted_exception = format_exception_only(SyntaxError, exc_value) formatted_exception.append(u'(Try --nologcapture for a more detailed traceback)\n') else: exc_lines = [] formatted_exception = format_exception_only(exc_type, exc_value) exc_lines.extend([_decode(f) for f in formatted_exception]) yield u''.join(exc_lines)
def test_human_path(): chdir(dirname(__file__)) eq_(human_path(__file__, getcwd()), basename(__file__))
def format_traceback(extracted_tb, exc_type, exc_value, cwd='', term=None, function_color=12, dim_color=8, editor='vi', template=DEFAULT_EDITOR_SHORTCUT_TEMPLATE): """Return an iterable of formatted Unicode traceback frames. Also include a pseudo-frame at the end representing the exception itself. Format things more compactly than the stock formatter, and make every frame an editor shortcut. """ def format_shortcut(editor, path, line_number, function=None): """Return a pretty-printed editor shortcut.""" return template.format( editor=editor, line_number=line_number or 0, path=path, function=function or u'', hash_if_function=u' # ' if function else u'', function_format=term.color(function_color), # Underline is also nice and doesn't make us # worry about appearance on different background # colors. normal=term.normal, dim_format=term.color(dim_color) + term.bold, line_number_max_width=line_number_max_width, term=term) template += '\n' # Newlines are awkward to express on the command line. extracted_tb = _unicode_decode_extracted_tb(extracted_tb) if not term: term = Terminal() if extracted_tb: # Shorten file paths: for i, (file, line_number, function, text) in enumerate(extracted_tb): extracted_tb[i] = human_path(src(file), cwd), line_number, function, text line_number_max_width = len( unicode(max(the_line for _, the_line, _, _ in extracted_tb))) # Stack frames: for i, (path, line_number, function, text) in enumerate(extracted_tb): text = (text and text.strip()) or u'' yield (format_shortcut(editor, path, line_number, function) + (u' %s\n' % text)) # Exception: if exc_type is SyntaxError: # Format a SyntaxError to look like our other traceback lines. # SyntaxErrors have a format different from other errors and include a # file path which looks out of place in our newly highlit, editor- # shortcutted world. if hasattr(exc_value, 'filename') and hasattr(exc_value, 'lineno'): exc_lines = [ format_shortcut(editor, exc_value.filename, exc_value.lineno) ] formatted_exception = format_exception_only( SyntaxError, exc_value)[1:] else: # The logcapture plugin may format exceptions as strings, # stripping them of the full filename and lineno exc_lines = [] formatted_exception = format_exception_only(SyntaxError, exc_value) formatted_exception.append( u'(Try --nologcapture for a more detailed traceback)\n') else: exc_lines = [] formatted_exception = format_exception_only(exc_type, exc_value) exc_lines.extend([_decode(f) for f in formatted_exception]) yield u''.join(exc_lines)