diff --git a/bears/general/SpaceConsistencyBear.py b/bears/general/SpaceConsistencyBear.py index 6853c7dfff..7148a68896 100644 --- a/bears/general/SpaceConsistencyBear.py +++ b/bears/general/SpaceConsistencyBear.py @@ -18,6 +18,7 @@ def run(self, file, use_spaces: bool, allow_trailing_whitespace: bool = False, + allow_leading_blanklines: bool = False, indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH, enforce_newline_at_EOF: bool = True, ): @@ -34,13 +35,56 @@ def run(self, Number of spaces per indentation level. :param enforce_newline_at_EOF: Whether to enforce a newline at the End Of File. + :param allow_leading_blanklines: + Whether to allow leading blank lines at the start + of file or not. ''' spacing_helper = SpacingHelper(indent_size) result_texts = [] additional_info_texts = [] - for line_number, line in enumerate(file, start=1): - replacement = line + def end_blanklines(): + end_line = False + enumerated_zip_obj = zip(range(1, len(file) + 1), + file) + enumerated_tuple = tuple(enumerated_zip_obj) + + for line_number, line in enumerated_tuple: + if replacement.strip() == '': + end_line = line_number + else: + break + return end_line + + if allow_leading_blanklines: + start_line_of _file = 1 + else: + end_blanklines = end_blanklines() + start_line_of_file = 1 + if end_blanklines: + start_line_of_file = end_blanklines + 1 + result_texts.append('Leading blank lines.') + additional_info_texts.append( + 'Your source code contains leading blank lines.' + 'Those usually have no meaning. Please consider ' + 'removing them.') + diff = Diff(file) + diff.delete_lines(1, end_blanklines) + 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, + additional_info='\n\n'.join(additional_info_texts)) + result_texts = [] + additional_info_texts = [] + + for line_number, line in enumerate(file[start_line_of_file - 1:], + start=start_line_of_file): + replacement = line if enforce_newline_at_EOF: # Since every line contains at the end at least one \n, only diff --git a/tests/general/SpaceConsistencyBearTest.py b/tests/general/SpaceConsistencyBearTest.py index c2019b3957..4e3d420285 100644 --- a/tests/general/SpaceConsistencyBearTest.py +++ b/tests/general/SpaceConsistencyBearTest.py @@ -44,21 +44,28 @@ def test_data_sets_tabs(self): self.section.append(Setting('use_spaces', 'false')) self.section.append(Setting('allow_trailing_whitespace', 'true')) self.section.append(Setting('enforce_newline_at_EOF', 'false')) + self.section.append(Setting('allow_leading_blanklines', 'false')) self.check_invalidity(self.uut, [' t']) self.check_validity(self.uut, ['t \n']) self.check_validity(self.uut, ['\tt\n']) + self.check_validity(self.uut, []) def test_enforce_newline_at_eof(self): self.section.append(Setting('use_spaces', 'true')) self.section.append(Setting('allow_trailing_whitespace', 'true')) self.section.append(Setting('enforce_newline_at_EOF', 'true')) + self.section.append(Setting('allow_leading_blanklines', 'true')) self.check_validity(self.uut, ['hello world \n'], force_linebreaks=False) self.check_validity(self.uut, ['def somecode():\n', + [' \n', + '\n', + ' \n', + 'def somecode():\n', " print('funny')\n", " print('funny end.')\n"], force_linebreaks=False) @@ -70,3 +77,20 @@ def test_enforce_newline_at_eof(self): " print('funny')\n", " print('the result is not funny...')"], force_linebreaks=False) + + def test_leading_blanklines(self): + self.section.append(Setting('use_spaces', 'true')) + self.section.append(Setting('allow_trailing_whitespace', 'false')) + self.section.append(Setting('enforce_newline_at_EOF', 'true')) + self.section.append(Setting('allow_leading_blanklines', 'false')) + + self.check_invalidity(self.uut, + ['\n', + ' \n', + 'def code():\n', + " print('Am I coding?')\n"], + force_linebreaks=False) + self.check_validity(self.uut, + ['def code():\n', + " print('Am I coding?')\n"], + force_linebreaks=False)