UtilitiesPython2/py2flakes/checker.py

changeset 2998
95581102e03e
parent 2302
f29e9405c851
child 3160
209a07d7e401
equal deleted inserted replaced
2997:7f0ef975da9e 2998:95581102e03e
20 import ast 20 import ast
21 iter_child_nodes = ast.iter_child_nodes 21 iter_child_nodes = ast.iter_child_nodes
22 except (ImportError, AttributeError): 22 except (ImportError, AttributeError):
23 def iter_child_nodes(node, astcls=_ast.AST): 23 def iter_child_nodes(node, astcls=_ast.AST):
24 """ 24 """
25 Yield all direct child nodes of *node*, that is, all fields that are nodes 25 Yield all direct child nodes of *node*, that is, all fields that are
26 and all items of fields that are lists of nodes. 26 nodes and all items of fields that are lists of nodes.
27 """ 27 """
28 for name in node._fields: 28 for name in node._fields:
29 field = getattr(node, name, None) 29 field = getattr(node, name, None)
30 if isinstance(field, astcls): 30 if isinstance(field, astcls):
31 yield field 31 yield field
289 node.parent = parent 289 node.parent = parent
290 if self.traceTree: 290 if self.traceTree:
291 print ' ' * self.nodeDepth + node.__class__.__name__ 291 print ' ' * self.nodeDepth + node.__class__.__name__
292 self.nodeDepth += 1 292 self.nodeDepth += 1
293 if self.futuresAllowed and not \ 293 if self.futuresAllowed and not \
294 (isinstance(node, _ast.ImportFrom) or self.isDocstring(node)): 294 (isinstance(node, _ast.ImportFrom) or
295 self.isDocstring(node)):
295 self.futuresAllowed = False 296 self.futuresAllowed = False
296 nodeType = node.__class__.__name__.upper() 297 nodeType = node.__class__.__name__.upper()
297 try: 298 try:
298 handler = getattr(self, nodeType) 299 handler = getattr(self, nodeType)
299 handler(node) 300 handler(node)
335 336
336 def addBinding(self, lineno, value, reportRedef=True): 337 def addBinding(self, lineno, value, reportRedef=True):
337 ''' 338 '''
338 Called when a binding is altered. 339 Called when a binding is altered.
339 340
340 @param lineno line of the statement responsible for the change (integer) 341 @param lineno line of the statement responsible for the change
342 (integer)
341 @param value the optional new value, a Binding instance, associated 343 @param value the optional new value, a Binding instance, associated
342 with the binding; if None, the binding is deleted if it exists 344 with the binding; if None, the binding is deleted if it exists
343 @param reportRedef flag indicating if rebinding while unused will be 345 @param reportRedef flag indicating if rebinding while unused will be
344 reported (boolean) 346 reported (boolean)
345 ''' 347 '''
346 if (isinstance(self.scope.get(value.name), FunctionDefinition) 348 if (isinstance(self.scope.get(value.name), FunctionDefinition)
347 and isinstance(value, FunctionDefinition)): 349 and isinstance(value, FunctionDefinition)):
348 self.report(messages.RedefinedFunction, 350 self.report(messages.RedefinedFunction,
349 lineno, value.name, self.scope[value.name].source.lineno) 351 lineno, value.name,
352 self.scope[value.name].source.lineno)
350 353
351 if not isinstance(self.scope, ClassScope): 354 if not isinstance(self.scope, ClassScope):
352 for scope in self.scopeStack[::-1]: 355 for scope in self.scopeStack[::-1]:
353 existing = scope.get(value.name) 356 existing = scope.get(value.name)
354 if (isinstance(existing, Importation) 357 if (isinstance(existing, Importation)
356 and (not isinstance(value, Importation) or 359 and (not isinstance(value, Importation) or
357 value.fullName == existing.fullName) 360 value.fullName == existing.fullName)
358 and reportRedef): 361 and reportRedef):
359 362
360 self.report(messages.RedefinedWhileUnused, 363 self.report(messages.RedefinedWhileUnused,
361 lineno, value.name, scope[value.name].source.lineno) 364 lineno, value.name,
365 scope[value.name].source.lineno)
362 366
363 if isinstance(value, UnBinding): 367 if isinstance(value, UnBinding):
364 try: 368 try:
365 del self.scope[value.name] 369 del self.scope[value.name]
366 except KeyError: 370 except KeyError:
454 if (os.path.basename(self.filename) == '__init__.py' and 458 if (os.path.basename(self.filename) == '__init__.py' and
455 node.id == '__path__'): 459 node.id == '__path__'):
456 # the special name __path__ is valid only in packages 460 # the special name __path__ is valid only in packages
457 pass 461 pass
458 else: 462 else:
459 self.report(messages.UndefinedName, node.lineno, node.id) 463 self.report(messages.UndefinedName,
464 node.lineno, node.id)
460 elif isinstance(node.ctx, (_ast.Store, _ast.AugStore)): 465 elif isinstance(node.ctx, (_ast.Store, _ast.AugStore)):
461 # if the name hasn't already been defined in the current scope 466 # if the name hasn't already been defined in the current scope
462 if isinstance(self.scope, FunctionScope) and node.id not in self.scope: 467 if isinstance(self.scope, FunctionScope) and \
468 node.id not in self.scope:
463 # for each function or module scope above us 469 # for each function or module scope above us
464 for scope in self.scopeStack[:-1]: 470 for scope in self.scopeStack[:-1]:
465 if not isinstance(scope, (FunctionScope, ModuleScope)): 471 if not isinstance(scope, (FunctionScope, ModuleScope)):
466 continue 472 continue
467 # if the name was defined in that scope, and the name has 473 # if the name was defined in that scope, and the name has
477 node.id, 483 node.id,
478 scope[node.id].source.lineno) 484 scope[node.id].source.lineno)
479 break 485 break
480 486
481 if isinstance(node.parent, 487 if isinstance(node.parent,
482 (_ast.For, _ast.comprehension, _ast.Tuple, _ast.List)): 488 (_ast.For, _ast.comprehension, _ast.Tuple,
489 _ast.List)):
483 binding = Binding(node.id, node) 490 binding = Binding(node.id, node)
484 elif (node.id == '__all__' and 491 elif (node.id == '__all__' and
485 isinstance(self.scope, ModuleScope)): 492 isinstance(self.scope, ModuleScope)):
486 binding = ExportBinding(node.id, node.parent.value) 493 binding = ExportBinding(node.id, node.parent.value)
487 else: 494 else:
494 node.id in self.scope.globals: 501 node.id in self.scope.globals:
495 del self.scope.globals[node.id] 502 del self.scope.globals[node.id]
496 else: 503 else:
497 self.addBinding(node.lineno, UnBinding(node.id, node)) 504 self.addBinding(node.lineno, UnBinding(node.id, node))
498 else: 505 else:
499 # must be a Param context -- this only happens for names in function 506 # must be a Param context -- this only happens for names in
500 # arguments, but these aren't dispatched through here 507 # function arguments, but these aren't dispatched through here
501 raise RuntimeError( 508 raise RuntimeError(
502 "Got impossible expression context: %r" % (node.ctx,)) 509 "Got impossible expression context: %r" % (node.ctx,))
503 510
504 def FUNCTIONDEF(self, node): 511 def FUNCTIONDEF(self, node):
505 if hasattr(node, 'decorators'): 512 if hasattr(node, 'decorators'):
522 for arg in arglist: 529 for arg in arglist:
523 if isinstance(arg, _ast.Tuple): 530 if isinstance(arg, _ast.Tuple):
524 addArgs(arg.elts) 531 addArgs(arg.elts)
525 else: 532 else:
526 if arg.id in args: 533 if arg.id in args:
527 self.report(messages.DuplicateArgument, node.lineno, arg.id) 534 self.report(messages.DuplicateArgument,
535 node.lineno, arg.id)
528 args.append(arg.id) 536 args.append(arg.id)
529 537
530 self.pushFunctionScope() 538 self.pushFunctionScope()
531 addArgs(node.args.args) 539 addArgs(node.args.args)
532 # vararg/kwarg identifiers are not Name nodes 540 # vararg/kwarg identifiers are not Name nodes
533 if node.args.vararg: 541 if node.args.vararg:
534 args.append(node.args.vararg) 542 args.append(node.args.vararg)
535 if node.args.kwarg: 543 if node.args.kwarg:
536 args.append(node.args.kwarg) 544 args.append(node.args.kwarg)
537 for name in args: 545 for name in args:
538 self.addBinding(node.lineno, Argument(name, node), reportRedef=False) 546 self.addBinding(node.lineno, Argument(name, node),
547 reportRedef=False)
539 if isinstance(node.body, list): 548 if isinstance(node.body, list):
540 # case for FunctionDefs 549 # case for FunctionDefs
541 for stmt in node.body: 550 for stmt in node.body:
542 self.handleNode(stmt, node) 551 self.handleNode(stmt, node)
543 else: 552 else:
579 self.handleNode(node.value, node) 588 self.handleNode(node.value, node)
580 for target in node.targets: 589 for target in node.targets:
581 self.handleNode(target, node) 590 self.handleNode(target, node)
582 591
583 def AUGASSIGN(self, node): 592 def AUGASSIGN(self, node):
584 # AugAssign is awkward: must set the context explicitly and visit twice, 593 # AugAssign is awkward: must set the context explicitly and visit
585 # once with AugLoad context, once with AugStore context 594 # twice, once with AugLoad context, once with AugStore context
586 node.target.ctx = _ast.AugLoad() 595 node.target.ctx = _ast.AugLoad()
587 self.handleNode(node.target, node) 596 self.handleNode(node.target, node)
588 self.handleNode(node.value, node) 597 self.handleNode(node.value, node)
589 node.target.ctx = _ast.AugStore() 598 node.target.ctx = _ast.AugStore()
590 self.handleNode(node.target, node) 599 self.handleNode(node.target, node)

eric ide

mercurial