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

Side by Side Diff: third_party/pylint/checkers/utils.py

Issue 719313003: Revert "pylint: upgrade to 1.3.1" (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
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
« no previous file with comments | « third_party/pylint/checkers/typecheck.py ('k') | third_party/pylint/checkers/variables.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # pylint: disable=W0611 1 # pylint: disable=W0611
2 # 2 #
3 # Copyright (c) 2003-2013 LOGILAB S.A. (Paris, FRANCE). 3 # Copyright (c) 2003-2010 LOGILAB S.A. (Paris, FRANCE).
4 # http://www.logilab.fr/ -- mailto:contact@logilab.fr 4 # http://www.logilab.fr/ -- mailto:contact@logilab.fr
5 # 5 #
6 # This program is free software; you can redistribute it and/or modify it under 6 # This program is free software; you can redistribute it and/or modify it under
7 # the terms of the GNU General Public License as published by the Free Software 7 # the terms of the GNU General Public License as published by the Free Software
8 # Foundation; either version 2 of the License, or (at your option) any later 8 # Foundation; either version 2 of the License, or (at your option) any later
9 # version. 9 # version.
10 # 10 #
11 # This program is distributed in the hope that it will be useful, but WITHOUT 11 # This program is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 # 14 #
15 # You should have received a copy of the GNU General Public License along with 15 # You should have received a copy of the GNU General Public License along with
16 # this program; if not, write to the Free Software Foundation, Inc., 16 # this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 """some functions that may be useful for various checkers 18 """some functions that may be useful for various checkers
19 """ 19 """
20 20
21 import re
22 import sys
23 import string 21 import string
22 from logilab import astng
23 from logilab.common.compat import builtins
24 BUILTINS_NAME = builtins.__name__
24 25
25 import astroid 26 COMP_NODE_TYPES = astng.ListComp, astng.SetComp, astng.DictComp, astng.GenExpr
26 from astroid import scoped_nodes
27 from logilab.common.compat import builtins
28
29 BUILTINS_NAME = builtins.__name__
30 COMP_NODE_TYPES = astroid.ListComp, astroid.SetComp, astroid.DictComp, astroid.G enExpr
31 PY3K = sys.version_info[0] == 3
32
33
34 class NoSuchArgumentError(Exception):
35 pass
36 27
37 def is_inside_except(node): 28 def is_inside_except(node):
38 """Returns true if node is inside the name of an except handler.""" 29 """Returns true if node is directly inside an exception handler"""
39 current = node 30 return isinstance(node.parent, astng.ExceptHandler)
40 while current and not isinstance(current.parent, astroid.ExceptHandler):
41 current = current.parent
42
43 return current and current is current.parent.name
44
45
46 def get_all_elements(node):
47 """Recursively returns all atoms in nested lists and tuples."""
48 if isinstance(node, (astroid.Tuple, astroid.List)):
49 for child in node.elts:
50 for e in get_all_elements(child):
51 yield e
52 else:
53 yield node
54 31
55 32
56 def clobber_in_except(node): 33 def clobber_in_except(node):
57 """Checks if an assignment node in an except handler clobbers an existing 34 """Checks if an assignment node in an except handler clobbers an existing
58 variable. 35 variable.
59 36
60 Returns (True, args for W0623) if assignment clobbers an existing variable, 37 Returns (True, args for W0623) if assignment clobbers an existing variable,
61 (False, None) otherwise. 38 (False, None) otherwise.
62 """ 39 """
63 if isinstance(node, astroid.AssAttr): 40 if isinstance(node, astng.AssAttr):
64 return (True, (node.attrname, 'object %r' % (node.expr.as_string(),))) 41 return (True, (node.attrname, 'object %r' % (node.expr.name,)))
65 elif isinstance(node, astroid.AssName): 42 elif node is not None:
66 name = node.name 43 name = node.name
67 if is_builtin(name): 44 if is_builtin(name):
68 return (True, (name, 'builtins')) 45 return (True, (name, 'builtins'))
69 else: 46 else:
70 stmts = node.lookup(name)[1] 47 scope, stmts = node.lookup(name)
71 if (stmts and not isinstance(stmts[0].ass_type(), 48 if (stmts and
72 (astroid.Assign, astroid.AugAssign, 49 not isinstance(stmts[0].ass_type(),
73 astroid.ExceptHandler))): 50 (astng.Assign, astng.AugAssign, astng.ExceptHandl er))):
74 return (True, (name, 'outer scope (line %s)' % stmts[0].fromline no)) 51 return (True, (name, 'outer scope (line %i)' % (stmts[0].lineno, )))
75 return (False, None) 52 return (False, None)
76 53
77 54
78 def safe_infer(node): 55 def safe_infer(node):
79 """return the inferred value for the given node. 56 """return the inferred value for the given node.
80 Return None if inference failed or if there is some ambiguity (more than 57 Return None if inference failed or if there is some ambiguity (more than
81 one node has been inferred) 58 one node has been inferred)
82 """ 59 """
83 try: 60 try:
84 inferit = node.infer() 61 inferit = node.infer()
85 value = inferit.next() 62 value = inferit.next()
86 except astroid.InferenceError: 63 except astng.InferenceError:
87 return 64 return
88 try: 65 try:
89 inferit.next() 66 inferit.next()
90 return # None if there is ambiguity on the inferred node 67 return # None if there is ambiguity on the inferred node
91 except astroid.InferenceError:
92 return # there is some kind of ambiguity
93 except StopIteration: 68 except StopIteration:
94 return value 69 return value
95 70
96 def is_super(node): 71 def is_super(node):
97 """return True if the node is referencing the "super" builtin function 72 """return True if the node is referencing the "super" builtin function
98 """ 73 """
99 if getattr(node, 'name', None) == 'super' and \ 74 if getattr(node, 'name', None) == 'super' and \
100 node.root().name == BUILTINS_NAME: 75 node.root().name == BUILTINS_NAME:
101 return True 76 return True
102 return False 77 return False
103 78
104 def is_error(node): 79 def is_error(node):
105 """return true if the function does nothing but raising an exception""" 80 """return true if the function does nothing but raising an exception"""
106 for child_node in node.get_children(): 81 for child_node in node.get_children():
107 if isinstance(child_node, astroid.Raise): 82 if isinstance(child_node, astng.Raise):
108 return True 83 return True
109 return False 84 return False
110 85
111 def is_raising(body): 86 def is_raising(body):
112 """return true if the given statement node raise an exception""" 87 """return true if the given statement node raise an exception"""
113 for node in body: 88 for node in body:
114 if isinstance(node, astroid.Raise): 89 if isinstance(node, astng.Raise):
115 return True 90 return True
116 return False 91 return False
117 92
118 def is_empty(body): 93 def is_empty(body):
119 """return true if the given node does nothing but 'pass'""" 94 """return true if the given node does nothing but 'pass'"""
120 return len(body) == 1 and isinstance(body[0], astroid.Pass) 95 return len(body) == 1 and isinstance(body[0], astng.Pass)
121 96
122 builtins = builtins.__dict__.copy() 97 builtins = __builtins__.copy()
123 SPECIAL_BUILTINS = ('__builtins__',) # '__path__', '__file__') 98 SPECIAL_BUILTINS = ('__builtins__',) # '__path__', '__file__')
124 99
125 def is_builtin_object(node):
126 """Returns True if the given node is an object from the __builtin__ module." ""
127 return node and node.root().name == BUILTINS_NAME
128
129 def is_builtin(name): # was is_native_builtin 100 def is_builtin(name): # was is_native_builtin
130 """return true if <name> could be considered as a builtin defined by python 101 """return true if <name> could be considered as a builtin defined by python
131 """ 102 """
132 if name in builtins: 103 if name in builtins:
133 return True 104 return True
134 if name in SPECIAL_BUILTINS: 105 if name in SPECIAL_BUILTINS:
135 return True 106 return True
136 return False 107 return False
137 108
138 def is_defined_before(var_node): 109 def is_defined_before(var_node):
139 """return True if the variable node is defined by a parent node (list, 110 """return True if the variable node is defined by a parent node (list,
140 set, dict, or generator comprehension, lambda) or in a previous sibling 111 set, dict, or generator comprehension, lambda) or in a previous sibling
141 node on the same line (statement_defining ; statement_using) 112 node on the same line (statement_defining ; statement_using)
142 """ 113 """
143 varname = var_node.name 114 varname = var_node.name
144 _node = var_node.parent 115 _node = var_node.parent
145 while _node: 116 while _node:
146 if isinstance(_node, COMP_NODE_TYPES): 117 if isinstance(_node, COMP_NODE_TYPES):
147 for ass_node in _node.nodes_of_class(astroid.AssName): 118 for ass_node in _node.nodes_of_class(astng.AssName):
148 if ass_node.name == varname: 119 if ass_node.name == varname:
149 return True 120 return True
150 elif isinstance(_node, astroid.For): 121 elif isinstance(_node, astng.For):
151 for ass_node in _node.target.nodes_of_class(astroid.AssName): 122 for ass_node in _node.target.nodes_of_class(astng.AssName):
152 if ass_node.name == varname: 123 if ass_node.name == varname:
153 return True 124 return True
154 elif isinstance(_node, astroid.With): 125 elif isinstance(_node, astng.With):
155 for expr, vars in _node.items: 126 if _node.vars is None:
156 if expr.parent_of(var_node): 127 # quickfix : case in which 'with' is used without 'as'
157 break 128 return False
158 if (vars and 129 if _node.vars.name == varname:
159 isinstance(vars, astroid.AssName) and 130 return True
160 vars.name == varname): 131 elif isinstance(_node, (astng.Lambda, astng.Function)):
161 return True
162 elif isinstance(_node, (astroid.Lambda, astroid.Function)):
163 if _node.args.is_argument(varname): 132 if _node.args.is_argument(varname):
164 return True 133 return True
165 if getattr(_node, 'name', None) == varname: 134 if getattr(_node, 'name', None) == varname:
166 return True 135 return True
167 break 136 break
168 elif isinstance(_node, astroid.ExceptHandler):
169 if isinstance(_node.name, astroid.AssName):
170 ass_node = _node.name
171 if ass_node.name == varname:
172 return True
173 _node = _node.parent 137 _node = _node.parent
174 # possibly multiple statements on the same line using semi colon separator 138 # possibly multiple statements on the same line using semi colon separator
175 stmt = var_node.statement() 139 stmt = var_node.statement()
176 _node = stmt.previous_sibling() 140 _node = stmt.previous_sibling()
177 lineno = stmt.fromlineno 141 lineno = stmt.fromlineno
178 while _node and _node.fromlineno == lineno: 142 while _node and _node.fromlineno == lineno:
179 for ass_node in _node.nodes_of_class(astroid.AssName): 143 for ass_node in _node.nodes_of_class(astng.AssName):
180 if ass_node.name == varname: 144 if ass_node.name == varname:
181 return True 145 return True
182 for imp_node in _node.nodes_of_class((astroid.From, astroid.Import)): 146 for imp_node in _node.nodes_of_class( (astng.From, astng.Import)):
183 if varname in [name[1] or name[0] for name in imp_node.names]: 147 if varname in [name[1] or name[0] for name in imp_node.names]:
184 return True 148 return True
185 _node = _node.previous_sibling() 149 _node = _node.previous_sibling()
186 return False 150 return False
187 151
188 def is_func_default(node): 152 def is_func_default(node):
189 """return true if the given Name node is used in function default argument's 153 """return true if the given Name node is used in function default argument's
190 value 154 value
191 """ 155 """
192 parent = node.scope() 156 parent = node.scope()
193 if isinstance(parent, astroid.Function): 157 if isinstance(parent, astng.Function):
194 for default_node in parent.args.defaults: 158 for default_node in parent.args.defaults:
195 for default_name_node in default_node.nodes_of_class(astroid.Name): 159 for default_name_node in default_node.nodes_of_class(astng.Name):
196 if default_name_node is node: 160 if default_name_node is node:
197 return True 161 return True
198 return False 162 return False
199 163
200 def is_func_decorator(node): 164 def is_func_decorator(node):
201 """return true if the name is used in function decorator""" 165 """return true if the name is used in function decorator"""
202 parent = node.parent 166 parent = node.parent
203 while parent is not None: 167 while parent is not None:
204 if isinstance(parent, astroid.Decorators): 168 if isinstance(parent, astng.Decorators):
205 return True 169 return True
206 if (parent.is_statement or 170 if parent.is_statement or isinstance(parent, astng.Lambda):
207 isinstance(parent, astroid.Lambda) or
208 isinstance(parent, (scoped_nodes.ComprehensionScope,
209 scoped_nodes.ListComp))):
210 break 171 break
211 parent = parent.parent 172 parent = parent.parent
212 return False 173 return False
213 174
214 def is_ancestor_name(frame, node): 175 def is_ancestor_name(frame, node):
215 """return True if `frame` is a astroid.Class node with `node` in the 176 """return True if `frame` is a astng.Class node with `node` in the
216 subtree of its bases attribute 177 subtree of its bases attribute
217 """ 178 """
218 try: 179 try:
219 bases = frame.bases 180 bases = frame.bases
220 except AttributeError: 181 except AttributeError:
221 return False 182 return False
222 for base in bases: 183 for base in bases:
223 if node in base.nodes_of_class(astroid.Name): 184 if node in base.nodes_of_class(astng.Name):
224 return True 185 return True
225 return False 186 return False
226 187
227 def assign_parent(node): 188 def assign_parent(node):
228 """return the higher parent which is not an AssName, Tuple or List node 189 """return the higher parent which is not an AssName, Tuple or List node
229 """ 190 """
230 while node and isinstance(node, (astroid.AssName, 191 while node and isinstance(node, (astng.AssName,
231 astroid.Tuple, 192 astng.Tuple,
232 astroid.List)): 193 astng.List)):
233 node = node.parent 194 node = node.parent
234 return node 195 return node
235 196
236 def overrides_an_abstract_method(class_node, name): 197 def overrides_an_abstract_method(class_node, name):
237 """return True if pnode is a parent of node""" 198 """return True if pnode is a parent of node"""
238 for ancestor in class_node.ancestors(): 199 for ancestor in class_node.ancestors():
239 if name in ancestor and isinstance(ancestor[name], astroid.Function) and \ 200 if name in ancestor and isinstance(ancestor[name], astng.Function) and \
240 ancestor[name].is_abstract(pass_is_abstract=False): 201 ancestor[name].is_abstract(pass_is_abstract=False):
241 return True 202 return True
242 return False 203 return False
243 204
244 def overrides_a_method(class_node, name): 205 def overrides_a_method(class_node, name):
245 """return True if <name> is a method overridden from an ancestor""" 206 """return True if <name> is a method overridden from an ancestor"""
246 for ancestor in class_node.ancestors(): 207 for ancestor in class_node.ancestors():
247 if name in ancestor and isinstance(ancestor[name], astroid.Function): 208 if name in ancestor and isinstance(ancestor[name], astng.Function):
248 return True 209 return True
249 return False 210 return False
250 211
251 PYMETHODS = set(('__new__', '__init__', '__del__', '__hash__', 212 PYMETHODS = set(('__new__', '__init__', '__del__', '__hash__',
252 '__str__', '__repr__', 213 '__str__', '__repr__',
253 '__len__', '__iter__', 214 '__len__', '__iter__',
254 '__delete__', '__get__', '__set__', 215 '__delete__', '__get__', '__set__',
255 '__getitem__', '__setitem__', '__delitem__', '__contains__', 216 '__getitem__', '__setitem__', '__delitem__', '__contains__',
256 '__getattribute__', '__getattr__', '__setattr__', '__delattr__' , 217 '__getattribute__', '__getattr__', '__setattr__', '__delattr__' ,
257 '__call__', 218 '__call__',
258 '__enter__', '__exit__', 219 '__enter__', '__exit__',
259 '__cmp__', '__ge__', '__gt__', '__le__', '__lt__', '__eq__', 220 '__cmp__', '__ge__', '__gt__', '__le__', '__lt__', '__eq__',
260 '__nonzero__', '__neg__', '__invert__', 221 '__nonzero__', '__neg__', '__invert__',
261 '__mul__', '__imul__', '__rmul__', 222 '__mul__', '__imul__', '__rmul__',
262 '__div__', '__idiv__', '__rdiv__', 223 '__div__', '__idiv__', '__rdiv__',
263 '__add__', '__iadd__', '__radd__', 224 '__add__', '__iadd__', '__radd__',
264 '__sub__', '__isub__', '__rsub__', 225 '__sub__', '__isub__', '__rsub__',
265 '__pow__', '__ipow__', '__rpow__', 226 '__pow__', '__ipow__', '__rpow__',
266 '__mod__', '__imod__', '__rmod__', 227 '__mod__', '__imod__', '__rmod__',
267 '__and__', '__iand__', '__rand__', 228 '__and__', '__iand__', '__rand__',
268 '__or__', '__ior__', '__ror__', 229 '__or__', '__ior__', '__ror__',
269 '__xor__', '__ixor__', '__rxor__', 230 '__xor__', '__ixor__', '__rxor__',
270 # XXX To be continued 231 # XXX To be continued
271 )) 232 ))
272 233
273 def check_messages(*messages): 234 def check_messages(*messages):
274 """decorator to store messages that are handled by a checker method""" 235 """decorator to store messages that are handled by a checker method"""
275 236
276 def store_messages(func): 237 def store_messages(func):
277 func.checks_msgs = messages 238 func.checks_msgs = messages
278 return func 239 return func
279 return store_messages 240 return store_messages
280 241
281 class IncompleteFormatString(Exception): 242 class IncompleteFormatString(Exception):
(...skipping 15 matching lines...) Expand all
297 parse error occurs.""" 258 parse error occurs."""
298 keys = set() 259 keys = set()
299 num_args = 0 260 num_args = 0
300 def next_char(i): 261 def next_char(i):
301 i += 1 262 i += 1
302 if i == len(format_string): 263 if i == len(format_string):
303 raise IncompleteFormatString 264 raise IncompleteFormatString
304 return (i, format_string[i]) 265 return (i, format_string[i])
305 i = 0 266 i = 0
306 while i < len(format_string): 267 while i < len(format_string):
307 char = format_string[i] 268 c = format_string[i]
308 if char == '%': 269 if c == '%':
309 i, char = next_char(i) 270 i, c = next_char(i)
310 # Parse the mapping key (optional). 271 # Parse the mapping key (optional).
311 key = None 272 key = None
312 if char == '(': 273 if c == '(':
313 depth = 1 274 depth = 1
314 i, char = next_char(i) 275 i, c = next_char(i)
315 key_start = i 276 key_start = i
316 while depth != 0: 277 while depth != 0:
317 if char == '(': 278 if c == '(':
318 depth += 1 279 depth += 1
319 elif char == ')': 280 elif c == ')':
320 depth -= 1 281 depth -= 1
321 i, char = next_char(i) 282 i, c = next_char(i)
322 key_end = i - 1 283 key_end = i - 1
323 key = format_string[key_start:key_end] 284 key = format_string[key_start:key_end]
324 285
325 # Parse the conversion flags (optional). 286 # Parse the conversion flags (optional).
326 while char in '#0- +': 287 while c in '#0- +':
327 i, char = next_char(i) 288 i, c = next_char(i)
328 # Parse the minimum field width (optional). 289 # Parse the minimum field width (optional).
329 if char == '*': 290 if c == '*':
330 num_args += 1 291 num_args += 1
331 i, char = next_char(i) 292 i, c = next_char(i)
332 else: 293 else:
333 while char in string.digits: 294 while c in string.digits:
334 i, char = next_char(i) 295 i, c = next_char(i)
335 # Parse the precision (optional). 296 # Parse the precision (optional).
336 if char == '.': 297 if c == '.':
337 i, char = next_char(i) 298 i, c = next_char(i)
338 if char == '*': 299 if c == '*':
339 num_args += 1 300 num_args += 1
340 i, char = next_char(i) 301 i, c = next_char(i)
341 else: 302 else:
342 while char in string.digits: 303 while c in string.digits:
343 i, char = next_char(i) 304 i, c = next_char(i)
344 # Parse the length modifier (optional). 305 # Parse the length modifier (optional).
345 if char in 'hlL': 306 if c in 'hlL':
346 i, char = next_char(i) 307 i, c = next_char(i)
347 # Parse the conversion type (mandatory). 308 # Parse the conversion type (mandatory).
348 if PY3K: 309 if c not in 'diouxXeEfFgGcrs%':
349 flags = 'diouxXeEfFgGcrs%a'
350 else:
351 flags = 'diouxXeEfFgGcrs%'
352 if char not in flags:
353 raise UnsupportedFormatCharacter(i) 310 raise UnsupportedFormatCharacter(i)
354 if key: 311 if key:
355 keys.add(key) 312 keys.add(key)
356 elif char != '%': 313 elif c != '%':
357 num_args += 1 314 num_args += 1
358 i += 1 315 i += 1
359 return keys, num_args 316 return keys, num_args
360
361
362 def is_attr_protected(attrname):
363 """return True if attribute name is protected (start with _ and some other
364 details), False otherwise.
365 """
366 return attrname[0] == '_' and not attrname == '_' and not (
367 attrname.startswith('__') and attrname.endswith('__'))
368
369 def node_frame_class(node):
370 """return klass node for a method node (or a staticmethod or a
371 classmethod), return null otherwise
372 """
373 klass = node.frame()
374
375 while klass is not None and not isinstance(klass, astroid.Class):
376 if klass.parent is None:
377 klass = None
378 else:
379 klass = klass.parent.frame()
380
381 return klass
382
383 def is_super_call(expr):
384 """return True if expression node is a function call and if function name
385 is super. Check before that you're in a method.
386 """
387 return (isinstance(expr, astroid.CallFunc) and
388 isinstance(expr.func, astroid.Name) and
389 expr.func.name == 'super')
390
391 def is_attr_private(attrname):
392 """Check that attribute name is private (at least two leading underscores,
393 at most one trailing underscore)
394 """
395 regex = re.compile('^_{2,}.*[^_]+_?$')
396 return regex.match(attrname)
397
398 def get_argument_from_call(callfunc_node, position=None, keyword=None):
399 """Returns the specified argument from a function call.
400
401 :param callfunc_node: Node representing a function call to check.
402 :param int position: position of the argument.
403 :param str keyword: the keyword of the argument.
404
405 :returns: The node representing the argument, None if the argument is not fo und.
406 :raises ValueError: if both position and keyword are None.
407 :raises NoSuchArgumentError: if no argument at the provided position or with
408 the provided keyword.
409 """
410 if position is None and keyword is None:
411 raise ValueError('Must specify at least one of: position or keyword.')
412 try:
413 if position is not None and not isinstance(callfunc_node.args[position], astroid.Keyword):
414 return callfunc_node.args[position]
415 except IndexError, error:
416 raise NoSuchArgumentError(error)
417 if keyword:
418 for arg in callfunc_node.args:
419 if isinstance(arg, astroid.Keyword) and arg.arg == keyword:
420 return arg.value
421 raise NoSuchArgumentError
OLDNEW
« no previous file with comments | « third_party/pylint/checkers/typecheck.py ('k') | third_party/pylint/checkers/variables.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698