Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/pylint/epylint.py

Issue 10447014: Add pylint to depot_tools. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Fix unittests. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/pylint/config.py ('k') | third_party/pylint/gui.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic- offset: 4 -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
3 """Emacs and Flymake compatible Pylint.
4
5 This script is for integration with emacs and is compatible with flymake mode.
6
7 epylint walks out of python packages before invoking pylint. This avoids
8 reporting import errors that occur when a module within a package uses the
9 absolute import path to get another module within this package.
10
11 For example:
12 - Suppose a package is structured as
13
14 a/__init__.py
15 a/b/x.py
16 a/c/y.py
17
18 - Then if y.py imports x as "from a.b import x" the following produces pylint errors
19
20 cd a/c; pylint y.py
21
22 - The following obviously doesn't
23
24 pylint a/c/y.py
25
26 - As this script will be invoked by emacs within the directory of the file
27 we are checking we need to go out of it to avoid these false positives.
28
29
30 You may also use py_run to run pylint with desired options and get back (or not) its output.
31 """
32
33 import sys, os, re
34 from subprocess import Popen, PIPE
35
36
37 def lint(filename):
38 """Pylint the given file.
39
40 When run from emacs we will be in the directory of a file, and passed its fi lename.
41 If this file is part of a package and is trying to import other modules from within
42 its own package or another package rooted in a directory below it, pylint wi ll classify
43 it as a failed import.
44
45 To get around this, we traverse down the directory tree to find the root of the package this
46 module is in. We then invoke pylint from this directory.
47
48 Finally, we must correct the filenames in the output generated by pylint so Emacs doesn't
49 become confused (it will expect just the original filename, while pylint may extend it with
50 extra directories if we've traversed down the tree)
51 """
52 # traverse downwards until we are out of a python package
53 fullPath = os.path.abspath(filename)
54 parentPath, childPath = os.path.dirname(fullPath), os.path.basename(fullPath )
55
56 while parentPath != "/" and os.path.exists(os.path.join(parentPath, '__init_ _.py')):
57 childPath = os.path.join(os.path.basename(parentPath), childPath)
58 parentPath = os.path.dirname(parentPath)
59
60 # Start pylint
61 process = Popen('pylint -f parseable -r n --disable=C,R,I "%s"' %
62 childPath, shell=True, stdout=PIPE, stderr=PIPE,
63 cwd=parentPath)
64 p = process.stdout
65
66 # The parseable line format is '%(path)s:%(line)s: [%(sigle)s%(obj)s] %(msg) s'
67 # NOTE: This would be cleaner if we added an Emacs reporter to pylint.report ers.text ..
68 regex = re.compile(r"\[(?P<type>[WE])(?P<remainder>.*?)\]")
69
70 def _replacement(mObj):
71 "Alter to include 'Error' or 'Warning'"
72 if mObj.group("type") == "W":
73 replacement = "Warning"
74 else:
75 replacement = "Error"
76 # replace as "Warning (W0511, funcName): Warning Text"
77 return "%s (%s%s):" % (replacement, mObj.group("type"), mObj.group("rema inder"))
78
79 for line in p:
80 # remove pylintrc warning
81 if line.startswith("No config file found"):
82 continue
83 line = regex.sub(_replacement, line, 1)
84 # modify the file name thats output to reverse the path traversal we mad e
85 parts = line.split(":")
86 if parts and parts[0] == childPath:
87 line = ":".join([filename] + parts[1:])
88 print line,
89
90 p.close()
91
92 def Run():
93 lint(sys.argv[1])
94
95
96 def py_run(command_options='', return_std=False, stdout=None, stderr=None,
97 script='epylint'):
98 """Run pylint from python (needs Python >= 2.4).
99
100 ``command_options`` is a string containing ``pylint`` command line options;
101 ``return_std`` (boolean) indicates return of created standart output
102 and error (see below);
103 ``stdout`` and ``stderr`` are 'file-like' objects in which standart output
104 could be written.
105
106 Calling agent is responsible for stdout/err management (creation, close).
107 Default standart output and error are those from sys,
108 or standalone ones (``subprocess.PIPE``) are used
109 if they are not set and ``return_std``.
110
111 If ``return_std`` is set to ``True``, this function returns a 2-uple
112 containing standart output and error related to created process,
113 as follows: ``(stdout, stderr)``.
114
115 A trivial usage could be as follows:
116 >>> py_run( '--version')
117 No config file found, using default configuration
118 pylint 0.18.1,
119 ...
120
121 To silently run Pylint on a module, and get its standart output and error:
122 >>> (pylint_stdout, pylint_stderr) = py_run( 'module_name.py', True)
123 """
124 # Create command line to call pylint
125 if os.name == 'nt':
126 script += '.bat'
127 command_line = script + ' ' + command_options
128 # Providing standart output and/or error if not set
129 if stdout is None:
130 if return_std:
131 stdout = PIPE
132 else:
133 stdout = sys.stdout
134 if stderr is None:
135 if return_std:
136 stderr = PIPE
137 else:
138 stderr = sys.stderr
139 # Call pylint in a subprocess
140 p = Popen(command_line, shell=True, stdout=stdout, stderr=stderr)
141 p.wait()
142 # Return standart output and error
143 if return_std:
144 return (p.stdout, p.stderr)
145
146
147 if __name__ == '__main__':
148 lint(sys.argv[1])
149
OLDNEW
« no previous file with comments | « third_party/pylint/config.py ('k') | third_party/pylint/gui.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698