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

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

Issue 707353002: pylint: upgrade to 1.3.1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Created 6 years, 1 month 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
OLDNEW
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 1 # -*- 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
2 # Copyright (c) 2003-2013 LOGILAB S.A. (Paris, FRANCE).
3 # http://www.logilab.fr/ -- mailto:contact@logilab.fr
4 #
5 # This program is free software; you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 2 of the License, or (at your option) any later
8 # version.
9 #
10 # This program is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
13 #
14 # You should have received a copy of the GNU General Public License along with
15 # this program; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
3 """Emacs and Flymake compatible Pylint. 17 """Emacs and Flymake compatible Pylint.
4 18
5 This script is for integration with emacs and is compatible with flymake mode. 19 This script is for integration with emacs and is compatible with flymake mode.
6 20
7 epylint walks out of python packages before invoking pylint. This avoids 21 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 22 reporting import errors that occur when a module within a package uses the
9 absolute import path to get another module within this package. 23 absolute import path to get another module within this package.
10 24
11 For example: 25 For example:
12 - Suppose a package is structured as 26 - Suppose a package is structured as
13 27
14 a/__init__.py 28 a/__init__.py
15 a/b/x.py 29 a/b/x.py
16 a/c/y.py 30 a/c/y.py
17 31
18 - Then if y.py imports x as "from a.b import x" the following produces pylint errors 32 - Then if y.py imports x as "from a.b import x" the following produces pylint
33 errors
19 34
20 cd a/c; pylint y.py 35 cd a/c; pylint y.py
21 36
22 - The following obviously doesn't 37 - The following obviously doesn't
23 38
24 pylint a/c/y.py 39 pylint a/c/y.py
25 40
26 - As this script will be invoked by emacs within the directory of the file 41 - 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. 42 we are checking we need to go out of it to avoid these false positives.
28 43
29 44
30 You may also use py_run to run pylint with desired options and get back (or not) its output. 45 You may also use py_run to run pylint with desired options and get back (or not)
46 its output.
31 """ 47 """
32 48
33 import sys, os, re 49 import sys, os
50 import os.path as osp
34 from subprocess import Popen, PIPE 51 from subprocess import Popen, PIPE
35 52
53 def _get_env():
54 '''Extracts the environment PYTHONPATH and appends the current sys.path to
55 those.'''
56 env = dict(os.environ)
57 env['PYTHONPATH'] = os.pathsep.join(sys.path)
58 return env
36 59
37 def lint(filename): 60 def lint(filename, options=None):
38 """Pylint the given file. 61 """Pylint the given file.
39 62
40 When run from emacs we will be in the directory of a file, and passed its fi lename. 63 When run from emacs we will be in the directory of a file, and passed its
41 If this file is part of a package and is trying to import other modules from within 64 filename. If this file is part of a package and is trying to import other
42 its own package or another package rooted in a directory below it, pylint wi ll classify 65 modules from within its own package or another package rooted in a directory
43 it as a failed import. 66 below it, pylint will classify it as a failed import.
44 67
45 To get around this, we traverse down the directory tree to find the root of the package this 68 To get around this, we traverse down the directory tree to find the root of
46 module is in. We then invoke pylint from this directory. 69 the package this module is in. We then invoke pylint from this directory.
47 70
48 Finally, we must correct the filenames in the output generated by pylint so Emacs doesn't 71 Finally, we must correct the filenames in the output generated by pylint so
49 become confused (it will expect just the original filename, while pylint may extend it with 72 Emacs doesn't become confused (it will expect just the original filename,
50 extra directories if we've traversed down the tree) 73 while pylint may extend it with extra directories if we've traversed down
74 the tree)
51 """ 75 """
52 # traverse downwards until we are out of a python package 76 # traverse downwards until we are out of a python package
53 fullPath = os.path.abspath(filename) 77 full_path = osp.abspath(filename)
54 parentPath, childPath = os.path.dirname(fullPath), os.path.basename(fullPath ) 78 parent_path = osp.dirname(full_path)
79 child_path = osp.basename(full_path)
55 80
56 while parentPath != "/" and os.path.exists(os.path.join(parentPath, '__init_ _.py')): 81 while parent_path != "/" and osp.exists(osp.join(parent_path, '__init__.py') ):
57 childPath = os.path.join(os.path.basename(parentPath), childPath) 82 child_path = osp.join(osp.basename(parent_path), child_path)
58 parentPath = os.path.dirname(parentPath) 83 parent_path = osp.dirname(parent_path)
59 84
60 # Start pylint 85 # Start pylint
61 process = Popen('pylint -f parseable -r n --disable=C,R,I "%s"' % 86 # Ensure we use the python and pylint associated with the running epylint
62 childPath, shell=True, stdout=PIPE, stderr=PIPE, 87 from pylint import lint as lint_mod
63 cwd=parentPath) 88 lint_path = lint_mod.__file__
64 p = process.stdout 89 options = options or ['--disable=C,R,I']
90 cmd = [sys.executable, lint_path] + options + [
91 '--msg-template', '{path}:{line}: {category} ({msg_id}, {symbol}, {obj}) {msg}',
92 '-r', 'n', child_path]
93 process = Popen(cmd, stdout=PIPE, cwd=parent_path, env=_get_env(),
94 universal_newlines=True)
65 95
66 # The parseable line format is '%(path)s:%(line)s: [%(sigle)s%(obj)s] %(msg) s' 96 for line in process.stdout:
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 97 # remove pylintrc warning
81 if line.startswith("No config file found"): 98 if line.startswith("No config file found"):
82 continue 99 continue
83 line = regex.sub(_replacement, line, 1) 100
84 # modify the file name thats output to reverse the path traversal we mad e 101 # modify the file name thats output to reverse the path traversal we mad e
85 parts = line.split(":") 102 parts = line.split(":")
86 if parts and parts[0] == childPath: 103 if parts and parts[0] == child_path:
87 line = ":".join([filename] + parts[1:]) 104 line = ":".join([filename] + parts[1:])
88 print line, 105 print line,
89 106
90 p.close() 107 process.wait()
91 108 return process.returncode
92 def Run():
93 lint(sys.argv[1])
94 109
95 110
96 def py_run(command_options='', return_std=False, stdout=None, stderr=None, 111 def py_run(command_options='', return_std=False, stdout=None, stderr=None,
97 script='epylint'): 112 script='epylint'):
98 """Run pylint from python (needs Python >= 2.4). 113 """Run pylint from python
99 114
100 ``command_options`` is a string containing ``pylint`` command line options; 115 ``command_options`` is a string containing ``pylint`` command line options;
101 ``return_std`` (boolean) indicates return of created standart output 116 ``return_std`` (boolean) indicates return of created standart output
102 and error (see below); 117 and error (see below);
103 ``stdout`` and ``stderr`` are 'file-like' objects in which standart output 118 ``stdout`` and ``stderr`` are 'file-like' objects in which standart output
104 could be written. 119 could be written.
105 120
106 Calling agent is responsible for stdout/err management (creation, close). 121 Calling agent is responsible for stdout/err management (creation, close).
107 Default standart output and error are those from sys, 122 Default standart output and error are those from sys,
108 or standalone ones (``subprocess.PIPE``) are used 123 or standalone ones (``subprocess.PIPE``) are used
(...skipping 21 matching lines...) Expand all
130 if return_std: 145 if return_std:
131 stdout = PIPE 146 stdout = PIPE
132 else: 147 else:
133 stdout = sys.stdout 148 stdout = sys.stdout
134 if stderr is None: 149 if stderr is None:
135 if return_std: 150 if return_std:
136 stderr = PIPE 151 stderr = PIPE
137 else: 152 else:
138 stderr = sys.stderr 153 stderr = sys.stderr
139 # Call pylint in a subprocess 154 # Call pylint in a subprocess
140 p = Popen(command_line, shell=True, stdout=stdout, stderr=stderr) 155 p = Popen(command_line, shell=True, stdout=stdout, stderr=stderr,
156 env=_get_env(), universal_newlines=True)
141 p.wait() 157 p.wait()
142 # Return standart output and error 158 # Return standart output and error
143 if return_std: 159 if return_std:
144 return (p.stdout, p.stderr) 160 return (p.stdout, p.stderr)
145 161
146 162
163 def Run():
164 if len(sys.argv) == 1:
165 print "Usage: %s <filename> [options]" % sys.argv[0]
166 sys.exit(1)
167 elif not osp.exists(sys.argv[1]):
168 print "%s does not exist" % sys.argv[1]
169 sys.exit(1)
170 else:
171 sys.exit(lint(sys.argv[1], sys.argv[2:]))
172
173
147 if __name__ == '__main__': 174 if __name__ == '__main__':
148 lint(sys.argv[1]) 175 Run()
149
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698