~ubuntu-branches/ubuntu/raring/pyflakes/raring-proposed

« back to all changes in this revision

Viewing changes to pyflakes/api.py

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-02-13 19:07:52 UTC
  • mfrom: (3.1.9 experimental)
  • Revision ID: package-import@ubuntu.com-20130213190752-pr06y05rz8n06tmg
Tags: 0.6.1-1~exp1
* New upstream release:
  + rebase add_main_function.diff.
  - drop always_close_fd.diff, merged upstream.
  - drop check_encoding_errors.diff, merged upstream.
* Bump standards version
* Switch to dh_python2
* Bump debhelper to 9
* Adjust Vcs URL to canonical format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
API for the command-line I{pyflakes} tool.
 
3
"""
 
4
 
 
5
import sys
 
6
import os
 
7
import _ast
 
8
 
 
9
from pyflakes import checker
 
10
from pyflakes import reporter as modReporter
 
11
 
 
12
__all__ = ['check', 'checkPath', 'checkRecursive', 'iterSourceCode', 'main']
 
13
 
 
14
 
 
15
def check(codeString, filename, reporter=None):
 
16
    """
 
17
    Check the Python source given by C{codeString} for flakes.
 
18
 
 
19
    @param codeString: The Python source to check.
 
20
    @type codeString: C{str}
 
21
 
 
22
    @param filename: The name of the file the source came from, used to report
 
23
        errors.
 
24
    @type filename: C{str}
 
25
 
 
26
    @param reporter: A L{Reporter} instance, where errors and warnings will be
 
27
        reported.
 
28
 
 
29
    @return: The number of warnings emitted.
 
30
    @rtype: C{int}
 
31
    """
 
32
    if reporter is None:
 
33
        reporter = modReporter._makeDefaultReporter()
 
34
    # First, compile into an AST and handle syntax errors.
 
35
    try:
 
36
        tree = compile(codeString, filename, "exec", _ast.PyCF_ONLY_AST)
 
37
    except SyntaxError:
 
38
        value = sys.exc_info()[1]
 
39
        msg = value.args[0]
 
40
 
 
41
        (lineno, offset, text) = value.lineno, value.offset, value.text
 
42
 
 
43
        # If there's an encoding problem with the file, the text is None.
 
44
        if text is None:
 
45
            # Avoid using msg, since for the only known case, it contains a
 
46
            # bogus message that claims the encoding the file declared was
 
47
            # unknown.
 
48
            reporter.unexpectedError(filename, 'problem decoding source')
 
49
        else:
 
50
            reporter.syntaxError(filename, msg, lineno, offset, text)
 
51
        return 1
 
52
    except Exception:
 
53
        reporter.unexpectedError(filename, 'problem decoding source')
 
54
        return 1
 
55
    else:
 
56
        # Okay, it's syntactically valid.  Now check it.
 
57
        w = checker.Checker(tree, filename)
 
58
        w.messages.sort(key=lambda m: m.lineno)
 
59
        for warning in w.messages:
 
60
            reporter.flake(warning)
 
61
        return len(w.messages)
 
62
 
 
63
 
 
64
def checkPath(filename, reporter=None):
 
65
    """
 
66
    Check the given path, printing out any warnings detected.
 
67
 
 
68
    @param reporter: A L{Reporter} instance, where errors and warnings will be
 
69
        reported.
 
70
 
 
71
    @return: the number of warnings printed
 
72
    """
 
73
    if reporter is None:
 
74
        reporter = modReporter._makeDefaultReporter()
 
75
    try:
 
76
        f = open(filename, 'U')
 
77
        try:
 
78
            return check(f.read() + '\n', filename, reporter)
 
79
        finally:
 
80
            f.close()
 
81
    except UnicodeError:
 
82
        reporter.unexpectedError(filename, 'problem decoding source')
 
83
    except IOError:
 
84
        msg = sys.exc_info()[1]
 
85
        reporter.unexpectedError(filename, msg.args[1])
 
86
    return 1
 
87
 
 
88
 
 
89
def iterSourceCode(paths):
 
90
    """
 
91
    Iterate over all Python source files in C{paths}.
 
92
 
 
93
    @param paths: A list of paths.  Directories will be recursed into and
 
94
        any .py files found will be yielded.  Any non-directories will be
 
95
        yielded as-is.
 
96
    """
 
97
    for path in paths:
 
98
        if os.path.isdir(path):
 
99
            for dirpath, dirnames, filenames in os.walk(path):
 
100
                for filename in filenames:
 
101
                    if filename.endswith('.py'):
 
102
                        yield os.path.join(dirpath, filename)
 
103
        else:
 
104
            yield path
 
105
 
 
106
 
 
107
def checkRecursive(paths, reporter):
 
108
    """
 
109
    Recursively check all source files in C{paths}.
 
110
 
 
111
    @param paths: A list of paths to Python source files and directories
 
112
        containing Python source files.
 
113
    @param reporter: A L{Reporter} where all of the warnings and errors
 
114
        will be reported to.
 
115
    @return: The number of warnings found.
 
116
    """
 
117
    warnings = 0
 
118
    for sourcePath in iterSourceCode(paths):
 
119
        warnings += checkPath(sourcePath, reporter)
 
120
    return warnings
 
121
 
 
122
 
 
123
def main(args):
 
124
    reporter = modReporter._makeDefaultReporter()
 
125
    if args:
 
126
        warnings = checkRecursive(args, reporter)
 
127
    else:
 
128
        warnings = check(sys.stdin.read(), '<stdin>', reporter)
 
129
    raise SystemExit(warnings > 0)