1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
from pylint.__pkginfo__ import version as pylint_version
try:
from logilab.astng.__pkginfo__ import version as astng_version
except ImportError:
from astroid.__pkginfo__ import version as astng_version
def register(linter):
if pylint_version < '0.24.0':
import pylint.utils
orig_check_message_id = pylint.utils.MessagesHandlerMixIn.check_message_id
def check_message_id(self, msgid):
# translate the new message ids back into the old ones
replacements = {'12': '65', '13': '99'}
new = msgid[1:3]
if new in replacements:
msgid = msgid[0] + replacements[new] + msgid[3:]
return orig_check_message_id(self, msgid)
pylint.utils.MessagesHandlerMixIn.check_message_id = check_message_id
def ignore(meth, msgid, *args, **kwargs):
# ignore non-existent message ids in disable/enable comments
ignore = ['W1401', 'R0924']
if msgid in ignore:
return
return meth(msgid, *args, **kwargs)
linter._options_methods['disable'] = lambda *args, **kwargs: ignore(linter.disable, *args, **kwargs)
linter._options_methods['enable'] = lambda *args, **kwargs: ignore(linter.enable, *args, **kwargs)
if pylint_version < '0.22.0':
import pylint.checkers.exceptions
orig_visit_raise = pylint.checkers.exceptions.ExceptionsChecker.visit_raise
def visit_raise(self, node):
if not hasattr(node, 'type') and hasattr(node, 'exc'):
node.type = node.exc
return orig_visit_raise(self, node)
pylint.checkers.exceptions.ExceptionsChecker.visit_raise = visit_raise
if astng_version < '0.23':
import logilab.astng.scoped_nodes
from logilab.astng.bases import InferenceContext, InferenceError
# backport import bug fix (e642ba33ba1bdde04ac9f0c75a25dc40131c55e7)
def ancestors(self, recurs=True, context=None):
yielded = set([self])
if context is None:
context = InferenceContext()
for stmt in self.bases:
path = set(context.path)
try:
for baseobj in stmt.infer(context):
if not isinstance(baseobj, logilab.astng.scoped_nodes.Class):
# duh ?
continue
if baseobj in yielded:
continue # cf xxx above
yielded.add(baseobj)
yield baseobj
if recurs:
for grandpa in baseobj.ancestors(True, context):
if grandpa in yielded:
continue # cf xxx above
yielded.add(grandpa)
yield grandpa
except InferenceError:
# XXX log error ?
pass
context.path = path
logilab.astng.scoped_nodes.Class.ancestors = ancestors
# support for classpropery (d110bcf2de4b8bc48e41638cf430f17c5714ffbc)
try:
from logilab.astng.rebuilder import TreeRebuilder
except:
try:
from logilab.astng._nodes_ast import TreeRebuilder
except:
from logilab.astng._nodes_compiler import TreeRebuilder
from logilab.astng import nodes
orig_visit_function = TreeRebuilder.visit_function
def visit_function(self, node, parent):
newnode = orig_visit_function(self, node, parent)
if newnode.decorators is not None:
for decorator_expr in newnode.decorators.nodes:
if isinstance(decorator_expr, nodes.Name):
if decorator_expr.name == 'classproperty':
newnode.type = 'classmethod'
return newnode
TreeRebuilder.visit_function = visit_function
if astng_version < '0.22':
from logilab.astng import nodes
from logilab.astng.bases import _infer_stmts, copy_context, path_wrapper, \
InferenceError, NotFoundError
from logilab.astng._exceptions import ASTNGBuildingException
import logilab.astng.scoped_nodes
from logilab.astng.node_classes import List, DelName
# backport of 11886551cfdcf969f0a661f8ab63c1fa1a6dd399 with
# a bit revert of af896e299ce5e381a928a77a9c28941cad90a243
def infer_from(self, context=None, asname=True):
name = context.lookupname
if name is None:
raise InferenceError()
if asname:
name = self.real_name(name)
module = self.do_import_module(self.modname)
try:
context = copy_context(context)
context.lookupname = name
return _infer_stmts(module.getattr(name, ignore_locals=module is self.root()), context)
except NotFoundError:
raise InferenceError(name)
nodes.From.infer = path_wrapper(infer_from)
def getattr(self, name, context=None, ignore_locals=False):
if name in self.special_attributes:
if name == '__file__':
return [cf(self.file)] + self.locals.get(name, [])
if name == '__path__' and self.package:
return [List()] + self.locals.get(name, [])
return std_special_attributes(self, name)
if not ignore_locals and name in self.locals:
return self.locals[name]
if self.package:
try:
return [self.import_module(name, relative_only=True)]
except (KeyboardInterrupt, SystemExit):
raise
except:
pass
raise NotFoundError(name)
logilab.astng.scoped_nodes.Module.getattr = logilab.astng.scoped_nodes.remove_nodes(getattr, DelName)
if astng_version < '0.21.1':
# backport of 3d463da455e33e7ddc53a295b6a33db7b9e4288b
from logilab.astng.scoped_nodes import Function
from logilab.astng.rebuilder import RebuildVisitor
from logilab.astng.bases import YES, Instance
orig_init = Function.__init__
def init(self, name, doc):
orig_init(self, name, doc)
self.instance_attrs = {}
Function.__init__ = init
orig_getattr = Function.getattr
def getattr(self, name, context=None):
if name != '__module__' and name in self.instance_attrs:
return self.instance_attrs[name]
return orig_getattr(self, name, context)
Function.getattr = getattr
def delayed_assattr(self, node):
"""visit a AssAttr node -> add name to locals, handle members
definition
"""
try:
frame = node.frame()
for infered in node.expr.infer():
if infered is YES:
continue
try:
if infered.__class__ is Instance:
infered = infered._proxied
iattrs = infered.instance_attrs
elif isinstance(infered, Instance):
# Const, Tuple, ... we may be wrong, may be not, but
# anyway we don't want to pollute builtin's namespace
continue
elif infered.is_function:
iattrs = infered.instance_attrs
else:
iattrs = infered.locals
except AttributeError:
# XXX log error
#import traceback
#traceback.print_exc()
continue
values = iattrs.setdefault(node.attrname, [])
if node in values:
continue
# get assign in __init__ first XXX useful ?
if frame.name == '__init__' and values and not \
values[0].frame().name == '__init__':
values.insert(0, node)
else:
values.append(node)
except InferenceError:
pass
RebuildVisitor.delayed_assattr = delayed_assattr
if astng_version < '0.20.4':
try:
from logilab.astng._nodes_ast import TreeRebuilder, _lineno_parent
except:
from logilab.astng._nodes_compiler import TreeRebuilder
_lineno_parent = (lambda *args: TreeRebuilder._set_infos(None, *args))
from logilab.astng import nodes
from logilab.astng.bases import NodeNG, Instance
from logilab.astng.mixins import ParentAssignTypeMixin
class Set(NodeNG, Instance, ParentAssignTypeMixin):
_astng_fields = ('elts',)
elts = None
def pytype(self):
return '__builtin__.set'
def itered(self):
return self.elts
def visit_set(self, node, parent):
newnode = Set()
_lineno_parent(node, newnode, parent)
newnode.elts = [self.visit(child, newnode) for child in node.elts]
newnode.set_line_info(newnode.last_child())
return newnode
TreeRebuilder.visit_set = visit_set
def visit_setcomp(self, node, parent):
newnode = nodes.SetComp()
_lineno_parent(node, newnode, parent)
newnode.elt = self.visit(node.elt, newnode)
newnode.generators = [self.visit(child, newnode)
for child in node.generators]
newnode.set_line_info(newnode.last_child())
return newnode
TreeRebuilder.visit_setcomp = visit_setcomp
class DictComp(NodeNG):
_astng_fields = ('key', 'value', 'generators')
key = None
value = None
generators = None
def visit_dictcomp(self, node, parent):
newnode = DictComp()
_lineno_parent(node, newnode, parent)
newnode.key = self.visit(node.key, newnode)
newnode.value = self.visit(node.value, newnode)
newnode.generators = [self.visit(child, newnode)
for child in node.generators]
newnode.set_line_info(newnode.last_child())
return newnode
TreeRebuilder.visit_dictcomp = visit_dictcomp
# backport of bfe9e5c53cfb75c3b45ebb5cb8e8902464782c7d
from logilab.astng.node_classes import From
orig_from_init = From.__init__
def from_init(self, fromname, names, level=0):
orig_from_init(self, fromname or '', names, level)
From.__init__ = from_init
# partial backport of 6d59ad07d722d01e458aaf8fd14fd7dfc7ebaa6e
from logilab.astng.scoped_nodes import Module
orig_absolute_modname = Module.absolute_modname
def absolute_modname(self, modname, level):
result = orig_absolute_modname(self, modname, level)
if result[-1] == '.':
return result[:-1]
return result
Module.absolute_modname = absolute_modname
# python2.4 compatibility (no super on old-style classes)
from logilab.astng.bases import Proxy, UnboundMethod
def unbound_igetattr(self, name, context=None):
if name == 'im_func':
return iter((self._proxied,))
return Proxy.igetattr(self, name, context)
UnboundMethod.igetattr = unbound_igetattr
def unbound_getattr(self, name, context=None):
if name == 'im_func':
return [self._proxied]
return Proxy.getattr(self, name, context)
UnboundMethod.getattr = unbound_getattr
|