~ibmcharmers/charms/xenial/ibm-cinder-storwize-svc/trunk

« back to all changes in this revision

Viewing changes to .tox/py35/lib/python3.5/site-packages/pyflakes/checker.py

  • Committer: Ankammarao
  • Date: 2017-03-06 05:11:42 UTC
  • Revision ID: achittet@in.ibm.com-20170306051142-dpg27z4es1k56hfn
Marked tests folder executable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Main module.
 
3
 
 
4
Implement the central Checker class.
 
5
Also, it models the Bindings and Scopes.
 
6
"""
 
7
import __future__
 
8
import doctest
 
9
import os
 
10
import sys
 
11
 
 
12
PY2 = sys.version_info < (3, 0)
 
13
PY32 = sys.version_info < (3, 3)    # Python 2.5 to 3.2
 
14
PY33 = sys.version_info < (3, 4)    # Python 2.5 to 3.3
 
15
PY34 = sys.version_info < (3, 5)    # Python 2.5 to 3.4
 
16
try:
 
17
    sys.pypy_version_info
 
18
    PYPY = True
 
19
except AttributeError:
 
20
    PYPY = False
 
21
 
 
22
builtin_vars = dir(__import__('__builtin__' if PY2 else 'builtins'))
 
23
 
 
24
try:
 
25
    import ast
 
26
except ImportError:     # Python 2.5
 
27
    import _ast as ast
 
28
 
 
29
    if 'decorator_list' not in ast.ClassDef._fields:
 
30
        # Patch the missing attribute 'decorator_list'
 
31
        ast.ClassDef.decorator_list = ()
 
32
        ast.FunctionDef.decorator_list = property(lambda s: s.decorators)
 
33
 
 
34
from pyflakes import messages
 
35
 
 
36
 
 
37
if PY2:
 
38
    def getNodeType(node_class):
 
39
        # workaround str.upper() which is locale-dependent
 
40
        return str(unicode(node_class.__name__).upper())
 
41
else:
 
42
    def getNodeType(node_class):
 
43
        return node_class.__name__.upper()
 
44
 
 
45
# Python >= 3.3 uses ast.Try instead of (ast.TryExcept + ast.TryFinally)
 
46
if PY32:
 
47
    def getAlternatives(n):
 
48
        if isinstance(n, (ast.If, ast.TryFinally)):
 
49
            return [n.body]
 
50
        if isinstance(n, ast.TryExcept):
 
51
            return [n.body + n.orelse] + [[hdl] for hdl in n.handlers]
 
52
else:
 
53
    def getAlternatives(n):
 
54
        if isinstance(n, ast.If):
 
55
            return [n.body]
 
56
        if isinstance(n, ast.Try):
 
57
            return [n.body + n.orelse] + [[hdl] for hdl in n.handlers]
 
58
 
 
59
if PY34:
 
60
    LOOP_TYPES = (ast.While, ast.For)
 
61
else:
 
62
    LOOP_TYPES = (ast.While, ast.For, ast.AsyncFor)
 
63
 
 
64
 
 
65
class _FieldsOrder(dict):
 
66
    """Fix order of AST node fields."""
 
67
 
 
68
    def _get_fields(self, node_class):
 
69
        # handle iter before target, and generators before element
 
70
        fields = node_class._fields
 
71
        if 'iter' in fields:
 
72
            key_first = 'iter'.find
 
73
        elif 'generators' in fields:
 
74
            key_first = 'generators'.find
 
75
        else:
 
76
            key_first = 'value'.find
 
77
        return tuple(sorted(fields, key=key_first, reverse=True))
 
78
 
 
79
    def __missing__(self, node_class):
 
80
        self[node_class] = fields = self._get_fields(node_class)
 
81
        return fields
 
82
 
 
83
 
 
84
def counter(items):
 
85
    """
 
86
    Simplest required implementation of collections.Counter. Required as 2.6
 
87
    does not have Counter in collections.
 
88
    """
 
89
    results = {}
 
90
    for item in items:
 
91
        results[item] = results.get(item, 0) + 1
 
92
    return results
 
93
 
 
94
 
 
95
def iter_child_nodes(node, omit=None, _fields_order=_FieldsOrder()):
 
96
    """
 
97
    Yield all direct child nodes of *node*, that is, all fields that
 
98
    are nodes and all items of fields that are lists of nodes.
 
99
    """
 
100
    for name in _fields_order[node.__class__]:
 
101
        if name == omit:
 
102
            continue
 
103
        field = getattr(node, name, None)
 
104
        if isinstance(field, ast.AST):
 
105
            yield field
 
106
        elif isinstance(field, list):
 
107
            for item in field:
 
108
                yield item
 
109
 
 
110
 
 
111
def convert_to_value(item):
 
112
    if isinstance(item, ast.Str):
 
113
        return item.s
 
114
    elif hasattr(ast, 'Bytes') and isinstance(item, ast.Bytes):
 
115
        return item.s
 
116
    elif isinstance(item, ast.Tuple):
 
117
        return tuple(convert_to_value(i) for i in item.elts)
 
118
    elif isinstance(item, ast.Num):
 
119
        return item.n
 
120
    elif isinstance(item, ast.Name):
 
121
        result = VariableKey(item=item)
 
122
        constants_lookup = {
 
123
            'True': True,
 
124
            'False': False,
 
125
            'None': None,
 
126
        }
 
127
        return constants_lookup.get(
 
128
            result.name,
 
129
            result,
 
130
        )
 
131
    elif (not PY33) and isinstance(item, ast.NameConstant):
 
132
        # None, True, False are nameconstants in python3, but names in 2
 
133
        return item.value
 
134
    else:
 
135
        return UnhandledKeyType()
 
136
 
 
137
 
 
138
class Binding(object):
 
139
    """
 
140
    Represents the binding of a value to a name.
 
141
 
 
142
    The checker uses this to keep track of which names have been bound and
 
143
    which names have not. See L{Assignment} for a special type of binding that
 
144
    is checked with stricter rules.
 
145
 
 
146
    @ivar used: pair of (L{Scope}, node) indicating the scope and
 
147
                the node that this binding was last used.
 
148
    """
 
149
 
 
150
    def __init__(self, name, source):
 
151
        self.name = name
 
152
        self.source = source
 
153
        self.used = False
 
154
 
 
155
    def __str__(self):
 
156
        return self.name
 
157
 
 
158
    def __repr__(self):
 
159
        return '<%s object %r from line %r at 0x%x>' % (self.__class__.__name__,
 
160
                                                        self.name,
 
161
                                                        self.source.lineno,
 
162
                                                        id(self))
 
163
 
 
164
    def redefines(self, other):
 
165
        return isinstance(other, Definition) and self.name == other.name
 
166
 
 
167
 
 
168
class Definition(Binding):
 
169
    """
 
170
    A binding that defines a function or a class.
 
171
    """
 
172
 
 
173
 
 
174
class UnhandledKeyType(object):
 
175
    """
 
176
    A dictionary key of a type that we cannot or do not check for duplicates.
 
177
    """
 
178
 
 
179
 
 
180
class VariableKey(object):
 
181
    """
 
