From e8c79dcd33972cbb798b94493216146f38e4d68e Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 10 Aug 2019 11:35:14 -0700 Subject: [PATCH] Fix --show-source when indented with tabs --- src/flake8/formatting/base.py | 7 +++++-- tests/unit/test_base_formatter.py | 28 +++++++++++++++++++--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/flake8/formatting/base.py b/src/flake8/formatting/base.py index 388ab0e..520dcbc 100644 --- a/src/flake8/formatting/base.py +++ b/src/flake8/formatting/base.py @@ -171,10 +171,13 @@ class BaseFormatter(object): # Because column numbers are 1-indexed, we need to remove one to get # the proper number of space characters. - pointer = (" " * (error.column_number - 1)) + "^" + indent = "".join( + c if c.isspace() else " " + for c in error.physical_line[: error.column_number - 1] + ) # Physical lines have a newline at the end, no need to add an extra # one - return error.physical_line + pointer + return "{}{}^".format(error.physical_line, indent) def _write(self, output): # type: (str) -> None """Handle logic of whether to use an output file or print().""" diff --git a/tests/unit/test_base_formatter.py b/tests/unit/test_base_formatter.py index ec051a8..ee589aa 100644 --- a/tests/unit/test_base_formatter.py +++ b/tests/unit/test_base_formatter.py @@ -65,19 +65,29 @@ def test_show_source_returns_nothing_when_there_is_source(): ) == '' -@pytest.mark.parametrize('line, column', [ - ('x=1\n', 2), - (' x=(1\n +2)\n', 5), - # TODO(sigmavirus24): Add more examples +@pytest.mark.parametrize(('line1', 'line2', 'column'), [ + ( + 'x=1\n', + ' ^', + 2, + ), + ( + ' x=(1\n +2)\n', + ' ^', + 5, + ), + ( + '\tx\t=\ty\n', + '\t \t \t^', + 6, + ), ]) -def test_show_source_updates_physical_line_appropriately(line, column): +def test_show_source_updates_physical_line_appropriately(line1, line2, column): """Ensure the error column is appropriately indicated.""" formatter = base.BaseFormatter(options(show_source=True)) - error = style_guide.Violation('A000', 'file.py', 1, column, 'error', line) + error = style_guide.Violation('A000', 'file.py', 1, column, 'error', line1) output = formatter.show_source(error) - assert output - _, pointer = output.rsplit('\n', 1) - assert pointer.count(' ') == (column - 1) + assert output == line1 + line2 @pytest.mark.parametrize('tee', [False, True])