def context(self) -> Optional[str]: """ A formatted string containing the line of code with the syntax error (or a non-empty line above it) along with a caret indicating the exact column where the error occurred. Return ``None`` if there's no relevant non-empty line to show. (e.g. the file consists of only blank lines) """ displayed_line = self.editor_line displayed_column = self.editor_column # we want to avoid displaying a blank line for context. If we're on a blank line # find the nearest line above us that isn't blank. while displayed_line >= 1 and not len( self._lines[displayed_line - 1].strip()): displayed_line -= 1 displayed_column = len(self._lines[displayed_line - 1]) # only show context if we managed to find a non-empty line if len(self._lines[displayed_line - 1].strip()): formatted_source_line = expand_tabs( self._lines[displayed_line - 1]).rstrip(_NEWLINE_CHARS) # fmt: off return (f"{formatted_source_line}\n" + f"{' ' * (displayed_column - 1)}^") # fmt: on else: return None
def editor_column(self) -> int: """ The one-indexed column in the user's editor, assuming tabs expand to 1-8 spaces. """ pos_line, pos_column = self.pos tab_adjusted_column = len( expand_tabs(self.lines[pos_line - 1][:pos_column])) # Text editors use a one-indexed column, so we need to add one to our # zero-indexed column to get a human-readable result. return tab_adjusted_column + 1
def editor_column(self) -> int: """ The expected one-indexed column that's likely to match the behavior of the user's editor, assuming tabs expand to 1-8 spaces. This is the column number shown when the syntax error is printed out with `str`. This assumes single-width characters. However, because python doesn't ship with a wcwidth function, it's hard to handle this properly without a third-party dependency. For a raw zero-indexed character offset without tab expansion, see :attr:`raw_column`. """ prefix_str = self._lines[self.raw_line - 1][:self.raw_column] tab_adjusted_column = len(expand_tabs(prefix_str)) # Text editors use a one-indexed column, so we need to add one to our # zero-indexed column to get a human-readable result. return tab_adjusted_column + 1
def test_expand_tabs(self, input, output) -> None: self.assertEqual(expand_tabs(input), output)