182
    A dictionary key which is a variable.
 
183
 
 
184
    @ivar item: The variable AST object.
 
185
    """
 
186
    def __init__(self, item):
 
187
        self.name = item.id
 
188
 
 
189
    def __eq__(self, compare):
 
190
        return (
 
191
            compare.__class__ == self.__class__
 
192
            and compare.name == self.name
 
193
        )
 
194
 
 
195
    def __hash__(self):
 
196
        return hash(self.name)
 
197
 
 
198
 
 
199
class Importation(Definition):
 
200
    """
 
201
    A binding created by an import statement.
 
202
 
 
203
    @ivar fullName: The complete name given to the import statement,
 
204
        possibly including multiple dotted components.
 
205
    @type fullName: C{str}
 
206
    """
 
207
 
 
208
    def __init__(self, name, source, full_name=None):
 
209
        self.fullName = full_name or name
 
210
        self.redefined = []
 
211
        super(Importation, self).__init__(name, source)
 
212
 
 
213
    def redefines(self, other):
 
214
        if isinstance(other, SubmoduleImportation):
 
215
            # See note in SubmoduleImportation about RedefinedWhileUnused
 
216
            return self.fullName == other.fullName
 
217
        return isinstance(other, Definition) and self.name == other.name
 
218
 
 
219
    def _has_alias(self):
 
220
        """Return whether importation needs an as clause."""
 
221
        return not self.fullName.split('.')[-1] == self.name
 
222
 
 
223
    @property
 
224
    def source_statement(self):
 
225
        """Generate a source statement equivalent to the import."""
 
226
        if self._has_alias():
 
227
            return 'import %s as %s' % (self.fullName, self.name)
 
228
        else:
 
229
            return 'import %s' % self.fullName
 
230
 
 
231
    def __str__(self):
 
232
        """Return import full name with alias."""
 
233
        if self._has_alias():
 
234
            return self.fullName + ' as ' + self.name
 
235
        else:
 
236
            return self.fullName
 
237
 
 
238
 
 
239
class SubmoduleImportation(Importation):
 
240
    """
 
241
    A binding created by a submodule import statement.
 
242
 
 
243
    A submodule import is a special case where the root module is implicitly
 
244
    imported, without an 'as' clause, and the submodule is also imported.
 
245
    Python does not restrict which attributes of the root module may be used.
 
246
 
 
247
    This class is only used when the submodule import is without an 'as' clause.
 
248
 
 
249
    pyflakes handles this case by registering the root module name in the scope,
 
250
    allowing any attribute of the root module to be accessed.
 
251
 
 
252
    RedefinedWhileUnused is suppressed in `redefines` unless the submodule
 
253
    name is also the same, to avoid false positives.
 
254
    """
 
255
 
 
256
    def __init__(self, name, source):
 
257
        # A dot should only appear in the name when it is a submodule import
 
258
        assert '.' in name and (not source or isinstance(source, ast.Import))
 
259
        package_name = name.split('.')[0]
 
260
        super(SubmoduleImportation, self).__init__(package_name, source)
 
261
        self.fullName = name
 
262
 
 
263
    def redefines(self, other):
 
264
        if isinstance(other, Importation):
 
265
            return self.fullName == other.fullName
 
266
        return super(SubmoduleImportation, self).redefines(other)
 
267
 
 
268
    def __str__(self):
 
269
        return self.fullName
 
270
 
 
271
    @property
 
272
    def source_statement(self):
 
273
        return 'import ' + self.fullName
 
274
 
 
275
 
 
276
class ImportationFrom(Importation):
 
277
 
 
278
    def __init__(self, name, source, module, real_name=None):
 
279
        self.module = module
 
280
        self.real_name = real_name or name
 
281
 
 
282
        if module.endswith('.'):
 
283
            full_name = module + self.real_name
 
284
        else:
 
285
            full_name = module + '.' + self.real_name
 
286
 
 
287
        super(ImportationFrom, self).__init__(name, source, full_name)
 
288
 
 
289
    def __str__(self):
 
290
        """Return import full name with alias."""
 
291
        if self.real_name != self.name:
 
292
            return self.fullName + ' as ' + self.name
 
293
        else:
 
294
            return self.fullName
 
295
 
 
296
    @property
 
297
    def source_statement(self):
 
298
        if self.real_name != self.name:
 
299
            return 'from %s import %s as %s' % (self.module,
 
300
                                                self.real_name,
 
301
                                                self.name)
 
302
        else:
 
303
            return 'from %s import %s' % (self.module, self.name)
 
304
 
 
305
 
 
306
class StarImportation(Importation):
 
307
    """A binding created by a 'from x import *' statement."""
 
308
 
 
309
    def __init__(self, name, source):
 
310
        super(StarImportation, self).__init__('*', source)
 
311
        # Each star importation needs a unique name, and
 
312
        # may not be the module name otherwise it will be deemed imported
 
313
        self.name = name + '.*'
 
314
        self.fullName = name
 
315
 
 
316
    @property
 
317
    def source_statement(self):
 
318
        return 'from ' + self.fullName + ' import *'
 
319
 
 
320
    def __str__(self):
 
321
        # When the module ends with a ., avoid the ambiguous '..*'
 
322
        if self.fullName.endswith('.'):
 
323
            return self.source_statement
 
324
        else:
 
325
            return self.name
 
326
 
 
327
 
 
328
class FutureImportation(ImportationFrom):
 
329
    """
 
330
    A binding created by a from `__future__` import statement.
 
331
 
 
332
    `__future__` imports are implicitly used.
 
333
    """
 
334
 
 
335
    def __init__(self, name, source, scope):
 
336
        super(FutureImportation, self).__init__(name, source, '__future__')
 
337
        self.used = (scope, source)
 
338
 
 
339
 
 
340
class Argument(Binding):
 
341
    """
 
342
    Represents binding a name as an argument.
 
343
    """
 
344
 
 
345
 
 
346
class Assignment(Binding):
 
347
    """
 
348
    Represents binding a name with an explicit assignment.
 
349
 
 
350
    The checker will raise warnings for any Assignment that isn't used. Also,
 
351
    the checker does not consider assignments in tuple/list unpacking to be
 
352
    Assignments, rather it treats them as simple Bindings.
 
353
    """
 
354
 
 
355
 
 
356
class FunctionDefinition(Definition):
 
357
    pass
 
358
 
 
359
 
 
360
class ClassDefinition(Definition):
 
361
    pass
 
362
 
 
363
 
 
364
class ExportBinding(Binding):
 
365
    """
 
366
    A binding created by an C{__all__} assignment.  If the names in the list
 
367
    can be determined statically, they will be treated as names for export and
 
368
    additional checking applied to them.
 
369
 
 
370
    The only C{__all__} assignment that can be recognized is one which takes
 
371
    the value of a literal list containing literal strings.  For example::
 
372
 
 
373
        __all__ = ["foo", "bar"]
 
374
 
 
375
    Names which are imported and not otherwise used but appear in the value of
 
376
    C{__all__} will not have an unused import warning reported for them.
 
377
    """
 
378
 
 
379
    def __init__(self, name, source, scope):
 
380
        if '__all__' in scope and isinstance(source, ast.AugAssign):
 
381
            self.names = list(scope['__all__'].names)
 
382
        else:
 
383
            self.names = []
 
384
        if isinstance(source.value, (ast.List, ast.Tuple)):
 
385
            for node in source.value.elts:
 
386
                if isinstance(node, ast.Str):
 
387
                    self.names.append(node.s)
 
388
        super(ExportBinding, self).__init__(name, source)
 
389
 
 
390
 
 
391
class Scope(dict):
 
392
    importStarred = False       # set to True when import * is found
 
393
 
 
394
    def __repr__(self):
 
395
        scope_cls = self.__class__.__name__
 
396
        return '<%s at 0x%x %s>' % (scope_cls, id(self), dict.__repr__(self))
 
397
 
 
398
 
 
399
class ClassScope(Scope):
 
400
    pass
 
401
 
 
402
 
 
403
class FunctionScope(Scope):
 
404
    """
 
405
    I represent a name scope for a function.
 
406
 
 
407
    @ivar globals: Names declared 'global' in this function.
 
408
    """
 
409
    usesLocals = False
 
410
    alwaysUsed = set(['__tracebackhide__',
 
411
                      '__traceback_info__', '__traceback_supplement__'])
 
412
 
 
413
    def __init__(self):
 
414
        super(FunctionScope, self).__init__()
 
415
        # Simplify: manage the special locals as globals
 
416
        self.globals = self.alwaysUsed.copy()
 
417
        self.returnValue = None     # First non-empty return
 
418
        self.isGenerator = False    # Detect a generator
 
419
 
 
420
    def unusedAssignments(self):
 
421
        """
 
422
        Return a generator for the assignments which have not been used.
 
423
        """
 
424
        for name, binding in self.items():
 
425
            if (not binding.used and name not in self.globals
 
426
                    and not self.usesLocals
 
427
                    and isinstance(binding, Assignment)):
 
428
                yield name, binding
 
429
 
 
430
 
 
431
class GeneratorScope(Scope):
 
432
    pass
 
433
 
 
434
 
 
435
class ModuleScope(Scope):
 
436
    """Scope for a module."""
 
437
    _futures_allowed = True
 
438
 
 
439
 
 
440
class DoctestScope(ModuleScope):
 
441
    """Scope for a doctest."""
 
442
 
 
443
 
 
444
# Globally defined names which are not attributes of the builtins module, or
 
445
# are only present on some platforms.
 
446
_MAGIC_GLOBALS = ['__file__', '__builtins__', 'WindowsError']
 
447
 
 
448
 
 
449
def getNodeName(node):
 
450
    # Returns node.id, or node.name, or None
 
451
    if hasattr(node, 'id'):     # One of the many nodes with an id
 
452
        return node.id
 
453
    if hasattr(node, 'name'):   # an ExceptHandler node
 
454
        return node.name
 
455
 
 
456
 
 
457
class Checker(object):
 
458
    """
 
459
    I check the cleanliness and sanity of Python code.
 
460
 
 
461
    @ivar _deferredFunctions: Tracking list used by L{deferFunction}.  Elements
 
462
        of the list are two-tuples.  The first element is the callable passed
 
463
        to L{deferFunction}.  The second element is a copy of the scope stack
 
464
        at the time L{deferFunction} was called.
 
465
 
 
466
    @ivar _deferredAssignments: Similar to C{_deferredFunctions}, but for
 
467
        callables which are deferred assignment checks.
 
468
    """
 
469
 
 
470
    nodeDepth = 0
 
471
    offset = None
 
472
    traceTree = False
 
473
 
 
474
    builtIns = set(builtin_vars).union(_MAGIC_GLOBALS)
 
475
    _customBuiltIns = os.environ.get('PYFLAKES_BUILTINS')
 
476
    if _customBuiltIns:
 
477
        builtIns.update(_customBuiltIns.split(','))
 
478
    del _customBuiltIns
 
479
 
 
480
    def __init__(self, tree, filename='(none)', builtins=None,
 
481
                 withDoctest='PYFLAKES_DOCTEST' in os.environ):
 
482
        self._nodeHandlers = {}
 
483
        self._deferredFunctions = []
 
484
        self._deferredAssignments = []
 
485
        self.deadScopes = []
 
486
        self.messages = []
 
487
        self.filename = filename
 
488
        if builtins:
 
489
            self.builtIns = self.builtIns.union(builtins)
 
490
        self.withDoctest = withDoctest
 
491
        self.scopeStack = [ModuleScope()]
 
492
        self.exceptHandlers = [()]
 
493
        self.root = tree
 
494
        self.handleChildren(tree)
 
495
        self.runDeferred(self._deferredFunctions)
 
496
        # Set _deferredFunctions to None so that deferFunction will fail
 
497
        # noisily if called after we've run through the deferred functions.
 
498
        self._deferredFunctions = None
 
499
        self.runDeferred(self._deferredAssignments)
 
500
        # Set _deferredAssignments to None so that deferAssignment will fail
 
501
        # noisily if called after we've run through the deferred assignments.
 
502
        self._deferredAssignments = None
 
503
        del self.scopeStack[1:]
 
504
        self.popScope()
 
505
        self.checkDeadScopes()
 
506
 
 
507
    def deferFunction(self, callable):
 
508
        """
 
509
        Schedule a function handler to be called just before completion.
 
510
 
 
511
        This is used for handling function bodies, which must be deferred
 
512
        because code later in the file might modify the global scope. When
 
513
        `callable` is called, the scope at the time this is called will be
 
514
        restored, however it will contain any new bindings added to it.
 
515
        """
 
516
        self._deferredFunctions.append((callable, self.scopeStack[:], self.offset))
 
517
 
 
518
    def deferAssignment(self, callable):
 
519
        """
 
520
        Schedule an assignment handler to be called just after deferred
 
521
        function handlers.
 
522
        """
 
523
        self._deferredAssignments.append((callable, self.scopeStack[:], self.offset))
 
524
 
 
525
    def runDeferred(self, deferred):
 
526
        """
 
527
        Run the callables in C{deferred} using their associated scope stack.
 
528
        """
 
529
        for handler, scope, offset in deferred:
 
530
            self.scopeStack = scope
 
531
            self.offset = offset
 
532
            handler()
 
533
 
 
534
    def _in_doctest(self):
 
535
        return (len(self.scopeStack) >= 2 and
 
536
                isinstance(self.scopeStack[1], DoctestScope))
 
537
 
 
538
    @property
 
539
    def futuresAllowed(self):
 
540
        if not all(isinstance(scope, ModuleScope)
 
541
                   for scope in self.scopeStack):
 
542
            return False
 
543
 
 
544
        return self.scope._futures_allowed
 
545
 
 
546
    @futuresAllowed.setter
 
547
    def futuresAllowed(self, value):
 
548
        assert value is False
 
549
        if isinstance(self.scope, ModuleScope):
 
550
            self.scope._futures_allowed = False
 
551
 
 
552
    @property
 
553
    def scope(self):
 
554
        return self.scopeStack[-1]
 
555
 
 
556
    def popScope(self):
 
557
        self.deadScopes.append(self.scopeStack.pop())
 
558
 
 
559
    def checkDeadScopes(self):
 
560
        """
 
561
        Look at scopes which have been fully examined and report names in them
 
562
        which were imported but unused.
 
563
        """
 
564
        for scope in self.deadScopes:
 
565
            # imports in classes are public members
 
566
            if isinstance(scope, ClassScope):
 
567
                continue
 
568
 
 
569
            all_binding = scope.get('__all__')
 
570
            if all_binding and not isinstance(all_binding, ExportBinding):
 
571
                all_binding = None
 
572
 
 
573
            if all_binding:
 
574
                all_names = set(all_binding.names)
 
575
                undefined = all_names.difference(scope)
 
576
            else:
 
577
                all_names = undefined = []
 
578
 
 
579
            if undefined:
 
580
                if not scope.importStarred and \
 
581
                   os.path.basename(self.filename) != '__init__.py':
 
582
                    # Look for possible mistakes in the export list
 
583
                    for name in undefined:
 
584
                        self.report(messages.UndefinedExport,
 
585
                                    scope['__all__'].source, name)
 
586
 
 
587
                # mark all import '*' as used by the undefined in __all__
 
588
                if scope.importStarred:
 
589
                    for binding in scope.values():
 
590
                        if isinstance(binding, StarImportation):
 
591
                            binding.used = all_binding
 
592
 
 
593
            # Look for imported names that aren't used.
 
594
            for value in scope.values():
 
595
                if isinstance(value, Importation):
 
596
                    used = value.used or value.name in all_names
 
597
                    if not used:
 
598
                        messg = messages.UnusedImport
 
599
                        self.report(messg, value.source, str(value))
 
600
                    for node in value.redefined:
 
601
                        if isinstance(self.getParent(node), ast.For):
 
602
                            messg = messages.ImportShadowedByLoopVar
 
603
                        elif used:
 
604
                            continue
 
605
                        else:
 
606
                            messg = messages.RedefinedWhileUnused
 
607
                        self.report(messg, node, value.name, value.source)
 
608
 
 
609
    def pushScope(self, scopeClass=FunctionScope):
 
610
        self.scopeStack.append(scopeClass())
 
611
 
 
612
    def report(self, messageClass, *args, **kwargs):
 
613
        self.messages.append(messageClass(self.filename, *args, **kwargs))
 
614
 
 
615
    def getParent(self, node):
 
616
        # Lookup the first parent which is not Tuple, List or Starred
 
617
        while True:
 
618
            node = node.parent
 
619
            if not hasattr(node, 'elts') and not hasattr(node, 'ctx'):
 
620
                return node
 
621
 
 
622
    def getCommonAncestor(self, lnode, rnode, stop):
 
623
        if stop in (lnode, rnode) or not (hasattr(lnode, 'parent') and
 
624
                                          hasattr(rnode, 'parent')):
 
625
            return None
 
626
        if lnode is rnode:
 
627
            return lnode
 
628
 
 
629
        if (lnode.depth > rnode.depth):
 
630
            return self.getCommonAncestor(lnode.parent, rnode, stop)
 
631
        if (lnode.depth < rnode.depth):
 
632
            return self.getCommonAncestor(lnode, rnode.parent, stop)
 
633
        return self.getCommonAncestor(lnode.parent, rnode.parent, stop)
 
634
 
 
635
    def descendantOf(self, node, ancestors, stop):
 
636
        for a in ancestors:
 
637
            if self.getCommonAncestor(node, a, stop):
 
638
                return True
 
639
        return False
 
640
 
 
641
    def differentForks(self, lnode, rnode):
 
642
        """True, if lnode and rnode are located on different forks of IF/TRY"""
 
643
        ancestor = self.getCommonAncestor(lnode, rnode, self.root)
 
644
        parts = getAlternatives(ancestor)
 
645
        if parts:
 
646
            for items in parts:
 
647
                if self.descendantOf(lnode, items, ancestor) ^ \
 
648
                   self.descendantOf(rnode, items, ancestor):
 
649
                    return True
 
650
        return False
 
651
 
 
652
    def addBinding(self, node, value):
 
653
        """
 
654
        Called when a binding is altered.
 
655
 
 
656
        - `node` is the statement responsible for the change
 
657
        - `value` is the new value, a Binding instance
 
658
        """
 
659
        # assert value.source in (node, node.parent):
 
660
        for scope in self.scopeStack[::-1]:
 
661
            if value.name in scope:
 
662
                break
 
663
        existing = scope.get(value.name)
 
664
 
 
665
        if existing and not self.differentForks(node, existing.source):
 
666
 
 
667
            parent_stmt = self.getParent(value.source)
 
668
            if isinstance(existing, Importation) and isinstance(parent_stmt, ast.For):
 
669
                self.report(messages.ImportShadowedByLoopVar,
 
670
                            node, value.name, existing.source)
 
671
 
 
672
            elif scope is self.scope:
 
673
                if (isinstance(parent_stmt, ast.comprehension) and
 
674
                        not isinstance(self.getParent(existing.source),
 
675
                                       (ast.For, ast.comprehension))):
 
676
                    self.report(messages.RedefinedInListComp,
 
677
                                node, value.name, existing.source)
 
678
                elif not existing.used and value.redefines(existing):
 
679
                    self.report(messages.RedefinedWhileUnused,
 
680
                                node, value.name, existing.source)
 
681
 
 
682
            elif isinstance(existing, Importation) and value.redefines(existing):
 
683
                existing.redefined.append(node)
 
684
 
 
685
        if value.name in self.scope:
 
686
            # then assume the rebound name is used as a global or within a loop
 
687
            value.used = self.scope[value.name].used
 
688
 
 
689
        self.scope[value.name] = value
 
690
 
 
691
    def getNodeHandler(self, node_class):
 
692
        try:
 
693
            return self._nodeHandlers[node_class]
 
694
        except KeyError:
 
695
            nodeType = getNodeType(node_class)
 
696
        self._nodeHandlers[node_class] = handler = getattr(self, nodeType)
 
697
        return handler
 
698
 
 
699
    def handleNodeLoad(self, node):
 
700
        name = getNodeName(node)
 
701
        if not name:
 
702
            return
 
703
 
 
704
        in_generators = None
 
705
        importStarred = None
 
706
 
 
707
        # try enclosing function scopes and global scope
 
708
        for scope in self.scopeStack[-1::-1]:
 
709
            # only generators used in a class scope can access the names
 
710
            # of the class. this is skipped during the first iteration
 
711
            if in_generators is False and isinstance(scope, ClassScope):
 
712
                continue
 
713
 
 
714
            try:
 
715
                scope[name].used = (self.scope, node)
 
716
            except KeyError:
 
717
                pass
 
718
            else:
 
719
                return
 
720
 
 
721
            importStarred = importStarred or scope.importStarred
 
722
 
 
723
            if in_generators is not False:
 
724
                in_generators = isinstance(scope, GeneratorScope)
 
725
 
 
726
        # look in the built-ins
 
727
        if name in self.builtIns:
 
728
            return
 
729
 
 
730
        if importStarred:
 
731
            from_list = []
 
732
 
 
733
            for scope in self.scopeStack[-1::-1]:
 
734
                for binding in scope.values():
 
735
                    if isinstance(binding, StarImportation):
 
736
                        # mark '*' imports as used for each scope
 
737
                        binding.used = (self.scope, node)
 
738
                        from_list.append(binding.fullName)
 
739
 
 
740
            # report * usage, with a list of possible sources
 
741
            from_list = ', '.join(sorted(from_list))
 
742
            self.report(messages.ImportStarUsage, node, name, from_list)
 
743
            return
 
744
 
 
745
        if name == '__path__' and os.path.basename(self.filename) == '__init__.py':
 
746
            # the special name __path__ is valid only in packages
 
747
            return
 
748
 
 
749
        # protected with a NameError handler?
 
750
        if 'NameError' not in self.exceptHandlers[-1]:
 
751
            self.report(messages.UndefinedName, node, name)
 
752
 
 
753
    def handleNodeStore(self, node):
 
754
        name = getNodeName(node)
 
755
        if not name:
 
756
            return
 
757
        # if the name hasn't already been defined in the current scope
 
758
        if isinstance(self.scope, FunctionScope) and name not in self.scope:
 
759
            # for each function or module scope above us
 
760
            for scope in self.scopeStack[:-1]:
 
761
                if not isinstance(scope, (FunctionScope, ModuleScope)):
 
762
                    continue
 
763
                # if the name was defined in that scope, and the name has
 
764
                # been accessed already in the current scope, and hasn't
 
765
                # been declared global
 
766
                used = name in scope and scope[name].used
 
767
                if used and used[0] is self.scope and name not in self.scope.globals:
 
768
                    # then it's probably a mistake
 
769
                    self.report(messages.UndefinedLocal,
 
770
                                scope[name].used[1], name, scope[name].source)
 
771
                    break
 
772
 
 
773
        parent_stmt = self.getParent(node)
 
774
        if isinstance(parent_stmt, (ast.For, ast.comprehension)) or (
 
775
                parent_stmt != node.parent and
 
776
                not self.isLiteralTupleUnpacking(parent_stmt)):
 
777
            binding = Binding(name, node)
 
778
        elif name == '__all__' and isinstance(self.scope, ModuleScope):
 
779
            binding = ExportBinding(name, node.parent, self.scope)
 
780
        else:
 
781
            binding = Assignment(name, node)
 
782
        self.addBinding(node, binding)
 
783
 
 
784
    def handleNodeDelete(self, node):
 
785
 
 
786
        def on_conditional_branch():
 
787
            """
 
788
            Return `True` if node is part of a conditional body.
 
789
            """
 
790
            current = getattr(node, 'parent', None)
 
791
            while current:
 
792
                if isinstance(current, (ast.If, ast.While, ast.IfExp)):
 
793
                    return True
 
794
                current = getattr(current, 'parent', None)
 
795
            return False
 
796
 
 
797
        name = getNodeName(node)
 
798
        if not name:
 
799
            return
 
800
 
 
801
        if on_conditional_branch():
 
802
            # We cannot predict if this conditional branch is going to
 
803
            # be executed.
 
804
            return
 
805
 
 
806
        if isinstance(self.scope, FunctionScope) and name in self.scope.globals:
 
807
            self.scope.globals.remove(name)
 
808
        else:
 
809
            try:
 
810
                del self.scope[name]
 
811
            except KeyError:
 
812
                self.report(messages.UndefinedName, node, name)
 
813
 
 
814
    def handleChildren(self, tree, omit=None):
 
815
        for node in iter_child_nodes(tree, omit=omit):
 
816
            self.handleNode(node, tree)
 
817
 
 
818
    def isLiteralTupleUnpacking(self, node):
 
819
        if isinstance(node, ast.Assign):
 
820
            for child in node.targets + [node.value]:
 
821
                if not hasattr(child, 'elts'):
 
822
                    return False
 
823
            return True
 
824
 
 
825
    def isDocstring(self, node):
 
826
        """
 
827
        Determine if the given node is a docstring, as long as it is at the
 
828
        correct place in the node tree.
 
