def test_print_spaces_tabs_in_unicode(self): printer = StringPrinter() sh = SpacingHelper(4) test_string = "\the\tllo world " print_spaces_tabs_in_unicode(printer, test_string, dict(sh.yield_tab_lengths(test_string)), "red") self.assertEqual(printer.string, "--->he->llo•world•••") # Test the case when the bullet can't be printed because of encoding # problems. def hijack_print(text, *args, **kwargs): if "•" in text: raise UnicodeEncodeError("test-codec", "", 0, 1, "") else: return StringPrinter.print(printer, text, *args, **kwargs) printer.print = hijack_print printer.clear() test_string = " he\tllo world " print_spaces_tabs_in_unicode(printer, test_string, dict(sh.yield_tab_lengths(test_string)), "red") self.assertEqual(printer.string, ".he>llo..world.")
def run(self, filename, file, max_line_length: int=80, tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH): ''' Yields results for all lines longer than the given maximum line length. :param max_line_length: Maximum number of characters for a line. :param tab_width: Number of spaces to show for one tab. ''' spacing_helper = SpacingHelper(tab_width) for line_number, line in enumerate(file): line = spacing_helper.replace_tabs_with_spaces(line) if len(line) > max_line_length + 1: yield Result.from_values( origin=self, message="Line is longer than allowed." + " ({actual} > {maximum})".format( actual=len(line)-1, maximum=max_line_length), file=filename, line=line_number + 1, column=max_line_length + 1, end_line=line_number + 1, end_column=len(line))
def run(self, filename, file, max_line_length: int = 79, indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH, ignore_length_regex: typed_list(str) = ()): ''' Yields results for all lines longer than the given maximum line length. :param max_line_length: Maximum number of characters for a line, the newline character being excluded. :param indent_size: Number of spaces per indentation level. :param ignore_length_regex: Lines matching each of the regular expressions in this list will be ignored. ''' spacing_helper = SpacingHelper(indent_size) ignore_regexes = [re.compile(regex) for regex in ignore_length_regex] for line_number, line in enumerate(file): line = spacing_helper.replace_tabs_with_spaces(line) if len(line) > max_line_length + 1: if any(regex.search(line) for regex in ignore_regexes): continue yield Result.from_values( origin=self, message="Line is longer than allowed." + " ({actual} > {maximum})".format(actual=len(line) - 1, maximum=max_line_length), file=filename, line=line_number + 1, column=max_line_length + 1, end_line=line_number + 1, end_column=len(line))
def print_lines(console_printer, file_dict, section, sourcerange): """ Prints the lines between the current and the result line. If needed they will be shortened. :param console_printer: Object to print messages on the console. :param file_dict: A dictionary containing all files as values with filenames as key. :param sourcerange: The SourceRange object referring to the related lines to print. """ for i in range(sourcerange.start.line, sourcerange.end.line + 1): console_printer.print(format_lines(lines='', line_nr=i), color=FILE_LINES_COLOR, end='') line = file_dict[sourcerange.file][i - 1].rstrip("\n") tab_width = int(section.get('tab_width', 4)) s = SpacingHelper(tab_width) tab_dict = dict(s.yield_tab_lengths(line)) printed_chars = 0 if i == sourcerange.start.line and sourcerange.start.column: print_spaces_tabs_in_unicode( console_printer, line[:sourcerange.start.column-1], tab_dict, FILE_LINES_COLOR) printed_chars = sourcerange.start.column-1 if i == sourcerange.end.line and sourcerange.end.column: print_spaces_tabs_in_unicode( console_printer, line[printed_chars:sourcerange.end.column-1], tab_dict, HIGHLIGHTED_CODE_COLOR, printed_chars) print_spaces_tabs_in_unicode( console_printer, line[sourcerange.end.column-1:], tab_dict, FILE_LINES_COLOR, sourcerange.end.column-1) console_printer.print("") else: print_spaces_tabs_in_unicode( console_printer, line[printed_chars:], tab_dict, HIGHLIGHTED_CODE_COLOR, printed_chars) console_printer.print("")
def run(self, filename, file, use_spaces: bool, allow_trailing_whitespace: bool=False, tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH): """ Checks the space consistency for each line. :param use_spaces: True if spaces are to be used instead of tabs. :param allow_trailing_whitespace: Whether to allow trailing whitespace or not. :param tab_width: Number of spaces representing one tab. """ results = [] spacing_helper = SpacingHelper(tab_width) for line_number, line in enumerate(file): replacement = line if not allow_trailing_whitespace: replacement = replacement.rstrip(" \t\n") + "\n" if use_spaces: replacement = spacing_helper.replace_tabs_with_spaces( replacement) else: replacement = spacing_helper.replace_spaces_with_tabs( replacement) if replacement != line: diff = Diff() diff.change_line(line_number + 1, line, replacement) results.append(PatchResult(self, _("Line contains spacing " "inconsistencies."), {filename: diff}, filename, line_nr=line_number+1)) return results
def run(self, filename, file, use_spaces: bool, allow_trailing_whitespace: bool = False, tab_width: int = SpacingHelper.DEFAULT_TAB_WIDTH, enforce_newline_at_EOF: bool = True): ''' Checks the space consistency for each line. :param use_spaces: True if spaces are to be used instead of tabs. :param allow_trailing_whitespace: Whether to allow trailing whitespace or not. :param tab_width: Number of spaces representing one tab. :param enforce_newline_at_EOF: Whether to enforce a newline at the End Of File. ''' spacing_helper = SpacingHelper(tab_width) result_texts = [] for line_number, line in enumerate(file, start=1): replacement = line if enforce_newline_at_EOF: # Since every line contains at the end at least one \n, only # the last line could potentially not have one. So we don't # need to check whether the current line_number is the last # one. if replacement[-1] != "\n": replacement += "\n" result_texts.append("No newline at EOF.") if not allow_trailing_whitespace: pre_replacement = line replacement = replacement.rstrip(" \t\n") + "\n" if replacement != pre_replacement: result_texts.append("Trailing whitespaces.") if use_spaces: pre_replacement = replacement replacement = spacing_helper.replace_tabs_with_spaces( replacement) if replacement != pre_replacement: result_texts.append("Tabs used instead of spaces.") else: pre_replacement = replacement replacement = spacing_helper.replace_spaces_with_tabs( replacement) if replacement != pre_replacement: result_texts.append("Spaces used instead of tabs.") if len(result_texts) > 0: diff = Diff(file) diff.change_line(line_number, line, replacement) inconsistencies = "".join("\n- " + string for string in result_texts) yield Result.from_values( self, "Line contains following spacing inconsistencies:" + inconsistencies, diffs={filename: diff}, file=filename, line=line_number) result_texts = []
def run( self, filename, file, use_spaces: bool, allow_trailing_whitespace: bool = False, indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH, enforce_newline_at_EOF: bool = True, ): ''' Check and correct spacing for all textual data. This includes usage of tabs vs. spaces, trailing whitespace and (missing) newlines before the end of the file. :param use_spaces: True if spaces are to be used instead of tabs. :param allow_trailing_whitespace: Whether to allow trailing whitespace or not. :param indent_size: Number of spaces per indentation level. :param enforce_newline_at_EOF: Whether to enforce a newline at the End Of File. ''' spacing_helper = SpacingHelper(indent_size) result_texts = [] additional_info_texts = [] for line_number, line in enumerate(file, start=1): replacement = line if enforce_newline_at_EOF: # Since every line contains at the end at least one \n, only # the last line could potentially not have one. So we don't # need to check whether the current line_number is the last # one. if replacement[-1] != '\n': replacement += '\n' result_texts.append('No newline at EOF.') additional_info_texts.append( "A trailing newline character ('\\n') is missing from " 'your file. ' '<http://stackoverflow.com/a/5813359/3212182> gives ' 'more information about why you might need one.') if not allow_trailing_whitespace: replacement = replacement.rstrip(' \t\n') + '\n' if replacement != line.rstrip('\n') + '\n': result_texts.append('Trailing whitespaces.') additional_info_texts.append( 'Your source code contains trailing whitespaces. ' 'Those usually have no meaning. Please consider ' 'removing them.') if use_spaces: pre_replacement = replacement replacement = replacement.expandtabs(indent_size) if replacement != pre_replacement: result_texts.append('Tabs used instead of spaces.') else: pre_replacement = replacement replacement = spacing_helper.replace_spaces_with_tabs( replacement) if replacement != pre_replacement: result_texts.append('Spaces used instead of tabs.') if len(result_texts) > 0: diff = Diff(file) diff.change_line(line_number, line, replacement) inconsistencies = ''.join('\n- ' + string for string in result_texts) yield Result.from_values( self, 'Line contains following spacing inconsistencies:' + inconsistencies, diffs={filename: diff}, file=filename, line=line_number, additional_info='\n\n'.join(additional_info_texts)) result_texts = [] additional_info_texts = []
def setUp(self): self.uut = SpacingHelper()
def run(self, filename, file, use_spaces: bool, allow_trailing_whitespace: bool = False, tab_width: int = SpacingHelper.DEFAULT_TAB_WIDTH, enforce_newline_at_EOF: bool = True): ''' Check and correct spacing for all textual data. This includes usage of tabs vs. spaces, trailing whitespace and (missing) newlines before the end of the file. :param use_spaces: True if spaces are to be used instead of tabs. :param allow_trailing_whitespace: Whether to allow trailing whitespace or not. :param tab_width: Number of spaces representing one tab. :param enforce_newline_at_EOF: Whether to enforce a newline at the End Of File. ''' spacing_helper = SpacingHelper(tab_width) result_texts = [] additional_info_texts = [] for line_number, line in enumerate(file, start=1): replacement = line if enforce_newline_at_EOF: # Since every line contains at the end at least one \n, only # the last line could potentially not have one. So we don't # need to check whether the current line_number is the last # one. if replacement[-1] != "\n": replacement += "\n" result_texts.append("No newline at EOF.") additional_info_texts.append( "A trailing newline character ('\\n') is missing from " "your file. " "<http://stackoverflow.com/a/5813359/3212182> gives " "more information about why you might need one.") if not allow_trailing_whitespace: replacement = replacement.rstrip(" \t\n") + "\n" if replacement != line.rstrip("\n") + "\n": result_texts.append("Trailing whitespaces.") additional_info_texts.append( "Your source code contains trailing whitespaces. Those " "usually have no meaning. Please consider removing " "them.") if use_spaces: pre_replacement = replacement replacement = spacing_helper.replace_tabs_with_spaces( replacement) if replacement != pre_replacement: result_texts.append("Tabs used instead of spaces.") else: pre_replacement = replacement replacement = spacing_helper.replace_spaces_with_tabs( replacement) if replacement != pre_replacement: result_texts.append("Spaces used instead of tabs.") if len(result_texts) > 0: diff = Diff(file) diff.change_line(line_number, line, replacement) inconsistencies = "".join("\n- " + string for string in result_texts) yield Result.from_values( self, "Line contains following spacing inconsistencies:" + inconsistencies, diffs={filename: diff}, file=filename, line=line_number, additional_info="\n\n".join(additional_info_texts)) result_texts = [] additional_info_texts = []