/
extension.py
91 lines (77 loc) · 2.67 KB
/
extension.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python
from __future__ import (
absolute_import,
division,
print_function,
unicode_literals,
)
import importlib
import inspect
import pkgutil
import optparse
import sys
import dlint
class Flake8Extension(object):
name = dlint.__name__
version = dlint.__version__
def __init__(self, tree, filename):
self.tree = tree
self.filename = filename
@classmethod
def add_options(cls, parser):
try:
parser.add_option(
'--print-dlint-linters',
action='store_true',
help='Print Dlint linter information.',
parse_from_config=False
)
except optparse.OptionConflictError:
# Occurs during development when flake8 detects the dlint package
# twice: once because it's been installed in editable mode, and
# once from the local filesystem directory. We can safely nop here
# since the option(s) have already been added.
pass
@classmethod
def parse_options(cls, options):
if options.print_dlint_linters:
code_prefix_len = 7
linters = Flake8Extension.get_linter_classes()
output_lines = [
"{} {} {}".format(l._code, l.__name__, l._error_tmpl[code_prefix_len:])
for l in sorted(linters, key=lambda li: li._code)
]
print("\n".join(output_lines))
EX_OK = 0
sys.exit(EX_OK)
@staticmethod
def get_plugin_linter_classes():
module_prefix = 'dlint_plugin_'
class_prefix = 'Dlint'
plugin_modules = [
importlib.import_module(name)
for finder, name, ispkg in pkgutil.iter_modules()
if name.startswith(module_prefix)
]
plugin_classes = [
cls
for module in plugin_modules
for name, cls in inspect.getmembers(module, predicate=inspect.isclass)
if name.startswith(class_prefix)
]
return plugin_classes
@staticmethod
def get_linter_classes():
return dlint.linters.ALL + tuple(Flake8Extension.get_plugin_linter_classes())
def run(self):
linter_instances = [l() for l in Flake8Extension.get_linter_classes()]
multi_visitor = dlint.multi.MultiNodeVisitor(linter_instances)
multi_visitor.visit(self.tree)
for linter_instance in linter_instances:
for result in linter_instance.get_results():
yield (
result.lineno,
result.col_offset,
result.message,
type(linter_instance)
)