mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-14 00:14:46 +00:00
Run checks expecting an AST
This commit is contained in:
parent
576d1f6c85
commit
0b063a1024
4 changed files with 48 additions and 2 deletions
|
|
@ -326,6 +326,37 @@ class FileChecker(object):
|
||||||
self.processor.keyword_arguments_for(plugin.parameters, arguments)
|
self.processor.keyword_arguments_for(plugin.parameters, arguments)
|
||||||
return plugin.execute(**arguments)
|
return plugin.execute(**arguments)
|
||||||
|
|
||||||
|
def run_ast_checks(self):
|
||||||
|
"""Run all checks expecting an abstract syntax tree."""
|
||||||
|
try:
|
||||||
|
ast = self.processor.build_ast()
|
||||||
|
except (ValueError, SyntaxError, TypeError):
|
||||||
|
(exc_type, exception) = sys.exc_info()[:2]
|
||||||
|
if len(exception.args) > 1:
|
||||||
|
offset = exception.args[1]
|
||||||
|
if len(offset) > 2:
|
||||||
|
offset = offset[1:3]
|
||||||
|
else:
|
||||||
|
offset = (1, 0)
|
||||||
|
|
||||||
|
self.report('E999', offset[0], offset[1], '%s: %s' %
|
||||||
|
(exc_type.__name__, exception.args[0]))
|
||||||
|
return
|
||||||
|
|
||||||
|
for plugin in self.checks.ast_plugins:
|
||||||
|
checker = self.run_check(plugin, tree=ast)
|
||||||
|
# NOTE(sigmavirus24): If we want to allow for AST plugins that are
|
||||||
|
# not classes exclusively, we can do the following:
|
||||||
|
# retrieve_results = getattr(checker, 'run', lambda: checker)
|
||||||
|
# Otherwise, we just call run on the checker
|
||||||
|
for (line_number, offset, text, check) in checker.run():
|
||||||
|
self.report(
|
||||||
|
error_code=None,
|
||||||
|
line_number=line_number,
|
||||||
|
column=offset,
|
||||||
|
text=text,
|
||||||
|
)
|
||||||
|
|
||||||
def run_logical_checks(self):
|
def run_logical_checks(self):
|
||||||
"""Run all checks expecting a logical line."""
|
"""Run all checks expecting a logical line."""
|
||||||
comments, logical_line, mapping = self.processor.build_logical_line()
|
comments, logical_line, mapping = self.processor.build_logical_line()
|
||||||
|
|
@ -404,6 +435,8 @@ class FileChecker(object):
|
||||||
self.report(exc.error_code, exc.line_number, exc.column_number,
|
self.report(exc.error_code, exc.line_number, exc.column_number,
|
||||||
exc.error_message)
|
exc.error_message)
|
||||||
|
|
||||||
|
self.run_ast_checks()
|
||||||
|
|
||||||
if results_queue is not None:
|
if results_queue is not None:
|
||||||
results_queue.put((self.filename, self.results))
|
results_queue.put((self.filename, self.results))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,9 @@ class Application(object):
|
||||||
self.option_manager, argv
|
self.option_manager, argv
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.check_plugins.provide_options(self.option_manager, self.options,
|
||||||
|
self.args)
|
||||||
|
|
||||||
def make_formatter(self):
|
def make_formatter(self):
|
||||||
# type: () -> NoneType
|
# type: () -> NoneType
|
||||||
"""Initialize a formatter based on the parsed options."""
|
"""Initialize a formatter based on the parsed options."""
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ from flake8 import defaults
|
||||||
from flake8 import exceptions
|
from flake8 import exceptions
|
||||||
from flake8 import utils
|
from flake8 import utils
|
||||||
|
|
||||||
|
PyCF_ONLY_AST = 1024
|
||||||
NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE])
|
NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE])
|
||||||
# Work around Python < 2.6 behaviour, which does not generate NL after
|
# Work around Python < 2.6 behaviour, which does not generate NL after
|
||||||
# a comment which is on a line by itself.
|
# a comment which is on a line by itself.
|
||||||
|
|
@ -172,6 +173,10 @@ class FileProcessor(object):
|
||||||
(previous_row, previous_column) = end
|
(previous_row, previous_column) = end
|
||||||
return comments, logical, mapping
|
return comments, logical, mapping
|
||||||
|
|
||||||
|
def build_ast(self):
|
||||||
|
"""Build an abstract syntax tree from the list of lines."""
|
||||||
|
return compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST)
|
||||||
|
|
||||||
def build_logical_line(self):
|
def build_logical_line(self):
|
||||||
"""Build a logical line from the current tokens list."""
|
"""Build a logical line from the current tokens list."""
|
||||||
comments, logical, mapping_list = self.build_logical_line_tokens()
|
comments, logical, mapping_list = self.build_logical_line_tokens()
|
||||||
|
|
@ -223,6 +228,10 @@ class FileProcessor(object):
|
||||||
except tokenize.TokenError as exc:
|
except tokenize.TokenError as exc:
|
||||||
raise exceptions.InvalidSyntax(exc.message, exception=exc)
|
raise exceptions.InvalidSyntax(exc.message, exception=exc)
|
||||||
|
|
||||||
|
def line_for(self, line_number):
|
||||||
|
"""Retrieve the physical line at the specified line number."""
|
||||||
|
return self.lines[line_number - 1]
|
||||||
|
|
||||||
def next_line(self):
|
def next_line(self):
|
||||||
"""Get the next line from the list."""
|
"""Get the next line from the list."""
|
||||||
if self.line_number >= self.total_lines:
|
if self.line_number >= self.total_lines:
|
||||||
|
|
|
||||||
|
|
@ -187,12 +187,13 @@ class StyleGuide(object):
|
||||||
error, codes_str)
|
error, codes_str)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def handle_error(self, code, filename, line_number, column_number, text):
|
def handle_error(self, code, filename, line_number, column_number, text,
|
||||||
|
physical_line=None):
|
||||||
# type: (str, str, int, int, str) -> NoneType
|
# type: (str, str, int, int, str) -> NoneType
|
||||||
"""Handle an error reported by a check."""
|
"""Handle an error reported by a check."""
|
||||||
error = Error(code, filename, line_number, column_number, text)
|
error = Error(code, filename, line_number, column_number, text)
|
||||||
if (self.should_report_error(error.code) is Decision.Selected and
|
if (self.should_report_error(error.code) is Decision.Selected and
|
||||||
self.is_inline_ignored(error) is False):
|
self.is_inline_ignored(error, physical_line) is False):
|
||||||
self.formatter.handle(error)
|
self.formatter.handle(error)
|
||||||
self.listener.notify(error.code, error)
|
self.listener.notify(error.code, error)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue