Utilities/py3flakes/checker.py

changeset 945
8cd4d08fa9f6
parent 801
16f9875e278b
child 1509
c0b5e693b0eb
equal deleted inserted replaced
944:1b59c4ba121e 945:8cd4d08fa9f6
11 import os.path 11 import os.path
12 import ast 12 import ast
13 13
14 from . import messages 14 from . import messages
15 15
16
16 class Binding(object): 17 class Binding(object):
17 """ 18 """
18 Represents the binding of a value to a name. 19 Represents the binding of a value to a name.
19 20
20 The checker uses this to keep track of which names have been bound and 21 The checker uses this to keep track of which names have been bound and
34 self.__class__.__name__, 35 self.__class__.__name__,
35 self.name, 36 self.name,
36 self.source.lineno, 37 self.source.lineno,
37 id(self)) 38 id(self))
38 39
40
39 class UnBinding(Binding): 41 class UnBinding(Binding):
40 ''' 42 '''
41 Created by the 'del' operator. 43 Created by the 'del' operator.
42 ''' 44 '''
43 45
46
44 class Importation(Binding): 47 class Importation(Binding):
45 """ 48 """
46 A binding created by an import statement. 49 A binding created by an import statement.
47 """ 50 """
48 def __init__(self, name, source): 51 def __init__(self, name, source):
49 self.fullName = name 52 self.fullName = name
50 name = name.split('.')[0] 53 name = name.split('.')[0]
51 super(Importation, self).__init__(name, source) 54 super(Importation, self).__init__(name, source)
52 55
56
53 class Argument(Binding): 57 class Argument(Binding):
54 """ 58 """
55 Represents binding a name as an argument. 59 Represents binding a name as an argument.
56 """ 60 """
61
57 62
58 class Assignment(Binding): 63 class Assignment(Binding):
59 """ 64 """
60 Represents binding a name with an explicit assignment. 65 Represents binding a name with an explicit assignment.
61 66
62 The checker will raise warnings for any Assignment that isn't used. Also, 67 The checker will raise warnings for any Assignment that isn't used. Also,
63 the checker does not consider assignments in tuple/list unpacking to be 68 the checker does not consider assignments in tuple/list unpacking to be
64 Assignments, rather it treats them as simple Bindings. 69 Assignments, rather it treats them as simple Bindings.
65 """ 70 """
66 71
72
67 class FunctionDefinition(Binding): 73 class FunctionDefinition(Binding):
68 """ 74 """
69 Represents a function definition. 75 Represents a function definition.
70 """ 76 """
71 pass 77 pass
78
72 79
73 class ExportBinding(Binding): 80 class ExportBinding(Binding):
74 """ 81 """
75 A binding created by an __all__ assignment. If the names in the list 82 A binding created by an __all__ assignment. If the names in the list
76 can be determined statically, they will be treated as names for export and 83 can be determined statically, they will be treated as names for export and
95 names.append(node.s) 102 names.append(node.s)
96 elif isinstance(node, ast.Num): 103 elif isinstance(node, ast.Num):
97 names.append(node.n) 104 names.append(node.n)
98 return names 105 return names
99 106
107
100 class Scope(dict): 108 class Scope(dict):
101 """ 109 """
102 Class defining the scope base class. 110 Class defining the scope base class.
103 """ 111 """
104 importStarred = False # set to True when import * is found 112 importStarred = False # set to True when import * is found
108 self.__class__.__name__, id(self), dict.__repr__(self)) 116 self.__class__.__name__, id(self), dict.__repr__(self))
109 117
110 def __init__(self): 118 def __init__(self):
111 super(Scope, self).__init__() 119 super(Scope, self).__init__()
112 120
121
113 class ClassScope(Scope): 122 class ClassScope(Scope):
114 """ 123 """
115 Class representing a name scope for a class. 124 Class representing a name scope for a class.
116 """ 125 """
117 pass 126 pass
127
118 128
119 class FunctionScope(Scope): 129 class FunctionScope(Scope):
120 """ 130 """
121 Class representing a name scope for a function. 131 Class representing a name scope for a function.
122 """ 132 """
123 def __init__(self): 133 def __init__(self):
124 super(FunctionScope, self).__init__() 134 super(FunctionScope, self).__init__()
125 self.globals = {} 135 self.globals = {}
126 136
137
127 class ModuleScope(Scope): 138 class ModuleScope(Scope):
128 """ 139 """
129 Class representing a name scope for a module. 140 Class representing a name scope for a module.
130 """ 141 """
131 pass 142 pass
132 143
133 # Globally defined names which are not attributes of the builtins module. 144 # Globally defined names which are not attributes of the builtins module.
134 _MAGIC_GLOBALS = ['__file__', '__builtins__'] 145 _MAGIC_GLOBALS = ['__file__', '__builtins__']
135 146
147
136 class Checker(object): 148 class Checker(object):
137 """ 149 """
138 Class to check the cleanliness and sanity of Python code. 150 Class to check the cleanliness and sanity of Python code.
139 """ 151 """
140 nodeDepth = 0 152 nodeDepth = 0
141 traceTree = False 153 traceTree = False
142 154
143 def __init__(self, module, filename = '(none)'): 155 def __init__(self, module, filename='(none)'):
144 """ 156 """
145 Constructor 157 Constructor
146 158
147 @param module parsed module tree or module source code 159 @param module parsed module tree or module source code
148 @param filename name of the module file (string) 160 @param filename name of the module file (string)
299 SLICE = EXTSLICE = INDEX = handleChildren 311 SLICE = EXTSLICE = INDEX = handleChildren
300 312
301 # additional node types 313 # additional node types
302 COMPREHENSION = KEYWORD = handleChildren 314 COMPREHENSION = KEYWORD = handleChildren
303 315
304 def addBinding(self, lineno, value, reportRedef = True): 316 def addBinding(self, lineno, value, reportRedef=True):
305 ''' 317 '''
306 Called when a binding is altered. 318 Called when a binding is altered.
307 319
308 @param lineno line of the statement responsible for the change (integer) 320 @param lineno line of the statement responsible for the change (integer)
309 @param value the optional new value, a Binding instance, associated 321 @param value the optional new value, a Binding instance, associated
365 def FOR(self, node): 377 def FOR(self, node):
366 """ 378 """
367 Process bindings for loop variables. 379 Process bindings for loop variables.
368 """ 380 """
369 vars = [] 381 vars = []
382
370 def collectLoopVars(n): 383 def collectLoopVars(n):
371 if isinstance(n, ast.Name): 384 if isinstance(n, ast.Name):
372 vars.append(n.id) 385 vars.append(n.id)
373 elif isinstance(n, ast.expr_context): 386 elif isinstance(n, ast.expr_context):
374 return 387 return
617 self.addBinding(node.lineno, importation) 630 self.addBinding(node.lineno, importation)
618 631
619 def IMPORTFROM(self, node): 632 def IMPORTFROM(self, node):
620 if node.module == '__future__': 633 if node.module == '__future__':
621 if not self.futuresAllowed: 634 if not self.futuresAllowed:
622 self.report(messages.LateFutureImport, node.lineno, 635 self.report(messages.LateFutureImport, node.lineno,
623 [n.name for n in node.names]) 636 [n.name for n in node.names])
624 else: 637 else:
625 self.futuresAllowed = False 638 self.futuresAllowed = False
626 639
627 for alias in node.names: 640 for alias in node.names:

eric ide

mercurial