OLD | NEW |
1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. | 1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr | 2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
| 3 # copyright 2003-2010 Sylvain Thenault, all rights reserved. |
| 4 # contact mailto:thenault@gmail.com |
3 # | 5 # |
4 # This file is part of astroid. | 6 # This file is part of logilab-astng. |
5 # | 7 # |
6 # astroid is free software: you can redistribute it and/or modify it | 8 # logilab-astng is free software: you can redistribute it and/or modify it |
7 # under the terms of the GNU Lesser General Public License as published by the | 9 # under the terms of the GNU Lesser General Public License as published by the |
8 # Free Software Foundation, either version 2.1 of the License, or (at your | 10 # Free Software Foundation, either version 2.1 of the License, or (at your |
9 # option) any later version. | 11 # option) any later version. |
10 # | 12 # |
11 # astroid is distributed in the hope that it will be useful, but | 13 # logilab-astng is distributed in the hope that it will be useful, but |
12 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 14 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | 15 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License |
14 # for more details. | 16 # for more details. |
15 # | 17 # |
16 # You should have received a copy of the GNU Lesser General Public License along | 18 # You should have received a copy of the GNU Lesser General Public License along |
17 # with astroid. If not, see <http://www.gnu.org/licenses/>. | 19 # with logilab-astng. If not, see <http://www.gnu.org/licenses/>. |
18 """this module contains a set of functions to handle inference on astroid trees | 20 """this module contains a set of functions to handle inference on astng trees |
19 """ | 21 """ |
20 | 22 |
21 __doctype__ = "restructuredtext en" | 23 __doctype__ = "restructuredtext en" |
22 | 24 |
23 from itertools import chain | 25 from itertools import chain |
| 26 import sys |
24 | 27 |
25 from astroid import nodes | 28 from logilab.astng import nodes |
26 | 29 |
27 from astroid.manager import AstroidManager | 30 from logilab.astng.manager import ASTNGManager |
28 from astroid.exceptions import (AstroidError, InferenceError, NoDefault, | 31 from logilab.astng.exceptions import (ASTNGBuildingException, ASTNGError, |
29 NotFoundError, UnresolvableName) | 32 InferenceError, NoDefault, NotFoundError, UnresolvableName) |
30 from astroid.bases import (YES, Instance, InferenceContext, | 33 from logilab.astng.bases import YES, Instance, InferenceContext, Generator, \ |
31 _infer_stmts, copy_context, path_wrapper, | 34 _infer_stmts, copy_context, path_wrapper, raise_if_nothing_infered |
32 raise_if_nothing_infered) | 35 from logilab.astng.protocols import _arguments_infer_argname |
33 from astroid.protocols import ( | |
34 _arguments_infer_argname, | |
35 BIN_OP_METHOD, UNARY_OP_METHOD) | |
36 | 36 |
37 MANAGER = AstroidManager() | 37 MANAGER = ASTNGManager() |
38 | 38 |
39 | 39 |
40 class CallContext(object): | 40 class CallContext: |
41 """when inferring a function call, this class is used to remember values | 41 """when inferring a function call, this class is used to remember values |
42 given as argument | 42 given as argument |
43 """ | 43 """ |
44 def __init__(self, args, starargs, dstarargs): | 44 def __init__(self, args, starargs, dstarargs): |
45 self.args = [] | 45 self.args = [] |
46 self.nargs = {} | 46 self.nargs = {} |
47 for arg in args: | 47 for arg in args: |
48 if isinstance(arg, nodes.Keyword): | 48 if isinstance(arg, nodes.Keyword): |
49 self.nargs[arg.arg] = arg.value | 49 self.nargs[arg.arg] = arg.value |
50 else: | 50 else: |
51 self.args.append(arg) | 51 self.args.append(arg) |
52 self.starargs = starargs | 52 self.starargs = starargs |
53 self.dstarargs = dstarargs | 53 self.dstarargs = dstarargs |
54 | 54 |
55 def infer_argument(self, funcnode, name, context): | 55 def infer_argument(self, funcnode, name, context): |
56 """infer a function argument value according to the call context""" | 56 """infer a function argument value according to the call context""" |
57 # 1. search in named keywords | 57 # 1. search in named keywords |
58 try: | 58 try: |
59 return self.nargs[name].infer(context) | 59 return self.nargs[name].infer(context) |
60 except KeyError: | 60 except KeyError: |
61 # Function.args.args can be None in astroid (means that we don't hav
e | 61 # Function.args.args can be None in astng (means that we don't have |
62 # information on argnames) | 62 # information on argnames) |
63 argindex = funcnode.args.find_argname(name)[0] | 63 argindex = funcnode.args.find_argname(name)[0] |
64 if argindex is not None: | 64 if argindex is not None: |
65 # 2. first argument of instance/class method | 65 # 2. first argument of instance/class method |
66 if argindex == 0 and funcnode.type in ('method', 'classmethod'): | 66 if argindex == 0 and funcnode.type in ('method', 'classmethod'): |
67 if context.boundnode is not None: | 67 if context.boundnode is not None: |
68 boundnode = context.boundnode | 68 boundnode = context.boundnode |
69 else: | 69 else: |
70 # XXX can do better ? | 70 # XXX can do better ? |
71 boundnode = funcnode.parent.frame() | 71 boundnode = funcnode.parent.frame() |
72 if funcnode.type == 'method': | 72 if funcnode.type == 'method': |
73 if not isinstance(boundnode, Instance): | 73 if not isinstance(boundnode, Instance): |
74 boundnode = Instance(boundnode) | 74 boundnode = Instance(boundnode) |
75 return iter((boundnode,)) | 75 return iter((boundnode,)) |
76 if funcnode.type == 'classmethod': | 76 if funcnode.type == 'classmethod': |
77 return iter((boundnode,)) | 77 return iter((boundnode,)) |
78 # if we have a method, extract one position | |
79 # from the index, so we'll take in account | |
80 # the extra parameter represented by `self` or `cls` | |
81 if funcnode.type in ('method', 'classmethod'): | |
82 argindex -= 1 | |
83 # 2. search arg index | 78 # 2. search arg index |
84 try: | 79 try: |
85 return self.args[argindex].infer(context) | 80 return self.args[argindex].infer(context) |
86 except IndexError: | 81 except IndexError: |
87 pass | 82 pass |
88 # 3. search in *args (.starargs) | 83 # 3. search in *args (.starargs) |
89 if self.starargs is not None: | 84 if self.starargs is not None: |
90 its = [] | 85 its = [] |
91 for infered in self.starargs.infer(context): | 86 for infered in self.starargs.infer(context): |
92 if infered is YES: | 87 if infered is YES: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 raise InferenceError(name) | 122 raise InferenceError(name) |
128 | 123 |
129 | 124 |
130 # .infer method ############################################################### | 125 # .infer method ############################################################### |
131 | 126 |
132 | 127 |
133 def infer_end(self, context=None): | 128 def infer_end(self, context=None): |
134 """inference's end for node such as Module, Class, Function, Const... | 129 """inference's end for node such as Module, Class, Function, Const... |
135 """ | 130 """ |
136 yield self | 131 yield self |
137 nodes.Module._infer = infer_end | 132 nodes.Module.infer = infer_end |
138 nodes.Class._infer = infer_end | 133 nodes.Class.infer = infer_end |
139 nodes.Function._infer = infer_end | 134 nodes.Function.infer = infer_end |
140 nodes.Lambda._infer = infer_end | 135 nodes.Lambda.infer = infer_end |
141 nodes.Const._infer = infer_end | 136 nodes.Const.infer = infer_end |
142 nodes.List._infer = infer_end | 137 nodes.List.infer = infer_end |
143 nodes.Tuple._infer = infer_end | 138 nodes.Tuple.infer = infer_end |
144 nodes.Dict._infer = infer_end | 139 nodes.Dict.infer = infer_end |
145 nodes.Set._infer = infer_end | |
146 | 140 |
147 def _higher_function_scope(node): | |
148 """ Search for the first function which encloses the given | |
149 scope. This can be used for looking up in that function's | |
150 scope, in case looking up in a lower scope for a particular | |
151 name fails. | |
152 | |
153 :param node: A scope node. | |
154 :returns: | |
155 ``None``, if no parent function scope was found, | |
156 otherwise an instance of :class:`astroid.scoped_nodes.Function`, | |
157 which encloses the given node. | |
158 """ | |
159 current = node | |
160 while current.parent and not isinstance(current.parent, nodes.Function): | |
161 current = current.parent | |
162 if current and current.parent: | |
163 return current.parent | |
164 | 141 |
165 def infer_name(self, context=None): | 142 def infer_name(self, context=None): |
166 """infer a Name: use name lookup rules""" | 143 """infer a Name: use name lookup rules""" |
167 frame, stmts = self.lookup(self.name) | 144 frame, stmts = self.lookup(self.name) |
168 if not stmts: | 145 if not stmts: |
169 # Try to see if the name is enclosed in a nested function | 146 raise UnresolvableName(self.name) |
170 # and use the higher (first function) scope for searching. | |
171 # TODO: should this be promoted to other nodes as well? | |
172 parent_function = _higher_function_scope(self.scope()) | |
173 if parent_function: | |
174 _, stmts = parent_function.lookup(self.name) | |
175 | |
176 if not stmts: | |
177 raise UnresolvableName(self.name) | |
178 context = context.clone() | 147 context = context.clone() |
179 context.lookupname = self.name | 148 context.lookupname = self.name |
180 return _infer_stmts(stmts, context, frame) | 149 return _infer_stmts(stmts, context, frame) |
181 nodes.Name._infer = path_wrapper(infer_name) | 150 nodes.Name.infer = path_wrapper(infer_name) |
182 nodes.AssName.infer_lhs = infer_name # won't work with a path wrapper | 151 nodes.AssName.infer_lhs = infer_name # won't work with a path wrapper |
183 | 152 |
184 | 153 |
185 def infer_callfunc(self, context=None): | 154 def infer_callfunc(self, context=None): |
186 """infer a CallFunc node by trying to guess what the function returns""" | 155 """infer a CallFunc node by trying to guess what the function returns""" |
187 callcontext = context.clone() | 156 callcontext = context.clone() |
188 callcontext.callcontext = CallContext(self.args, self.starargs, self.kwargs) | 157 callcontext.callcontext = CallContext(self.args, self.starargs, self.kwargs) |
189 callcontext.boundnode = None | 158 callcontext.boundnode = None |
190 for callee in self.func.infer(context): | 159 for callee in self.func.infer(context): |
191 if callee is YES: | 160 if callee is YES: |
192 yield callee | 161 yield callee |
193 continue | 162 continue |
194 try: | 163 try: |
195 if hasattr(callee, 'infer_call_result'): | 164 if hasattr(callee, 'infer_call_result'): |
196 for infered in callee.infer_call_result(self, callcontext): | 165 for infered in callee.infer_call_result(self, callcontext): |
197 yield infered | 166 yield infered |
198 except InferenceError: | 167 except InferenceError: |
199 ## XXX log error ? | 168 ## XXX log error ? |
200 continue | 169 continue |
201 nodes.CallFunc._infer = path_wrapper(raise_if_nothing_infered(infer_callfunc)) | 170 nodes.CallFunc.infer = path_wrapper(raise_if_nothing_infered(infer_callfunc)) |
202 | 171 |
203 | 172 |
204 def infer_import(self, context=None, asname=True): | 173 def infer_import(self, context=None, asname=True): |
205 """infer an Import node: return the imported module/object""" | 174 """infer an Import node: return the imported module/object""" |
206 name = context.lookupname | 175 name = context.lookupname |
207 if name is None: | 176 if name is None: |
208 raise InferenceError() | 177 raise InferenceError() |
209 if asname: | 178 if asname: |
210 yield self.do_import_module(self.real_name(name)) | 179 yield self.do_import_module(self.real_name(name)) |
211 else: | 180 else: |
212 yield self.do_import_module(name) | 181 yield self.do_import_module(name) |
213 nodes.Import._infer = path_wrapper(infer_import) | 182 nodes.Import.infer = path_wrapper(infer_import) |
214 | 183 |
215 def infer_name_module(self, name): | 184 def infer_name_module(self, name): |
216 context = InferenceContext() | 185 context = InferenceContext() |
217 context.lookupname = name | 186 context.lookupname = name |
218 return self.infer(context, asname=False) | 187 return self.infer(context, asname=False) |
219 nodes.Import.infer_name_module = infer_name_module | 188 nodes.Import.infer_name_module = infer_name_module |
220 | 189 |
221 | 190 |
222 def infer_from(self, context=None, asname=True): | 191 def infer_from(self, context=None, asname=True): |
223 """infer a From nodes: return the imported module/object""" | 192 """infer a From nodes: return the imported module/object""" |
224 name = context.lookupname | 193 name = context.lookupname |
225 if name is None: | 194 if name is None: |
226 raise InferenceError() | 195 raise InferenceError() |
227 if asname: | 196 if asname: |
228 name = self.real_name(name) | 197 name = self.real_name(name) |
229 module = self.do_import_module() | 198 module = self.do_import_module(self.modname) |
230 try: | 199 try: |
231 context = copy_context(context) | 200 context = copy_context(context) |
232 context.lookupname = name | 201 context.lookupname = name |
233 return _infer_stmts(module.getattr(name, ignore_locals=module is self.ro
ot()), context) | 202 return _infer_stmts(module.getattr(name, ignore_locals=module is self.ro
ot()), context) |
234 except NotFoundError: | 203 except NotFoundError: |
235 raise InferenceError(name) | 204 raise InferenceError(name) |
236 nodes.From._infer = path_wrapper(infer_from) | 205 nodes.From.infer = path_wrapper(infer_from) |
237 | 206 |
238 | 207 |
239 def infer_getattr(self, context=None): | 208 def infer_getattr(self, context=None): |
240 """infer a Getattr node by using getattr on the associated object""" | 209 """infer a Getattr node by using getattr on the associated object""" |
241 #context = context.clone() | 210 #context = context.clone() |
242 for owner in self.expr.infer(context): | 211 for owner in self.expr.infer(context): |
243 if owner is YES: | 212 if owner is YES: |
244 yield owner | 213 yield owner |
245 continue | 214 continue |
246 try: | 215 try: |
247 context.boundnode = owner | 216 context.boundnode = owner |
248 for obj in owner.igetattr(self.attrname, context): | 217 for obj in owner.igetattr(self.attrname, context): |
249 yield obj | 218 yield obj |
250 context.boundnode = None | 219 context.boundnode = None |
251 except (NotFoundError, InferenceError): | 220 except (NotFoundError, InferenceError): |
252 context.boundnode = None | 221 context.boundnode = None |
253 except AttributeError: | 222 except AttributeError: |
254 # XXX method / function | 223 # XXX method / function |
255 context.boundnode = None | 224 context.boundnode = None |
256 nodes.Getattr._infer = path_wrapper(raise_if_nothing_infered(infer_getattr)) | 225 nodes.Getattr.infer = path_wrapper(raise_if_nothing_infered(infer_getattr)) |
257 nodes.AssAttr.infer_lhs = raise_if_nothing_infered(infer_getattr) # # won't work
with a path wrapper | 226 nodes.AssAttr.infer_lhs = raise_if_nothing_infered(infer_getattr) # # won't work
with a path wrapper |
258 | 227 |
259 | 228 |
260 def infer_global(self, context=None): | 229 def infer_global(self, context=None): |
261 if context.lookupname is None: | 230 if context.lookupname is None: |
262 raise InferenceError() | 231 raise InferenceError() |
263 try: | 232 try: |
264 return _infer_stmts(self.root().getattr(context.lookupname), context) | 233 return _infer_stmts(self.root().getattr(context.lookupname), context) |
265 except NotFoundError: | 234 except NotFoundError: |
266 raise InferenceError() | 235 raise InferenceError() |
267 nodes.Global._infer = path_wrapper(infer_global) | 236 nodes.Global.infer = path_wrapper(infer_global) |
268 | 237 |
269 | 238 |
270 def infer_subscript(self, context=None): | 239 def infer_subscript(self, context=None): |
271 """infer simple subscription such as [1,2,3][0] or (1,2,3)[-1]""" | 240 """infer simple subscription such as [1,2,3][0] or (1,2,3)[-1]""" |
272 value = self.value.infer(context).next() | 241 if isinstance(self.slice, nodes.Index): |
273 if value is YES: | 242 index = self.slice.value.infer(context).next() |
274 yield YES | 243 if index is YES: |
275 return | 244 yield YES |
276 | 245 return |
277 index = self.slice.infer(context).next() | |
278 if index is YES: | |
279 yield YES | |
280 return | |
281 | |
282 if isinstance(index, nodes.Const): | |
283 try: | 246 try: |
284 assigned = value.getitem(index.value, context) | 247 # suppose it's a Tuple/List node (attribute error else) |
| 248 assigned = self.value.getitem(index.value, context) |
285 except AttributeError: | 249 except AttributeError: |
286 raise InferenceError() | 250 raise InferenceError() |
287 except (IndexError, TypeError): | 251 except (IndexError, TypeError): |
288 yield YES | 252 yield YES |
289 return | 253 return |
290 for infered in assigned.infer(context): | 254 for infered in assigned.infer(context): |
291 yield infered | 255 yield infered |
292 else: | 256 else: |
293 raise InferenceError() | 257 raise InferenceError() |
294 nodes.Subscript._infer = path_wrapper(infer_subscript) | 258 nodes.Subscript.infer = path_wrapper(infer_subscript) |
295 nodes.Subscript.infer_lhs = raise_if_nothing_infered(infer_subscript) | 259 nodes.Subscript.infer_lhs = raise_if_nothing_infered(infer_subscript) |
296 | 260 |
| 261 |
| 262 UNARY_OP_METHOD = {'+': '__pos__', |
| 263 '-': '__neg__', |
| 264 '~': '__invert__', |
| 265 'not': None, # XXX not '__nonzero__' |
| 266 } |
| 267 |
297 def infer_unaryop(self, context=None): | 268 def infer_unaryop(self, context=None): |
298 for operand in self.operand.infer(context): | 269 for operand in self.operand.infer(context): |
299 try: | 270 try: |
300 yield operand.infer_unary_op(self.op) | 271 yield operand.infer_unary_op(self.op) |
301 except TypeError: | 272 except TypeError: |
302 continue | 273 continue |
303 except AttributeError: | 274 except AttributeError: |
304 meth = UNARY_OP_METHOD[self.op] | 275 meth = UNARY_OP_METHOD[self.op] |
305 if meth is None: | 276 if meth is None: |
306 yield YES | 277 yield YES |
307 else: | 278 else: |
308 try: | 279 try: |
309 # XXX just suppose if the type implement meth, returned type | 280 # XXX just suppose if the type implement meth, returned type |
310 # will be the same | 281 # will be the same |
311 operand.getattr(meth) | 282 operand.getattr(meth) |
312 yield operand | 283 yield operand |
313 except GeneratorExit: | 284 except GeneratorExit: |
314 raise | 285 raise |
315 except: | 286 except: |
316 yield YES | 287 yield YES |
317 nodes.UnaryOp._infer = path_wrapper(infer_unaryop) | 288 nodes.UnaryOp.infer = path_wrapper(infer_unaryop) |
| 289 |
| 290 |
| 291 BIN_OP_METHOD = {'+': '__add__', |
| 292 '-': '__sub__', |
| 293 '/': '__div__', |
| 294 '//': '__floordiv__', |
| 295 '*': '__mul__', |
| 296 '**': '__power__', |
| 297 '%': '__mod__', |
| 298 '&': '__and__', |
| 299 '|': '__or__', |
| 300 '^': '__xor__', |
| 301 '<<': '__lshift__', |
| 302 '>>': '__rshift__', |
| 303 } |
318 | 304 |
319 def _infer_binop(operator, operand1, operand2, context, failures=None): | 305 def _infer_binop(operator, operand1, operand2, context, failures=None): |
320 if operand1 is YES: | 306 if operand1 is YES: |
321 yield operand1 | 307 yield operand1 |
322 return | 308 return |
323 try: | 309 try: |
324 for valnode in operand1.infer_binary_op(operator, operand2, context): | 310 for valnode in operand1.infer_binary_op(operator, operand2, context): |
325 yield valnode | 311 yield valnode |
326 except AttributeError: | 312 except AttributeError: |
327 try: | 313 try: |
328 # XXX just suppose if the type implement meth, returned type | 314 # XXX just suppose if the type implement meth, returned type |
329 # will be the same | 315 # will be the same |
330 operand1.getattr(BIN_OP_METHOD[operator]) | 316 operand1.getattr(BIN_OP_METHOD[operator]) |
331 yield operand1 | 317 yield operand1 |
332 except: | 318 except: |
333 if failures is None: | 319 if failures is None: |
334 yield YES | 320 yield YES |
335 else: | 321 else: |
336 failures.append(operand1) | 322 failures.append(operand1) |
337 | 323 |
338 def infer_binop(self, context=None): | 324 def infer_binop(self, context=None): |
339 failures = [] | 325 failures = [] |
340 for lhs in self.left.infer(context): | 326 for lhs in self.left.infer(context): |
341 for val in _infer_binop(self.op, lhs, self.right, context, failures): | 327 for val in _infer_binop(self.op, lhs, self.right, context, failures): |
342 yield val | 328 yield val |
343 for lhs in failures: | 329 for lhs in failures: |
344 for rhs in self.right.infer(context): | 330 for rhs in self.right.infer(context): |
345 for val in _infer_binop(self.op, rhs, lhs, context): | 331 for val in _infer_binop(self.op, rhs, lhs, context): |
346 yield val | 332 yield val |
347 nodes.BinOp._infer = path_wrapper(infer_binop) | 333 nodes.BinOp.infer = path_wrapper(infer_binop) |
348 | 334 |
349 | 335 |
350 def infer_arguments(self, context=None): | 336 def infer_arguments(self, context=None): |
351 name = context.lookupname | 337 name = context.lookupname |
352 if name is None: | 338 if name is None: |
353 raise InferenceError() | 339 raise InferenceError() |
354 return _arguments_infer_argname(self, name, context) | 340 return _arguments_infer_argname(self, name, context) |
355 nodes.Arguments._infer = infer_arguments | 341 nodes.Arguments.infer = infer_arguments |
356 | 342 |
357 | 343 |
358 def infer_ass(self, context=None): | 344 def infer_ass(self, context=None): |
359 """infer a AssName/AssAttr: need to inspect the RHS part of the | 345 """infer a AssName/AssAttr: need to inspect the RHS part of the |
360 assign node | 346 assign node |
361 """ | 347 """ |
362 stmt = self.statement() | 348 stmt = self.statement() |
363 if isinstance(stmt, nodes.AugAssign): | 349 if isinstance(stmt, nodes.AugAssign): |
364 return stmt.infer(context) | 350 return stmt.infer(context) |
365 stmts = list(self.assigned_stmts(context=context)) | 351 stmts = list(self.assigned_stmts(context=context)) |
366 return _infer_stmts(stmts, context) | 352 return _infer_stmts(stmts, context) |
367 nodes.AssName._infer = path_wrapper(infer_ass) | 353 nodes.AssName.infer = path_wrapper(infer_ass) |
368 nodes.AssAttr._infer = path_wrapper(infer_ass) | 354 nodes.AssAttr.infer = path_wrapper(infer_ass) |
369 | 355 |
370 def infer_augassign(self, context=None): | 356 def infer_augassign(self, context=None): |
371 failures = [] | 357 failures = [] |
372 for lhs in self.target.infer_lhs(context): | 358 for lhs in self.target.infer_lhs(context): |
373 for val in _infer_binop(self.op, lhs, self.value, context, failures): | 359 for val in _infer_binop(self.op, lhs, self.value, context, failures): |
374 yield val | 360 yield val |
375 for lhs in failures: | 361 for lhs in failures: |
376 for rhs in self.value.infer(context): | 362 for rhs in self.value.infer(context): |
377 for val in _infer_binop(self.op, rhs, lhs, context): | 363 for val in _infer_binop(self.op, rhs, lhs, context): |
378 yield val | 364 yield val |
379 nodes.AugAssign._infer = path_wrapper(infer_augassign) | 365 nodes.AugAssign.infer = path_wrapper(infer_augassign) |
380 | 366 |
381 | 367 |
382 # no infer method on DelName and DelAttr (expected InferenceError) | 368 # no infer method on DelName and DelAttr (expected InferenceError) |
383 | 369 |
384 | 370 |
385 def infer_empty_node(self, context=None): | 371 def infer_empty_node(self, context=None): |
386 if not self.has_underlying_object(): | 372 if not self.has_underlying_object(): |
387 yield YES | 373 yield YES |
388 else: | 374 else: |
389 try: | 375 try: |
390 for infered in MANAGER.infer_ast_from_something(self.object, | 376 for infered in MANAGER.infer_astng_from_something(self.object, |
391 context=context): | 377 context=context): |
392 yield infered | 378 yield infered |
393 except AstroidError: | 379 except ASTNGError: |
394 yield YES | 380 yield YES |
395 nodes.EmptyNode._infer = path_wrapper(infer_empty_node) | 381 nodes.EmptyNode.infer = path_wrapper(infer_empty_node) |
396 | 382 |
397 | |
398 def infer_index(self, context=None): | |
399 return self.value.infer(context) | |
400 nodes.Index._infer = infer_index | |
OLD | NEW |