829
        """
 
830
        return isinstance(node, ast.Str) or (isinstance(node, ast.Expr) and
 
831
                                             isinstance(node.value, ast.Str))
 
832
 
 
833
    def getDocstring(self, node):
 
834
        if isinstance(node, ast.Expr):
 
835
            node = node.value
 
836
        if not isinstance(node, ast.Str):
 
837
            return (None, None)
 
838
 
 
839
        if PYPY:
 
840
            doctest_lineno = node.lineno - 1
 
841
        else:
 
842
            # Computed incorrectly if the docstring has backslash
 
843
            doctest_lineno = node.lineno - node.s.count('\n') - 1
 
844
 
 
845
        return (node.s, doctest_lineno)
 
846
 
 
847
    def handleNode(self, node, parent):
 
848
        if node is None:
 
849
            return
 
850
        if self.offset and getattr(node, 'lineno', None) is not None:
 
851
            node.lineno += self.offset[0]
 
852
            node.col_offset += self.offset[1]
 
853
        if self.traceTree:
 
854
            print('  ' * self.nodeDepth + node.__class__.__name__)
 
855
        if self.futuresAllowed and not (isinstance(node, ast.ImportFrom) or
 
856
                                        self.isDocstring(node)):
 
857
            self.futuresAllowed = False
 
858
        self.nodeDepth += 1
 
859
        node.depth = self.nodeDepth
 
860
        node.parent = parent
 
861
        try:
 
862
            handler = self.getNodeHandler(node.__class__)
 
863
            handler(node)
 
864
        finally:
 
865
            self.nodeDepth -= 1
 
866
        if self.traceTree:
 
867
            print('  ' * self.nodeDepth + 'end ' + node.__class__.__name__)
 
868
 
 
869
    _getDoctestExamples = doctest.DocTestParser().get_examples
 
870
 
 
871
    def handleDoctests(self, node):
 
872
        try:
 
873
            (docstring, node_lineno) = self.getDocstring(node.body[0])
 
874
            examples = docstring and self._getDoctestExamples(docstring)
 
875
        except (ValueError, IndexError):
 
876
            # e.g. line 6 of the docstring for <string> has inconsistent
 
877
            # leading whitespace: ...
 
878
            return
 
879
        if not examples:
 
880
            return
 
881
 
 
882
        # Place doctest in module scope
 
883
        saved_stack = self.scopeStack
 
884
        self.scopeStack = [self.scopeStack[0]]
 
885
        node_offset = self.offset or (0, 0)
 
886
        self.pushScope(DoctestScope)
 
887
        underscore_in_builtins = '_' in self.builtIns
 
888
        if not underscore_in_builtins:
 
889
            self.builtIns.add('_')
 
890
        for example in examples:
 
891
            try:
 
892
                tree = compile(example.source, "<doctest>", "exec", ast.PyCF_ONLY_AST)
 
893
            except SyntaxError:
 
894
                e = sys.exc_info()[1]
 
895
                if PYPY:
 
896
                    e.offset += 1
 
897
                position = (node_lineno + example.lineno + e.lineno,
 
898
                            example.indent + 4 + (e.offset or 0))
 
899
                self.report(messages.DoctestSyntaxError, node, position)
 
900
            else:
 
901
                self.offset = (node_offset[0] + node_lineno + example.lineno,
 
902
                               node_offset[1] + example.indent + 4)
 
903
                self.handleChildren(tree)
 
904
                self.offset = node_offset
 
905
        if not underscore_in_builtins:
 
906
            self.builtIns.remove('_')
 
907
        self.popScope()
 
908
        self.scopeStack = saved_stack
 
909
 
 
910
    def ignore(self, node):
 
911
        pass
 
912
 
 
913
    # "stmt" type nodes
 
914
    DELETE = PRINT = FOR = ASYNCFOR = WHILE = IF = WITH = WITHITEM = \
 
915
        ASYNCWITH = ASYNCWITHITEM = RAISE = TRYFINALLY = EXEC = \
 
916
        EXPR = ASSIGN = handleChildren
 
917
 
 
918
    PASS = ignore
 
919
 
 
920
    # "expr" type nodes
 
921
    BOOLOP = BINOP = UNARYOP = IFEXP = SET = \
 
922
        COMPARE = CALL = REPR = ATTRIBUTE = SUBSCRIPT = \
 
923
        STARRED = NAMECONSTANT = handleChildren
 
924
 
 
925
    NUM = STR = BYTES = ELLIPSIS = ignore
 
926
 
 
927
    # "slice" type nodes
 
928
    SLICE = EXTSLICE = INDEX = handleChildren
 
929
 
 
930
    # expression contexts are node instances too, though being constants
 
931
    LOAD = STORE = DEL = AUGLOAD = AUGSTORE = PARAM = ignore
 
932
 
 
933
    # same for operators
 
934
    AND = OR = ADD = SUB = MULT = DIV = MOD = POW = LSHIFT = RSHIFT = \
 
935
        BITOR = BITXOR = BITAND = FLOORDIV = INVERT = NOT = UADD = USUB = \
 
936
        EQ = NOTEQ = LT = LTE = GT = GTE = IS = ISNOT = IN = NOTIN = \
 
937
        MATMULT = ignore
 
938
 
 
939
    # additional node types
 
940
    COMPREHENSION = KEYWORD = FORMATTEDVALUE = JOINEDSTR = handleChildren
 
941
 
 
942
    def DICT(self, node):
 
943
        # Complain if there are duplicate keys with different values
 
944
        # If they have the same value it's not going to cause potentially
 
945
        # unexpected behaviour so we'll not complain.
 
946
        keys = [
 
947
            convert_to_value(key) for key in node.keys
 
948
        ]
 
949
 
 
950
        key_counts = counter(keys)
 
951
        duplicate_keys = [
 
952
            key for key, count in key_counts.items()
 
953
            if count > 1
 
954
        ]
 
955
 
 
956
        for key in duplicate_keys:
 
957
            key_indices = [i for i, i_key in enumerate(keys) if i_key == key]
 
958
 
 
959
            values = counter(
 
960
                convert_to_value(node.values[index])
 
961
                for index in key_indices
 
962
            )
 
963
            if any(count == 1 for value, count in values.items()):
 
964
                for key_index in key_indices:
 
965
                    key_node = node.keys[key_index]
 
966
                    if isinstance(key, VariableKey):
 
967
                        self.report(messages.MultiValueRepeatedKeyVariable,
 
968
                                    key_node,
 
969
                                    key.name)
 
970
                    else:
 
971
                        self.report(
 
972
                            messages.MultiValueRepeatedKeyLiteral,
 
973
                            key_node,
 
974
                            key,
 
975
                        )
 
976
        self.handleChildren(node)
 
977
 
 
978
    def ASSERT(self, node):
 
979
        if isinstance(node.test, ast.Tuple) and node.test.elts != []:
 
980
            self.report(messages.AssertTuple, node)
 
981
        self.handleChildren(node)
 
982
 
 
983
    def GLOBAL(self, node):
 
984
        """
 
985
        Keep track of globals declarations.
 
986
        """
 
987
        global_scope_index = 1 if self._in_doctest() else 0
 
988
        global_scope = self.scopeStack[global_scope_index]
 
989
 
 
990
        # Ignore 'global' statement in global scope.
 
991
        if self.scope is not global_scope:
 
992
 
 
993
            # One 'global' statement can bind multiple (comma-delimited) names.
 
994
            for node_name in node.names:
 
995
                node_value = Assignment(node_name, node)
 
996
 
 
997
                # Remove UndefinedName messages already reported for this name.
 
998
                # TODO: if the global is not used in this scope, it does not
 
999
                # become a globally defined name.  See test_unused_global.
 
1000
                self.messages = [
 
1001
                    m for m in self.messages if not
 
1002
                    isinstance(m, messages.UndefinedName) or
 
1003
                    m.message_args[0] != node_name]
 
1004
 
 
1005
                # Bind name to global scope if it doesn't exist already.
 
1006
                global_scope.setdefault(node_name, node_value)
 
1007
 
 
1008
                # Bind name to non-global scopes, but as already "used".
 
1009
                node_value.used = (global_scope, node)
 
1010
                for scope in self.scopeStack[global_scope_index + 1:]:
 
1011
                    scope[node_name] = node_value
 
1012
 
 
1013
    NONLOCAL = GLOBAL
 
1014
 
 
1015
    def GENERATOREXP(self, node):
 
1016
        self.pushScope(GeneratorScope)
 
1017
        self.handleChildren(node)
 
1018
        self.popScope()
 
1019
 
 
1020
    LISTCOMP = handleChildren if PY2 else GENERATOREXP
 
1021
 
 
1022
    DICTCOMP = SETCOMP = GENERATOREXP
 
1023
 
 
1024
    def NAME(self, node):
 
1025
        """
 
1026
        Handle occurrence of Name (which can be a load/store/delete access.)
 
