|
|
@@ -0,0 +1,107 @@ |
|
|
from django.conf import settings |
|
|
from django.core.management.base import BaseCommand |
|
|
|
|
|
#### pyflakes.scripts.pyflakes, modified: |
|
|
## - return array of warnings instead of printing them |
|
|
## - honour pyflakes:ignore comments |
|
|
import compiler, sys |
|
|
import os |
|
|
|
|
|
import pyflakes.checker |
|
|
|
|
|
def check(codeString, filename): |
|
|
""" |
|
|
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} |
|
|
""" |
|
|
# Since compiler.parse does not reliably report syntax errors, use the |
|
|
# built in compiler first to detect those. |
|
|
try: |
|
|
try: |
|
|
compile(codeString, filename, "exec") |
|
|
except MemoryError: |
|
|
# Python 2.4 will raise MemoryError if the source can't be |
|
|
# decoded. |
|
|
if sys.version_info[:2] == (2, 4): |
|
|
raise SyntaxError(None) |
|
|
raise |
|
|
except (SyntaxError, IndentationError), value: |
|
|
msg = value.args[0] |
|
|
|
|
|
(lineno, offset, text) = value.lineno, value.offset, value.text |
|
|
|
|
|
# If there's an encoding problem with the file, the text is None. |
|
|
if text is None: |
|
|
# Avoid using msg, since for the only known case, it contains a |
|
|
# bogus message that claims the encoding the file declared was |
|
|
# unknown. |
|
|
return ["%s: problem decoding source" % (filename, )] |
|
|
else: |
|
|
line = text.splitlines()[-1] |
|
|
|
|
|
if offset is not None: |
|
|
offset = offset - (len(text) - len(line)) |
|
|
|
|
|
return ['%s:%d: %s' % (filename, lineno, msg)] |
|
|
else: |
|
|
# Okay, it's syntactically valid. Now parse it into an ast and check |
|
|
# it. |
|
|
tree = compiler.parse(codeString) |
|
|
w = pyflakes.checker.Checker(tree, filename) |
|
|
|
|
|
lines = codeString.split('\n') |
|
|
messages = [message for message in w.messages |
|
|
if lines[message.lineno-1].find('pyflakes:ignore') < 0] |
|
|
messages.sort(lambda a, b: cmp(a.lineno, b.lineno)) |
|
|
|
|
|
return messages |
|
|
|
|
|
|
|
|
def checkPath(filename): |
|
|
""" |
|
|
Check the given path, printing out any warnings detected. |
|
|
|
|
|
@return: the number of warnings printed |
|
|
""" |
|
|
try: |
|
|
return check(file(filename, 'U').read() + '\n', filename) |
|
|
except IOError, msg: |
|
|
return ["%s: %s" % (filename, msg.args[1])] |
|
|
|
|
|
|
|
|
def checkPaths(filenames): |
|
|
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'): |
|
|
warnings.extend(checkPath(os.path.join(dirpath, filename))) |
|
|
else: |
|
|
warnings.extend(checkPath(arg)) |
|
|
return warnings |
|
|
#### pyflakes.scripts.pyflakes ends. |
|
|
|
|
|
class Command(BaseCommand): |
|
|
help = "Run pyflakes syntax checks." |
|
|
args = '[filename [filename [...]]]' |
|
|
|
|
|
def handle(self, *filenames, **options): |
|
|
if not filenames: |
|
|
filenames = getattr(settings, 'PYFLAKES_DEFAULT_ARGS', ['.']) |
|
|
warnings = checkPaths(filenames) |
|
|
for warning in warnings: |
|
|
print warning |
|
|
|
|
|
if warnings: |
|
|
print 'Total warnings: %d' % len(warnings) |
|
|
raise SystemExit(1) |