forked from adamlaska/datatracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyflakes.py
More file actions
137 lines (109 loc) · 4.16 KB
/
pyflakes.py
File metadata and controls
137 lines (109 loc) · 4.16 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# Copyright The IETF Trust 2014-2020, All Rights Reserved
# -*- coding: utf-8 -*-
import ast
import io
import os
from pyflakes import checker, messages
import sys
from django.conf import settings
from django.core.management.base import BaseCommand
import debug # pyflakes:ignore
# BlackHole, PySyntaxError and checking based on
# https://github.com/patrys/gedit-pyflakes-plugin.git
class BlackHole(object):
write = flush = lambda *args, **kwargs: None
def __enter__(self):
self.stderr, sys.stderr = sys.stderr, self
def __exit__(self, *args, **kwargs):
sys.stderr = self.stderr
class PySyntaxError(messages.Message):
message = 'syntax error in line %d: %s'
def __init__(self, filename, lineno, col, message):
try:
super(PySyntaxError, self).__init__(filename, lineno)
except Exception:
sys.stderr.write("\nAn exception occurred while processing file %s\n"
"The file could contain syntax errors.\n\n" % filename)
raise
self.message_args = (col, message)
def check(codeString, filename, verbosity=1):
"""
Check the Python source given by C{codeString} for flakes.
@param codeString: The Python source to check.
@type codeString: C{str}
@param filename: The name of the file the source came from, used to report
errors.
@type filename: C{str}
@return: The number of warnings emitted.
@rtype: C{int}
"""
try:
with BlackHole():
tree = ast.parse(codeString, filename)
except SyntaxError as e:
return [PySyntaxError(filename, e.lineno, e.offset, e.text)]
else:
# Okay, it's syntactically valid. Now parse it into an ast and check
# it.
w = checker.Checker(tree, filename)
lines = codeString.split(b'\n')
# honour pyflakes:ignore comments
messages = [message for message in w.messages
if (lines[message.lineno-1].find(b'pyflakes:ignore') < 0 and lines[message.lineno-1].find(b'pyflakes: ignore') < 0) ]
# honour pyflakes:
messages.sort(key=lambda x: x.lineno)
if verbosity > 0:
if len(messages):
sys.stderr.write('F')
else:
sys.stderr.write('.')
sys.stderr.flush()
if verbosity > 1:
sys.stderr.write(" %s\n" % filename)
return messages
def checkPath(filename, verbosity):
"""
Check the given path, printing out any warnings detected.
@return: the number of warnings printed
"""
if verbosity > 1:
sys.stderr.write("\n %-78s " % filename)
sys.stderr.flush()
try:
with io.open(filename, 'br') as f:
text = f.read()
return check(text + b'\n', filename, verbosity)
except IOError as msg:
return ["%s: %s" % (filename, msg.args[1])]
except TypeError:
pass
def checkPaths(filenames, verbosity):
warnings = []
for arg in filenames:
if os.path.isdir(arg):
for dirpath, dirnames, filenames in os.walk(arg):
for filename in filenames:
if filename.endswith('.py'):
try:
warnings.extend(checkPath(os.path.join(dirpath, filename), verbosity))
except TypeError as e:
print("Exception while processing dirpath=%s, filename=%s: %s" % (dirpath, filename, e ))
raise
else:
warnings.extend(checkPath(arg, verbosity))
return warnings
#### pyflakes.scripts.pyflakes ends.
class Command(BaseCommand):
help = "Run pyflakes syntax checks."
args = '[path [path [...]]]'
def handle(self, *filenames, **options):
if not filenames:
filenames = getattr(settings, 'PYFLAKES_DEFAULT_ARGS', ['.'])
verbosity = int(options.get('verbosity'))
warnings = checkPaths(filenames, verbosity=verbosity)
print("")
for warning in warnings:
print(warning)
if warnings:
print('Total warnings: %d' % len(warnings))
raise SystemExit(1)