1027
        """
 
1028
        # Locate the name in locals / function / globals scopes.
 
1029
        if isinstance(node.ctx, (ast.Load, ast.AugLoad)):
 
1030
            self.handleNodeLoad(node)
 
1031
            if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
 
1032
                    and isinstance(node.parent, ast.Call)):
 
1033
                # we are doing locals() call in current scope
 
1034
                self.scope.usesLocals = True
 
1035
        elif isinstance(node.ctx, (ast.Store, ast.AugStore)):
 
1036
            self.handleNodeStore(node)
 
1037
        elif isinstance(node.ctx, ast.Del):
 
1038
            self.handleNodeDelete(node)
 
1039
        else:
 
1040
            # must be a Param context -- this only happens for names in function
 
1041
            # arguments, but these aren't dispatched through here
 
1042
            raise RuntimeError("Got impossible expression context: %r" % (node.ctx,))
 
1043
 
 
1044
    def CONTINUE(self, node):
 
1045
        # Walk the tree up until we see a loop (OK), a function or class
 
1046
        # definition (not OK), for 'continue', a finally block (not OK), or
 
1047
        # the top module scope (not OK)
 
1048
        n = node
 
1049
        while hasattr(n, 'parent'):
 
1050
            n, n_child = n.parent, n
 
1051
            if isinstance(n, LOOP_TYPES):
 
1052
                # Doesn't apply unless it's in the loop itself
 
1053
                if n_child not in n.orelse:
 
1054
                    return
 
1055
            if isinstance(n, (ast.FunctionDef, ast.ClassDef)):
 
1056
                break
 
1057
            # Handle Try/TryFinally difference in Python < and >= 3.3
 
1058
            if hasattr(n, 'finalbody') and isinstance(node, ast.Continue):
 
1059
                if n_child in n.finalbody:
 
1060
                    self.report(messages.ContinueInFinally, node)
 
1061
                    return
 
1062
        if isinstance(node, ast.Continue):
 
1063
            self.report(messages.ContinueOutsideLoop, node)
 
1064
        else:  # ast.Break
 
1065
            self.report(messages.BreakOutsideLoop, node)
 
1066
 
 
1067
    BREAK = CONTINUE
 
1068
 
 
1069
    def RETURN(self, node):
 
1070
        if isinstance(self.scope, (ClassScope, ModuleScope)):
 
1071
            self.report(messages.ReturnOutsideFunction, node)
 
1072
            return
 
1073
 
 
1074
        if (
 
1075
            node.value and
 
1076
            hasattr(self.scope, 'returnValue') and
 
1077
            not self.scope.returnValue
 
1078
        ):
 
1079
            self.scope.returnValue = node.value
 
1080
        self.handleNode(node.value, node)
 
1081
 
 
1082
    def YIELD(self, node):
 
1083
        if isinstance(self.scope, (ClassScope, ModuleScope)):
 
1084
            self.report(messages.YieldOutsideFunction, node)
 
1085
            return
 
1086
 
 
1087
        self.scope.isGenerator = True
 
1088
        self.handleNode(node.value, node)
 
1089
 
 
1090
    AWAIT = YIELDFROM = YIELD
 
1091
 
 
1092
    def FUNCTIONDEF(self, node):
 
1093
        for deco in node.decorator_list:
 
1094
            self.handleNode(deco, node)
 
1095
        self.LAMBDA(node)
 
1096
        self.addBinding(node, FunctionDefinition(node.name, node))
 
1097
        # doctest does not process doctest within a doctest,
 
1098
        # or in nested functions.
 
1099
        if (self.withDoctest and
 
1100
                not self._in_doctest() and
 
1101
                not isinstance(self.scope, FunctionScope)):
 
1102
            self.deferFunction(lambda: self.handleDoctests(node))
 
1103
 
 
1104
    ASYNCFUNCTIONDEF = FUNCTIONDEF
 
1105
 
 
1106
    def LAMBDA(self, node):
 
1107
        args = []
 
1108
        annotations = []
 
1109
 
 
1110
        if PY2:
 
1111
            def addArgs(arglist):
 
1112
                for arg in arglist:
 
1113
                    if isinstance(arg, ast.Tuple):
 
1114
                        addArgs(arg.elts)
 
1115
                    else:
 
1116
                        args.append(arg.id)
 
1117
            addArgs(node.args.args)
 
1118
            defaults = node.args.defaults
 
1119
        else:
 
1120
            for arg in node.args.args + node.args.kwonlyargs:
 
1121
                args.append(arg.arg)
 
1122
                annotations.append(arg.annotation)
 
1123
            defaults = node.args.defaults + node.args.kw_defaults
 
1124
 
 
1125
        # Only for Python3 FunctionDefs
 
1126
        is_py3_func = hasattr(node, 'returns')
 
1127
 
 
1128
        for arg_name in ('vararg', 'kwarg'):
 
1129
            wildcard = getattr(node.args, arg_name)
 
1130
            if not wildcard:
 
1131
                continue
 
1132
            args.append(wildcard if PY33 else wildcard.arg)
 
1133
            if is_py3_func:
 
1134
                if PY33:  # Python 2.5 to 3.3
 
1135
                    argannotation = arg_name + 'annotation'
 
1136
                    annotations.append(getattr(node.args, argannotation))
 
1137
                else:     # Python >= 3.4
 
1138
                    annotations.append(wildcard.annotation)
 
1139
 
 
1140
        if is_py3_func:
 
1141
            annotations.append(node.returns)
 
1142
 
 
1143
        if len(set(args)) < len(args):
 
1144
            for (idx, arg) in enumerate(args):
 
1145
                if arg in args[:idx]:
 
1146
                    self.report(messages.DuplicateArgument, node, arg)
 
1147
 
 
1148
        for child in annotations + defaults:
 
1149
            if child:
 
1150
                self.handleNode(child, node)
 
1151
 
 
1152
        def runFunction():
 
1153
 
 
1154
            self.pushScope()
 
1155
            for name in args:
 
1156
                self.addBinding(node, Argument(name, node))
 
1157
            if isinstance(node.body, list):
 
1158
                # case for FunctionDefs
 
1159
                for stmt in node.body:
 
1160
                    self.handleNode(stmt, node)
 
1161
            else:
 
1162
                # case for Lambdas
 
1163
                self.handleNode(node.body, node)
 
1164
 
 
1165
            def checkUnusedAssignments():
 
1166
                """
 
1167
                Check to see if any assignments have not been used.
 
1168
                """
 
1169
                for name, binding in self.scope.unusedAssignments():
 
1170
                    self.report(messages.UnusedVariable, binding.source, name)
 
1171
            self.deferAssignment(checkUnusedAssignments)
 
1172
 
 
1173
            if PY32:
 
1174
                def checkReturnWithArgumentInsideGenerator():
 
1175
                    """
 
1176
                    Check to see if there is any return statement with
 
1177
                    arguments but the function is a generator.
 
1178
                    """
 
1179
                    if self.scope.isGenerator and self.scope.returnValue:
 
1180
                        self.report(messages.ReturnWithArgsInsideGenerator,
 
1181
                                    self.scope.returnValue)
 
1182
                self.deferAssignment(checkReturnWithArgumentInsideGenerator)
 
1183
            self.popScope()
 
1184
 
 
1185
        self.deferFunction(runFunction)
 
1186
 
 
1187
    def CLASSDEF(self, node):
 
1188
        """
 
1189
        Check names used in a class definition, including its decorators, base
 
1190
        classes, and the body of its definition.  Additionally, add its name to
 
1191
        the current scope.
 
