Utilities/py3flakes/checker.py

changeset 2997
7f0ef975da9e
parent 2965
d133c7edd88a
child 3160
209a07d7e401
equal deleted inserted replaced
2996:c6f16f1b9958 2997:7f0ef975da9e
277 if node: 277 if node:
278 node.parent = parent 278 node.parent = parent
279 if self.traceTree: 279 if self.traceTree:
280 print(' ' * self.nodeDepth + node.__class__.__name__) 280 print(' ' * self.nodeDepth + node.__class__.__name__)
281 self.nodeDepth += 1 281 self.nodeDepth += 1
282 if self.futuresAllowed and not \ 282 if self.futuresAllowed and \
283 (isinstance(node, ast.ImportFrom) or self.isDocstring(node)): 283 not (isinstance(node, ast.ImportFrom) or
284 self.isDocstring(node)):
284 self.futuresAllowed = False 285 self.futuresAllowed = False
285 nodeType = node.__class__.__name__.upper() 286 nodeType = node.__class__.__name__.upper()
286 try: 287 try:
287 handler = getattr(self, nodeType) 288 handler = getattr(self, nodeType)
288 handler(node) 289 handler(node)
320 321
321 def addBinding(self, lineno, value, reportRedef=True): 322 def addBinding(self, lineno, value, reportRedef=True):
322 ''' 323 '''
323 Called when a binding is altered. 324 Called when a binding is altered.
324 325
325 @param lineno line of the statement responsible for the change (integer) 326 @param lineno line of the statement responsible for the change
327 (integer)
326 @param value the optional new value, a Binding instance, associated 328 @param value the optional new value, a Binding instance, associated
327 with the binding; if None, the binding is deleted if it exists 329 with the binding; if None, the binding is deleted if it exists
328 @param reportRedef flag indicating if rebinding while unused will be 330 @param reportRedef flag indicating if rebinding while unused will be
329 reported (boolean) 331 reported (boolean)
330 ''' 332 '''
331 if (isinstance(self.scope.get(value.name), FunctionDefinition) 333 if (isinstance(self.scope.get(value.name), FunctionDefinition)
332 and isinstance(value, FunctionDefinition) 334 and isinstance(value, FunctionDefinition)
333 and not self.scope.get(value.name).is_property 335 and not self.scope.get(value.name).is_property
334 and not value.is_property): 336 and not value.is_property):
335 self.report(messages.RedefinedFunction, 337 self.report(messages.RedefinedFunction,
336 lineno, value.name, self.scope[value.name].source.lineno) 338 lineno, value.name,
339 self.scope[value.name].source.lineno)
337 340
338 if not isinstance(self.scope, ClassScope): 341 if not isinstance(self.scope, ClassScope):
339 for scope in self.scopeStack[::-1]: 342 for scope in self.scopeStack[::-1]:
340 existing = scope.get(value.name) 343 existing = scope.get(value.name)
341 if isinstance(existing, Importation) and \ 344 if isinstance(existing, Importation) and \
343 not isinstance(value, UnBinding) and \ 346 not isinstance(value, UnBinding) and \
344 (not isinstance(value, Importation) or \ 347 (not isinstance(value, Importation) or \
345 value.fullName == existing.fullName) and \ 348 value.fullName == existing.fullName) and \
346 reportRedef: 349 reportRedef:
347 self.report(messages.RedefinedWhileUnused, 350 self.report(messages.RedefinedWhileUnused,
348 lineno, value.name, scope[value.name].source.lineno) 351 lineno, value.name,
352 scope[value.name].source.lineno)
349 353
350 if isinstance(value, UnBinding): 354 if isinstance(value, UnBinding):
351 try: 355 try:
352 del self.scope[value.name] 356 del self.scope[value.name]
353 except KeyError: 357 except KeyError:
444 if (os.path.basename(self.filename) == '__init__.py' and 448 if (os.path.basename(self.filename) == '__init__.py' and
445 node.id == '__path__'): 449 node.id == '__path__'):
446 # the special name __path__ is valid only in packages 450 # the special name __path__ is valid only in packages
447 pass 451 pass
448 else: 452 else:
449 self.report(messages.UndefinedName, node.lineno, node.id) 453 self.report(messages.UndefinedName,
454 node.lineno, node.id)
450 elif isinstance(node.ctx, (ast.Store, ast.AugStore)): 455 elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
451 # if the name hasn't already been defined in the current scope 456 # if the name hasn't already been defined in the current scope
452 if isinstance(self.scope, FunctionScope) and node.id not in self.scope: 457 if isinstance(self.scope, FunctionScope) and \
458 node.id not in self.scope:
453 # for each function or module scope above us 459 # for each function or module scope above us
454 for scope in self.scopeStack[:-1]: 460 for scope in self.scopeStack[:-1]:
455 if not isinstance(scope, (FunctionScope, ModuleScope)): 461 if not isinstance(scope, (FunctionScope, ModuleScope)):
456 continue 462 continue
457 # if the name was defined in that scope, and the name has 463 # if the name was defined in that scope, and the name has
484 node.id in self.scope.globals: 490 node.id in self.scope.globals:
485 del self.scope.globals[node.id] 491 del self.scope.globals[node.id]
486 else: 492 else:
487 self.addBinding(node.lineno, UnBinding(node.id, node)) 493 self.addBinding(node.lineno, UnBinding(node.id, node))
488 else: 494 else:
489 # must be a Param context -- this only happens for names in function 495 # must be a Param context -- this only happens for names in
490 # arguments, but these aren't dispatched through here 496 # function arguments, but these aren't dispatched through here
491 raise RuntimeError( 497 raise RuntimeError(
492 "Got impossible expression context: {0:r}".format(node.ctx,)) 498 "Got impossible expression context: {0:r}".format(node.ctx,))
493 499
494 def FUNCTIONDEF(self, node): 500 def FUNCTIONDEF(self, node):
495 is_property = False 501 is_property = False
516 for arg in arglist: 522 for arg in arglist:
517 if isinstance(arg.arg, tuple): 523 if isinstance(arg.arg, tuple):
518 addArgs(arg.arg) 524 addArgs(arg.arg)
519 else: 525 else:
520 if arg.arg in args: 526 if arg.arg in args:
521 self.report(messages.DuplicateArgument, node.lineno, arg.arg) 527 self.report(messages.DuplicateArgument,
528 node.lineno, arg.arg)
522 args.append(arg.arg) 529 args.append(arg.arg)
523 530
524 def checkUnusedAssignments(): 531 def checkUnusedAssignments():
525 """ 532 """
526 Check to see if any assignments have not been used. 533 Check to see if any assignments have not been used.
538 if node.args.vararg: 545 if node.args.vararg:
539 args.append(node.args.vararg) 546 args.append(node.args.vararg)
540 if node.args.kwarg: 547 if node.args.kwarg:
541 args.append(node.args.kwarg) 548 args.append(node.args.kwarg)
542 for name in args: 549 for name in args:
543 self.addBinding(node.lineno, Argument(name, node), reportRedef=False) 550 self.addBinding(node.lineno, Argument(name, node),
551 reportRedef=False)
544 if isinstance(node.body, list): 552 if isinstance(node.body, list):
545 self.handleBody(node) 553 self.handleBody(node)
546 else: 554 else:
547 self.handleNode(node.body, node) 555 self.handleNode(node.body, node)
548 self.deferAssignment(checkUnusedAssignments) 556 self.deferAssignment(checkUnusedAssignments)
626 self.handleNode(node.value, node) 634 self.handleNode(node.value, node)
627 for target in node.targets: 635 for target in node.targets:
628 self.handleNode(target, node) 636 self.handleNode(target, node)
629 637
630 def AUGASSIGN(self, node): 638 def AUGASSIGN(self, node):
631 # AugAssign is awkward: must set the context explicitly and visit twice, 639 # AugAssign is awkward: must set the context explicitly and
632 # once with AugLoad context, once with AugStore context 640 # visit twice, once with AugLoad context, once with AugStore context
633 node.target.ctx = ast.AugLoad() 641 node.target.ctx = ast.AugLoad()
634 self.handleNode(node.target, node) 642 self.handleNode(node.target, node)
635 self.handleNode(node.value, node) 643 self.handleNode(node.value, node)
636 node.target.ctx = ast.AugStore() 644 node.target.ctx = ast.AugStore()
637 self.handleNode(node.target, node) 645 self.handleNode(node.target, node)

eric ide

mercurial