diff --git a/src/flake8/formatting/base.py b/src/flake8/formatting/base.py index 4fda6f4..7c2e4b5 100644 --- a/src/flake8/formatting/base.py +++ b/src/flake8/formatting/base.py @@ -123,8 +123,9 @@ class BaseFormatter(object): :rtype: str """ - if not self.options.show_source: - return None + if not self.options.show_source or error.physical_line is None: + return '' + pointer = (' ' * error.column_number) + '^' # Physical lines have a newline at the end, no need to add an extra # one diff --git a/src/flake8/processor.py b/src/flake8/processor.py index 1824ed1..76c5512 100644 --- a/src/flake8/processor.py +++ b/src/flake8/processor.py @@ -250,7 +250,13 @@ class FileProcessor(object): def line_for(self, line_number): """Retrieve the physical line at the specified line number.""" - return self.lines[line_number - 1] + adjusted_line_number = line_number - 1 + # NOTE(sigmavirus24): Some plugins choose to report errors for empty + # files on Line 1. In those casese, we shouldn't bother trying to + # retrieve a physical line (since none exist). + if 0 <= adjusted_line_number < len(self.lines): + return self.lines[adjusted_line_number] + return None def next_line(self): """Get the next line from the list.""" diff --git a/tests/unit/test_base_formatter.py b/tests/unit/test_base_formatter.py index dc4a95c..f148806 100644 --- a/tests/unit/test_base_formatter.py +++ b/tests/unit/test_base_formatter.py @@ -51,7 +51,15 @@ def test_show_source_returns_nothing_when_not_showing_source(): formatter = base.BaseFormatter(options(show_source=False)) assert formatter.show_source( style_guide.Error('A000', 'file.py', 1, 1, 'error text', 'line') - ) is None + ) is '' + + +def test_show_source_returns_nothing_when_there_is_source(): + """Ensure we return nothing when there is no line.""" + formatter = base.BaseFormatter(options(show_source=True)) + assert formatter.show_source( + style_guide.Error('A000', 'file.py', 1, 1, 'error text', None) + ) is '' @pytest.mark.parametrize('line, column', [