Login

invoke pyflakes via manage.py

Author:
mpasternacki
Posted:
October 16, 2009
Language:
Python
Version:
1.1
Tags:
management pyflakes flakes
Score:
2 (after 2 ratings)

Invokes pyflakes diagnostic tool as a manage.py command. Save as flakes.py, since pyflakes.py will collide with pyflakes module.

I needed to invoke pyflakes as management command, because I alter sys.path in my manage.py, so system-wide pyflakes would not see project-local modules.

Provides possibility of ignoring warnings by adding text pyflakes:ignore in a comment at end of offending line. Returns non-zero status to system when non-ignored warnings are found.

Accepts list of directories or files as arguments. When no arguments are given, PYFLAKES_DEFAULT_ARGS setting is used (list of strings, by default ['.']).

  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
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)

More like this

  1. Command to dump data as a python script by willhardy 7 years, 1 month ago
  2. Management command to list custom management commands by pbx 6 years, 1 month ago
  3. A smart trace() command by aparajita 6 years, 1 month ago
  4. Shortcuts to your code organized by type (views, models, admin, ...) by stdbrouw 5 years, 5 months ago
  5. Quiet runserver by danielroseman 5 years, 2 months ago

Comments

Please login first before commenting.