2 API for the command-line I{pyflakes} tool.
4 from __future__
import with_statement
9 from optparse
import OptionParser
11 from pyflakes
import checker
, __version__
12 from pyflakes
import reporter
as modReporter
14 __all__
= ['check', 'checkPath', 'checkRecursive', 'iterSourceCode', 'main']
17 def check(codeString
, filename
, reporter
=None):
19 Check the Python source given by C{codeString} for flakes.
21 @param codeString: The Python source to check.
22 @type codeString: C{str}
24 @param filename: The name of the file the source came from, used to report
26 @type filename: C{str}
28 @param reporter: A L{Reporter} instance, where errors and warnings will be
31 @return: The number of warnings emitted.
35 reporter
= modReporter
._makeDefaultReporter
()
36 # First, compile into an AST and handle syntax errors.
38 tree
= compile(codeString
, filename
, "exec", _ast
.PyCF_ONLY_AST
)
40 value
= sys
.exc_info()[1]
43 (lineno
, offset
, text
) = value
.lineno
, value
.offset
, value
.text
45 # If there's an encoding problem with the file, the text is None.
47 # Avoid using msg, since for the only known case, it contains a
48 # bogus message that claims the encoding the file declared was
50 reporter
.unexpectedError(filename
, 'problem decoding source')
52 reporter
.syntaxError(filename
, msg
, lineno
, offset
, text
)
55 reporter
.unexpectedError(filename
, 'problem decoding source')
57 # Okay, it's syntactically valid. Now check it.
58 w
= checker
.Checker(tree
, filename
)
59 w
.messages
.sort(key
=lambda m
: m
.lineno
)
60 for warning
in w
.messages
:
61 reporter
.flake(warning
)
62 return len(w
.messages
)
65 def checkPath(filename
, reporter
=None):
67 Check the given path, printing out any warnings detected.
69 @param reporter: A L{Reporter} instance, where errors and warnings will be
72 @return: the number of warnings printed
75 reporter
= modReporter
._makeDefaultReporter
()
77 with
open(filename
, 'U') as f
:
78 codestr
= f
.read() + '\n'
80 reporter
.unexpectedError(filename
, 'problem decoding source')
83 msg
= sys
.exc_info()[1]
84 reporter
.unexpectedError(filename
, msg
.args
[1])
86 return check(codestr
, filename
, reporter
)
89 def iterSourceCode(paths
):
91 Iterate over all Python source files in C{paths}.
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
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
)
107 def checkRecursive(paths
, reporter
):
109 Recursively check all source files in C{paths}.
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
115 @return: The number of warnings found.
118 for sourcePath
in iterSourceCode(paths
):
119 warnings
+= checkPath(sourcePath
, reporter
)
124 parser
= OptionParser(prog
=prog
, version
=__version__
)
125 __
, args
= parser
.parse_args()
126 reporter
= modReporter
._makeDefaultReporter
()
128 warnings
= checkRecursive(args
, reporter
)
130 warnings
= check(sys
.stdin
.read(), '<stdin>', reporter
)
131 raise SystemExit(warnings
> 0)