1192
        """
 
1193
        for deco in node.decorator_list:
 
1194
            self.handleNode(deco, node)
 
1195
        for baseNode in node.bases:
 
1196
            self.handleNode(baseNode, node)
 
1197
        if not PY2:
 
1198
            for keywordNode in node.keywords:
 
1199
                self.handleNode(keywordNode, node)
 
1200
        self.pushScope(ClassScope)
 
1201
        # doctest does not process doctest within a doctest
 
1202
        # classes within classes are processed.
 
1203
        if (self.withDoctest and
 
1204
                not self._in_doctest() and
 
1205
                not isinstance(self.scope, FunctionScope)):
 
1206
            self.deferFunction(lambda: self.handleDoctests(node))
 
1207
        for stmt in node.body:
 
1208
            self.handleNode(stmt, node)
 
1209
        self.popScope()
 
1210
        self.addBinding(node, ClassDefinition(node.name, node))
 
1211
 
 
1212
    def AUGASSIGN(self, node):
 
1213
        self.handleNodeLoad(node.target)
 
1214
        self.handleNode(node.value, node)
 
1215
        self.handleNode(node.target, node)
 
1216
 
 
1217
    def TUPLE(self, node):
 
1218
        if not PY2 and isinstance(node.ctx, ast.Store):
 
1219
            # Python 3 advanced tuple unpacking: a, *b, c = d.
 
1220
            # Only one starred expression is allowed, and no more than 1<<8
 
1221
            # assignments are allowed before a stared expression. There is
 
1222
            # also a limit of 1<<24 expressions after the starred expression,
 
1223
            # which is impossible to test due to memory restrictions, but we
 
1224
            # add it here anyway
 
1225
            has_starred = False
 
1226
            star_loc = -1
 
1227
            for i, n in enumerate(node.elts):
 
1228
                if isinstance(n, ast.Starred):
 
1229
                    if has_starred:
 
1230
                        self.report(messages.TwoStarredExpressions, node)
 
1231
                        # The SyntaxError doesn't distinguish two from more
 
1232
                        # than two.
 
1233
                        break
 
1234
                    has_starred = True
 
1235
                    star_loc = i
 
1236
            if star_loc >= 1 << 8 or len(node.elts) - star_loc - 1 >= 1 << 24:
 
1237
                self.report(messages.TooManyExpressionsInStarredAssignment, node)
 
1238
        self.handleChildren(node)
 
1239
 
 
1240
    LIST = TUPLE
 
1241
 
 
1242
    def IMPORT(self, node):
 
1243
        for alias in node.names:
 
1244
            if '.' in alias.name and not alias.asname:
 
1245
                importation = SubmoduleImportation(alias.name, node)
 
1246
            else:
 
1247
                name = alias.asname or alias.name
 
1248
                importation = Importation(name, node, alias.name)
 
1249
            self.addBinding(node, importation)
 
1250
 
 
1251
    def IMPORTFROM(self, node):
 
1252
        if node.module == '__future__':
 
1253
            if not self.futuresAllowed:
 
1254
                self.report(messages.LateFutureImport,
 
1255
                            node, [n.name for n in node.names])
 
1256
        else:
 
1257
            self.futuresAllowed = False
 
1258
 
 
1259
        module = ('.' * node.level) + (node.module or '')
 
1260
 
 
1261
        for alias in node.names:
 
1262
            name = alias.asname or alias.name
 
1263
            if node.module == '__future__':
 
1264
                importation = FutureImportation(name, node, self.scope)
 
1265
                if alias.name not in __future__.all_feature_names:
 
1266
                    self.report(messages.FutureFeatureNotDefined,
 
1267
                                node, alias.name)
 
1268
            elif alias.name == '*':
 
1269
                # Only Python 2, local import * is a SyntaxWarning
 
1270
                if not PY2 and not isinstance(self.scope, ModuleScope):
 
1271
                    self.report(messages.ImportStarNotPermitted,
 
1272
                                node, module)
 
1273
                    continue
 
1274
 
 
1275
                self.scope.importStarred = True
 
1276
                self.report(messages.ImportStarUsed, node, module)
 
1277
                importation = StarImportation(module, node)
 
1278
            else:
 
1279
                importation = ImportationFrom(name, node,
 
1280
                                              module, alias.name)
 
1281
            self.addBinding(node, importation)
 
1282
 
 
1283
    def TRY(self, node):
 
1284
        handler_names = []
 
1285
        # List the exception handlers
 
1286
        for i, handler in enumerate(node.handlers):
 
1287
            if isinstance(handler.type, ast.Tuple):
 
1288
                for exc_type in handler.type.elts:
 
1289
                    handler_names.append(getNodeName(exc_type))
 
1290
            elif handler.type:
 
1291
                handler_names.append(getNodeName(handler.type))
 
1292
 
 
1293
            if handler.type is None and i < len(node.handlers) - 1:
 
1294
                self.report(messages.DefaultExceptNotLast, handler)
 
1295
        # Memorize the except handlers and process the body
 
1296
        self.exceptHandlers.append(handler_names)
 
1297
        for child in node.body:
 
1298
            self.handleNode(child, node)
 
1299
        self.exceptHandlers.pop()
 
1300
        # Process the other nodes: "except:", "else:", "finally:"
 
1301
        self.handleChildren(node, omit='body')
 
1302
 
 
1303
    TRYEXCEPT = TRY
 
1304
 
 
1305
    def EXCEPTHANDLER(self, node):
 
1306
        if PY2 or node.name is None:
 
1307
            self.handleChildren(node)
 
1308
            return
 
1309
 
 
1310
        # 3.x: the name of the exception, which is not a Name node, but
 
1311
        # a simple string, creates a local that is only bound within the scope
 
1312
        # of the except: block.
 
1313
 
 
1314
        for scope in self.scopeStack[::-1]:
 
1315
            if node.name in scope:
 
1316
                is_name_previously_defined = True
 
1317
                break
 
1318
        else:
 
1319
            is_name_previously_defined = False
 
1320
 
 
1321
        self.handleNodeStore(node)
 
1322
        self.handleChildren(node)
 
1323
        if not is_name_previously_defined:
 
1324
            # See discussion on https://github.com/PyCQA/pyflakes/pull/59
 
1325
 
 
1326
            # We're removing the local name since it's being unbound
 
1327
            # after leaving the except: block and it's always unbound
 
1328
            # if the except: block is never entered. This will cause an
 
1329
            # "undefined name" error raised if the checked code tries to
 
1330
            # use the name afterwards.
 
1331
            #
 
1332
            # Unless it's been removed already. Then do nothing.
 
1333
 
 
1334
            try:
 
1335
                del self.scope[node.name]
 
1336
            except KeyError:
 
1337
                pass
 
1338
 
 
1339
    def ANNASSIGN(self, node):
 
1340
        """
 
1341
        Annotated assignments don't have annotations evaluated on function
 
1342
        scope, hence the custom implementation.
 
1343
 
 
1344
        See: PEP 526.
 
1345
        """
 
1346
        if node.value:
 
1347
            # Only bind the *targets* if the assignment has a value.
 
1348
            # Otherwise it's not really ast.Store and shouldn't silence
 
1349
            # UndefinedLocal warnings.
 
1350
            self.handleNode(node.target, node)
 
1351
        if not isinstance(self.scope, FunctionScope):
 
1352
            self.handleNode(node.annotation, node)
 
1353
        if node.value:
 
1354
            # If the assignment has value, handle the *value* now.
 
1355
            self.handleNode(node.value, node)