2
from _ast import PyCF_ONLY_AST
3
from sys import version_info
5
from pyflakes import messages as m, checker
6
from pyflakes.test.harness import TestCase, skipIf, skip
10
def test_undefined(self):
11
self.flakes('bar', m.UndefinedName)
13
def test_definedInListComp(self):
14
self.flakes('[a for a in range(10) if a]')
16
@skipIf(version_info < (3,),
17
'in Python 2 list comprehensions execute in the same scope')
18
def test_undefinedInListComp(self):
20
[a for a in range(10)]
25
@skipIf(version_info < (3,),
26
'in Python 2 exception names stay bound after the except: block')
27
def test_undefinedExceptionName(self):
28
"""Exception names can't be used after the except: block."""
31
raise ValueError('ve')
32
except ValueError as exc:
38
def test_namesDeclaredInExceptBlocks(self):
39
"""Locals declared in except: blocks can be used after the block.
41
This shows the example in test_undefinedExceptionName is
45
raise ValueError('ve')
46
except ValueError as exc:
51
@skip('error reporting disabled due to false positives below')
52
def test_undefinedExceptionNameObscuringLocalVariable(self):
53
"""Exception names obscure locals, can't be used after.
55
Last line will raise UnboundLocalError on Python 3 after exiting
56
the except: block. Note next two examples for false positives to
59
exc = 'Original value'
61
raise ValueError('ve')
62
except ValueError as exc:
68
@skipIf(version_info < (3,),
69
'in Python 2 exception names stay bound after the except: block')
70
def test_undefinedExceptionNameObscuringLocalVariable2(self):
71
"""Exception names are unbound after the `except:` block.
73
Last line will raise UnboundLocalError on Python 3 but would print out
77
raise ValueError('ve')
78
except ValueError as exc:
81
exc = 'Original value'
85
def test_undefinedExceptionNameObscuringLocalVariableFalsePositive1(self):
86
"""Exception names obscure locals, can't be used after. Unless.
88
Last line will never raise UnboundLocalError because it's only
89
entered if no exception was raised."""
91
exc = 'Original value'
93
raise ValueError('ve')
94
except ValueError as exc:
95
print('exception logged')
100
def test_delExceptionInExcept(self):
101
"""The exception name can be deleted in the except: block."""
105
except Exception as exc:
109
def test_undefinedExceptionNameObscuringLocalVariableFalsePositive2(self):
110
"""Exception names obscure locals, can't be used after. Unless.
112
Last line will never raise UnboundLocalError because `error` is
113
only falsy if the `except:` block has not been entered."""
115
exc = 'Original value'
118
raise ValueError('ve')
119
except ValueError as exc:
120
error = 'exception logged'
127
@skip('error reporting disabled due to false positives below')
128
def test_undefinedExceptionNameObscuringGlobalVariable(self):
129
"""Exception names obscure globals, can't be used after.
131
Last line will raise UnboundLocalError on both Python 2 and
132
Python 3 because the existence of that exception name creates
133
a local scope placeholder for it, obscuring any globals, etc."""
135
exc = 'Original value'
138
pass # nothing is raised
139
except ValueError as exc:
140
pass # block never entered, exc stays unbound
145
@skip('error reporting disabled due to false positives below')
146
def test_undefinedExceptionNameObscuringGlobalVariable2(self):
147
"""Exception names obscure globals, can't be used after.
149
Last line will raise NameError on Python 3 because the name is
150
locally unbound after the `except:` block, even if it's
151
nonlocal. We should issue an error in this case because code
152
only working correctly if an exception isn't raised, is invalid.
153
Unless it's explicitly silenced, see false positives below."""
155
exc = 'Original value'
159
raise ValueError('ve')
160
except ValueError as exc:
161
pass # block never entered, exc stays unbound
166
def test_undefinedExceptionNameObscuringGlobalVariableFalsePositive1(self):
167
"""Exception names obscure globals, can't be used after. Unless.
169
Last line will never raise NameError because it's only entered
170
if no exception was raised."""
172
exc = 'Original value'
176
raise ValueError('ve')
177
except ValueError as exc:
178
print('exception logged')
183
def test_undefinedExceptionNameObscuringGlobalVariableFalsePositive2(self):
184
"""Exception names obscure globals, can't be used after. Unless.
186
Last line will never raise NameError because `error` is only
187
falsy if the `except:` block has not been entered."""
189
exc = 'Original value'
194
raise ValueError('ve')
195
except ValueError as exc:
196
error = 'exception logged'
203
def test_functionsNeedGlobalScope(self):
211
def test_builtins(self):
212
self.flakes('range(10)')
214
def test_builtinWindowsError(self):
216
C{WindowsError} is sometimes a builtin name, so no warning is emitted
219
self.flakes('WindowsError')
221
def test_magicGlobalsFile(self):
223
Use of the C{__file__} magic global should not emit an undefined name
226
self.flakes('__file__')
228
def test_magicGlobalsBuiltins(self):
230
Use of the C{__builtins__} magic global should not emit an undefined
233
self.flakes('__builtins__')
235
def test_magicGlobalsName(self):
237
Use of the C{__name__} magic global should not emit an undefined name
240
self.flakes('__name__')
242
def test_magicGlobalsPath(self):
244
Use of the C{__path__} magic global should not emit an undefined name
245
warning, if you refer to it from a file called __init__.py.
247
self.flakes('__path__', m.UndefinedName)
248
self.flakes('__path__', filename='package/__init__.py')
250
def test_globalImportStar(self):
251
"""Can't find undefined names with import *."""
252
self.flakes('from fu import *; bar',
253
m.ImportStarUsed, m.ImportStarUsage)
255
@skipIf(version_info >= (3,), 'obsolete syntax')
256
def test_localImportStar(self):
258
A local import * still allows undefined names to be found
265
''', m.ImportStarUsed, m.UndefinedName, m.UnusedImport)
267
@skipIf(version_info >= (3,), 'obsolete syntax')
268
def test_unpackedParameter(self):
269
"""Unpacked function parameters create bindings."""
275
def test_definedByGlobal(self):
277
"global" can make an otherwise undefined name in another function
281
def a(): global fu; fu = 1
286
def b(): global bar; bar = 1
289
def test_definedByGlobalMultipleNames(self):
291
"global" can accept multiple names.
294
def a(): global fu, bar; fu = 1; bar = 2
298
def test_globalInGlobalScope(self):
300
A global statement in the global scope is ignored.
306
''', m.UndefinedName)
308
def test_global_reset_name_only(self):
309
"""A global statement does not prevent other names being undefined."""
310
# Only different undefined names are reported.
311
# See following test that fails where the same name is used.
318
''', m.UndefinedName)
321
def test_unused_global(self):
322
"""An unused global statement does not define the name."""
329
''', m.UndefinedName)
332
"""Del deletes bindings."""
333
self.flakes('a = 1; del a; a', m.UndefinedName)
335
def test_delGlobal(self):
336
"""Del a global binding from a function."""
345
def test_delUndefined(self):
346
"""Del an undefined name."""
347
self.flakes('del a', m.UndefinedName)
349
def test_delConditional(self):
351
Ignores conditional bindings deletion.
361
def test_delConditionalNested(self):
363
Ignored conditional bindings deletion even if they are nested in other
375
def test_delWhile(self):
377
Ignore bindings deletion if called inside the body of a while
388
def test_delWhileTestUsage(self):
390
Ignore bindings deletion if called inside the body of a while
391
statement and name is used inside while's test part.
401
def test_delWhileNested(self):
403
Ignore bindings deletions if node is part of while's test, even when
404
del is in a nested block.
417
def test_globalFromNestedScope(self):
418
"""Global names are available from nested scopes."""
426
def test_laterRedefinedGlobalFromNestedScope(self):
428
Test that referencing a local name that shadows a global, before it is
429
defined, generates a warning.
437
''', m.UndefinedLocal)
439
def test_laterRedefinedGlobalFromNestedScope2(self):
441
Test that referencing a local name in a nested scope that shadows a
442
global declared in an enclosing scope, before it is defined, generates
453
''', m.UndefinedLocal)
455
def test_intermediateClassScopeIgnored(self):
457
If a name defined in an enclosing scope is shadowed by a local variable
458
and the name is used locally before it is bound, an unbound local
459
warning is emitted, even if there is a class scope between the enclosing
460
scope and the local scope.
471
''', m.UndefinedLocal)
473
def test_doubleNestingReportsClosestName(self):
475
Test that referencing a local name in a nested scope that shadows a
476
variable declared in two different outer scopes before it is defined
477
in the innermost scope generates an UnboundLocal warning which
478
refers to the nearest shadowed name.
480
exc = self.flakes('''
491
''', m.UndefinedLocal).messages[0]
493
# _DoctestMixin.flakes adds two lines preceding the code above.
494
expected_line_num = 7 if self.withDoctest else 5
496
self.assertEqual(exc.message_args, ('x', expected_line_num))
498
def test_laterRedefinedGlobalFromNestedScope3(self):
500
Test that referencing a local name in a nested scope that shadows a
501
global, before it is defined, generates a warning.
511
''', m.UndefinedLocal)
513
def test_undefinedAugmentedAssignment(self):
527
m.UndefinedName, m.UnusedVariable, # d
531
def test_nestedClass(self):
532
"""Nested classes can access enclosing scope."""
544
def test_badNestedClass(self):
545
"""Free variables in nested classes must bind at class creation."""
553
''', m.UndefinedName)
555
def test_definedAsStarArgs(self):
556
"""Star and double-star arg names are defined."""
562
@skipIf(version_info < (3,), 'new in Python 3')
563
def test_definedAsStarUnpack(self):
564
"""Star names in unpack are defined."""
578
@skipIf(version_info < (3,), 'new in Python 3')
579
def test_usedAsStarUnpack(self):
581
Star names in unpack are used if RHS is not a tuple/list literal.
593
[a, *b, c] = range(10)
596
@skipIf(version_info < (3,), 'new in Python 3')
597
def test_unusedAsStarUnpack(self):
599
Star names in unpack are unused if RHS is a tuple/list literal.
603
a, *b = any, all, 4, 2, 'un'
604
''', m.UnusedVariable, m.UnusedVariable)
607
(*a, b) = [bool, int, float, complex]
608
''', m.UnusedVariable, m.UnusedVariable)
611
[a, *b, c] = 9, 8, 7, 6, 5, 4
612
''', m.UnusedVariable, m.UnusedVariable, m.UnusedVariable)
614
@skipIf(version_info < (3,), 'new in Python 3')
615
def test_keywordOnlyArgs(self):
616
"""Keyword-only arg names are defined."""
624
def f(*, a, b=default_b):
628
@skipIf(version_info < (3,), 'new in Python 3')
629
def test_keywordOnlyArgsUndefined(self):
630
"""Typo in kwonly name."""
632
def f(*, a, b=default_c):
634
''', m.UndefinedName)
636
@skipIf(version_info < (3,), 'new in Python 3')
637
def test_annotationUndefined(self):
638
"""Undefined annotations."""
640
from abc import note1, note2, note3, note4, note5
641
def func(a: note1, *args: note2,
642
b: note3=12, **kw: note4) -> note5: pass
648
def func(a: {1, d}) -> (lambda c: e): pass
651
@skipIf(version_info < (3,), 'new in Python 3')
652
def test_metaClassUndefined(self):
654
from abc import ABCMeta
655
class A(metaclass=ABCMeta): pass
658
def test_definedInGenExp(self):
660
Using the loop variable of a generator expression results in no
663
self.flakes('(a for a in [1, 2, 3] if a)')
665
self.flakes('(b for b in (a for a in [1, 2, 3] if a) if b)')
667
def test_undefinedInGenExpNested(self):
669
The loop variables of generator expressions nested together are
670
not defined in the other generator.
672
self.flakes('(b for b in (a for a in [1, 2, 3] if b) if b)',
675
self.flakes('(b for b in (a for a in [1, 2, 3] if a) if a)',
678
def test_undefinedWithErrorHandler(self):
680
Some compatibility code checks explicitly for NameError.
681
It should not trigger warnings.
691
_memoryview.contiguous
692
except (NameError, AttributeError):
693
raise RuntimeError("Python >= 3.3 is required")
695
# If NameError is not explicitly handled, generate a warning
701
''', m.UndefinedName)
707
''', m.UndefinedName)
709
def test_definedInClass(self):
711
Defined name for generator expressions and dict/set comprehension.
719
B = dict((i, str(i)) for i in T)
722
if version_info >= (2, 7):
731
def test_definedInClassNested(self):
732
"""Defined name for nested generator expressions in a class."""
737
Z = (x for x in (a for a in T))
740
def test_undefinedInLoop(self):
742
The loop variable is defined after the expression is computed.
747
''', m.UndefinedName)
749
[42 for i in range(i)]
750
''', m.UndefinedName)
752
(42 for i in range(i))
753
''', m.UndefinedName)
755
@skipIf(version_info < (2, 7), 'Dictionary comprehensions do not exist')
756
def test_definedFromLambdaInDictionaryComprehension(self):
758
Defined name referenced from a lambda function within a dict/set
762
{lambda: id(x) for x in range(10)}
765
def test_definedFromLambdaInGenerator(self):
767
Defined name referenced from a lambda function within a generator
771
any(lambda: id(x) for x in range(10))
774
@skipIf(version_info < (2, 7), 'Dictionary comprehensions do not exist')
775
def test_undefinedFromLambdaInDictionaryComprehension(self):
777
Undefined name referenced from a lambda function within a dict/set
781
{lambda: id(y) for x in range(10)}
782
''', m.UndefinedName)
784
def test_undefinedFromLambdaInComprehension(self):
786
Undefined name referenced from a lambda function within a generator
790
any(lambda: id(y) for x in range(10))
791
''', m.UndefinedName)
794
class NameTests(TestCase):
796
Tests for some extra cases of name handling.
798
def test_impossibleContext(self):
800
A Name node with an unrecognized context results in a RuntimeError being
803
tree = compile("x = 10", "<test>", "exec", PyCF_ONLY_AST)
804
# Make it into something unrecognizable.
805
tree.body[0].targets[0].ctx = object()
806
self.assertRaises(RuntimeError, checker.Checker, tree)