1
1
# pylint: disable-msg=W0611
3
# Copyright (c) 2003-2007 LOGILAB S.A. (Paris, FRANCE).
3
# Copyright (c) 2003-2009 LOGILAB S.A. (Paris, FRANCE).
4
4
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
6
6
# This program is free software; you can redistribute it and/or modify it under
18
18
"""some functions that may be usefull for various checkers
21
from logilab.common import flatten
23
21
from logilab import astng
24
from logilab.astng.utils import are_exclusive
27
25
COMP_NODE_TYPES = (astng.ListComp, astng.GenExpr)
28
FOR_NODE_TYPES = (astng.For, astng.ListCompFor, astng.GenExprFor)
26
FOR_NODE_TYPES = (astng.For, astng.Comprehension, astng.Comprehension)
29
27
except AttributeError:
30
28
COMP_NODE_TYPES = astng.ListComp
31
FOR_NODE_TYPES = (astng.For, astng.ListCompFor)
29
FOR_NODE_TYPES = (astng.For, astng.Comprehension)
33
31
def safe_infer(node):
34
32
"""return the infered value for the given node.
57
55
def is_error(node):
58
56
"""return true if the function does nothing but raising an exception"""
59
for child_node in node.code.getChildNodes():
57
for child_node in node.get_children():
60
58
if isinstance(child_node, astng.Raise):
65
"""return true if the given statement node raise an exception
67
for node in stmt.nodes:
63
"""return true if the given statement node raise an exception"""
68
65
if isinstance(node, astng.Raise):
73
70
"""return true if the given node does nothing but 'pass'"""
74
children = node.getChildNodes()
75
return len(children) == 1 and isinstance(children[0], astng.Pass)
71
return len(body) == 1 and isinstance(body[0], astng.Pass)
77
73
builtins = __builtins__.copy()
78
74
SPECIAL_BUILTINS = ('__builtins__',) # '__path__', '__file__')
99
95
if ass_node.name == varname:
101
97
elif isinstance(_node, astng.For):
102
for ass_node in _node.assign.nodes_of_class(astng.AssName):
98
for ass_node in _node.target.nodes_of_class(astng.AssName):
103
99
if ass_node.name == varname:
105
101
elif isinstance(_node, astng.With):
106
102
if _node.vars.name == varname:
108
104
elif isinstance(_node, (astng.Lambda, astng.Function)):
109
if varname in flatten(_node.argnames):
105
if _node.args.is_argument(varname):
111
107
if getattr(_node, 'name', None) == varname:
115
111
# possibly multiple statements on the same line using semi colon separator
116
112
stmt = var_node.statement()
117
113
_node = stmt.previous_sibling()
119
while _node and _node.lineno == lineno:
114
lineno = stmt.fromlineno
115
while _node and _node.fromlineno == lineno:
120
116
for ass_node in _node.nodes_of_class(astng.AssName):
121
117
if ass_node.name == varname:
129
125
def is_func_default(node):
130
"""return true if the name is used in function default argument's value
126
"""return true if the given Name node is used in function default argument's
135
if isinstance(parent, astng.Function) and parent.defaults and \
136
node in parent.defaults:
138
return is_func_default(parent)
129
parent = node.scope()
130
if isinstance(parent, astng.Function):
131
for default_node in parent.args.defaults:
132
for default_name_node in default_node.nodes_of_class(astng.Name):
133
if default_name_node is node:
140
137
def is_func_decorator(node):
141
"""return true if the name is used in function decorator
138
"""return true if the name is used in function decorator"""
143
139
parent = node.parent
146
if isinstance(parent, astng.Decorators):
148
return is_func_decorator(parent)
140
while parent is not None:
141
if isinstance(parent, astng.Decorators):
143
if parent.is_statement:
145
parent = parent.parent
150
148
def is_ancestor_name(frame, node):
151
149
"""return True if `frame` is a astng.Class node with `node` in the
163
161
def assign_parent(node):
164
"""return the higher parent which is not an AssName, AssTuple or AssList
162
"""return the higher parent which is not an AssName, Tuple or List node
167
164
while node and isinstance(node, (astng.AssName,
170
167
node = node.parent
192
189
elif isinstance(node, astng.Module):
193
PYMETHODS = set(('__new__', '__init__',
194
'__len__', '__iter__',
195
'__getitem__', '__setitem__', '__delitem__',
196
'__getattribute__', '__getattr__', '__setattr__', '__delattr__',
197
'__cmp__', '__ge__', '__gt__', '__le__', '__lt__', '__eq__',
199
'__mul__', '__imul__', '__rmul__',
200
'__div__', '__idiv__', '__rdiv__',
201
'__add__', '__iadd__', '__radd__',
202
'__sub__', '__isub__', '__rsub__',
203
'__pow__', '__ipow__', '__rpow__',
204
'__mod__', '__imod__', '__rmod__',
205
# XXX To be continued