~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/test/test_undefined_names.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
from _ast import PyCF_ONLY_AST
 
3
from sys import version_info
 
4
 
 
5
from pyflakes import messages as m, checker
 
6
from pyflakes.test.harness import TestCase, skipIf, skip
 
7
 
 
8
 
 
9
class Test(TestCase):
 
10
    def test_undefined(self):
 
11
        self.flakes('bar', m.UndefinedName)
 
12
 
 
13
    def test_definedInListComp(self):
 
14
        self.flakes('[a for a in range(10) if a]')
 
15
 
 
16
    @skipIf(version_info < (3,),
 
17
            'in Python 2 list comprehensions execute in the same scope')
 
18
    def test_undefinedInListComp(self):
 
19
        self.flakes('''
 
20
        [a for a in range(10)]
 
21
        a
 
22
        ''',
 
23
                    m.UndefinedName)
 
24
 
 
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."""
 
29
        self.flakes('''
 
30
        try:
 
31
            raise ValueError('ve')
 
32
        except ValueError as exc:
 
33
            pass
 
34
        exc
 
35
        ''',
 
36
                    m.UndefinedName)
 
37
 
 
38
    def test_namesDeclaredInExceptBlocks(self):
 
39
        """Locals declared in except: blocks can be used after the block.
 
40
 
 
41
        This shows the example in test_undefinedExceptionName is
 
42
        different."""
 
43
        self.flakes('''
 
44
        try:
 
45
            raise ValueError('ve')
 
46
        except ValueError as exc:
 
47
            e = exc
 
48
        e
 
49
        ''')
 
50
 
 
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.
 
54
 
 
55
        Last line will raise UnboundLocalError on Python 3 after exiting
 
56
        the except: block. Note next two examples for false positives to
 
57
        watch out for."""
 
58
        self.flakes('''
 
59
        exc = 'Original value'
 
60
        try:
 
61
            raise ValueError('ve')
 
62
        except ValueError as exc:
 
63
            pass
 
64
        exc
 
65
        ''',
 
66
                    m.UndefinedName)
 
67
 
 
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.
 
72
 
 
73
        Last line will raise UnboundLocalError on Python 3 but would print out
 
74
        've' on Python 2."""
 
75
        self.flakes('''
 
76
        try:
 
77
            raise ValueError('ve')
 
78
        except ValueError as exc:
 
79
            pass
 
80
        print(exc)
 
81
        exc = 'Original value'
 
82
        ''',
 
83
                    m.UndefinedName)
 
84
 
 
85
    def test_undefinedExceptionNameObscuringLocalVariableFalsePositive1(self):
 
86
        """Exception names obscure locals, can't be used after. Unless.
 
87
 
 
88
        Last line will never raise UnboundLocalError because it's only
 
89
        entered if no exception was raised."""
 
90
        self.flakes('''
 
91
        exc = 'Original value'
 
92
        try:
 
93
            raise ValueError('ve')
 
94
        except ValueError as exc:
 
95
            print('exception logged')
 
96
            raise
 
97
        exc
 
98
        ''')
 
99
 
 
100
    def test_delExceptionInExcept(self):
 
101
        """The exception name can be deleted in the except: block."""
 
102
        self.flakes('''
 
103
        try:
 
104
            pass
 
105
        except Exception as exc:
 
106
            del exc
 
107
        ''')
 
108
 
 
109
    def test_undefinedExceptionNameObscuringLocalVariableFalsePositive2(self):
 
110
        """Exception names obscure locals, can't be used after. Unless.
 
111
 
 
112
        Last line will never raise UnboundLocalError because `error` is
 
113
        only falsy if the `except:` block has not been entered."""
 
114
        self.flakes('''
 
115
        exc = 'Original value'
 
116
        error = None
 
117
        try:
 
118
            raise ValueError('ve')
 
119
        except ValueError as exc:
 
120
            error = 'exception logged'
 
121
        if error:
 
122
            print(error)
 
123
        else:
 
124
            exc
 
125
        ''')
 
126
 
 
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.
 
130
 
 
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."""
 
134
        self.flakes('''
 
135
        exc = 'Original value'
 
136
        def func():
 
137
            try:
 
138
                pass  # nothing is raised
 
139
            except ValueError as exc:
 
140
                pass  # block never entered, exc stays unbound
 
141
            exc
 
142
        ''',
 
143
                    m.UndefinedLocal)
 
144
 
 
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.
 
148
 
 
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."""
 
154
        self.flakes('''
 
155
        exc = 'Original value'
 
156
        def func():
 
157
            global exc
 
158
            try:
 
159
                raise ValueError('ve')
 
160
            except ValueError as exc:
 
161
                pass  # block never entered, exc stays unbound
 
162
            exc
 
163
        ''',
 
164
                    m.UndefinedLocal)
 
165
 
 
166
    def test_undefinedExceptionNameObscuringGlobalVariableFalsePositive1(self):
 
167
        """Exception names obscure globals, can't be used after. Unless.
 
168
 
 
169
        Last line will never raise NameError because it's only entered
 
170
        if no exception was raised."""
 
171
        self.flakes('''
 
172
        exc = 'Original value'
 
173
        def func():
 
174
            global exc
 
175
            try:
 
176
                raise ValueError('ve')
 
177
            except ValueError as exc:
 
178
                print('exception logged')
 
179
                raise
 
180
            exc
 
181
        ''')
 
182
 
 
183
    def test_undefinedExceptionNameObscuringGlobalVariableFalsePositive2(self):
 
184
        """Exception names obscure globals, can't be used after. Unless.
 
185
 
 
186
        Last line will never raise NameError because `error` is only
 
187
        falsy if the `except:` block has not been entered."""
 
188
        self.flakes('''
 
189
        exc = 'Original value'
 
190
        def func():
 
191
            global exc
 
192
            error = None
 
193
            try:
 
194
                raise ValueError('ve')
 
195
            except ValueError as exc:
 
196
                error = 'exception logged'
 
197
            if error:
 
198
                print(error)
 
199
            else:
 
200
                exc
 
201
        ''')
 
202
 
 
203
    def test_functionsNeedGlobalScope(self):
 
204
        self.flakes('''
 
205
        class a:
 
206
            def b():
 
207
                fu
 
208
        fu = 1
 
209
        ''')
 
210
 
 
211
    def test_builtins(self):
 
212
        self.flakes('range(10)')
 
213
 
 
214
    def test_builtinWindowsError(self):
 
215
        """
 
216
        C{WindowsError} is sometimes a builtin name, so no warning is emitted
 
217
        for using it.
 
218
        """
 
219
        self.flakes('WindowsError')
 
220
 
 
221
    def test_magicGlobalsFile(self):
 
222
        """
 
223
        Use of the C{__file__} magic global should not emit an undefined name
 
224
        warning.
 
225
        """
 
226
        self.flakes('__file__')
 
227
 
 
228
    def test_magicGlobalsBuiltins(self):
 
229
        """
 
230
        Use of the C{__builtins__} magic global should not emit an undefined
 
231
        name warning.
 
232
        """
 
233
        self.flakes('__builtins__')
 
234
 
 
235
    def test_magicGlobalsName(self):
 
236
        """
 
237
        Use of the C{__name__} magic global should not emit an undefined name
 
238
        warning.
 
239
        """
 
240
        self.flakes('__name__')
 
241
 
 
242
    def test_magicGlobalsPath(self):
 
243
        """
 
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.
 
246
        """
 
247
        self.flakes('__path__', m.UndefinedName)
 
248
        self.flakes('__path__', filename='package/__init__.py')
 
249
 
 
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)
 
254
 
 
255
    @skipIf(version_info >= (3,), 'obsolete syntax')
 
256
    def test_localImportStar(self):
 
257
        """
 
258
        A local import * still allows undefined names to be found
 
259
        in upper scopes.
 
260
        """
 
261
        self.flakes('''
 
262
        def a():
 
263
            from fu import *
 
264
        bar
 
265
        ''', m.ImportStarUsed, m.UndefinedName, m.UnusedImport)
 
266
 
 
267
    @skipIf(version_info >= (3,), 'obsolete syntax')
 
268
    def test_unpackedParameter(self):
 
269
        """Unpacked function parameters create bindings."""
 
270
        self.flakes('''
 
271
        def a((bar, baz)):
 
272
            bar; baz
 
273
        ''')
 
274
 
 
275
    def test_definedByGlobal(self):
 
276
        """
 
277
        "global" can make an otherwise undefined name in another function
 
278
        defined.
 
279
        """
 
280
        self.flakes('''
 
281
        def a(): global fu; fu = 1
 
282
        def b(): fu
 
283
        ''')
 
284
        self.flakes('''
 
285
        def c(): bar
 
286
        def b(): global bar; bar = 1
 
287
        ''')
 
288
 
 
289
    def test_definedByGlobalMultipleNames(self):
 
290
        """
 
291
        "global" can accept multiple names.
 
292
        """
 
293
        self.flakes('''
 
294
        def a(): global fu, bar; fu = 1; bar = 2
 
295
        def b(): fu; bar
 
296
        ''')
 
297
 
 
298
    def test_globalInGlobalScope(self):
 
299
        """
 
300
        A global statement in the global scope is ignored.
 
301
        """
 
302
        self.flakes('''
 
303
        global x
 
304
        def foo():
 
305
            print(x)
 
306
        ''', m.UndefinedName)
 
307
 
 
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.
 
312
        self.flakes('''
 
313
        def f1():
 
314
            s
 
315
 
 
316
        def f2():
 
317
            global m
 
318
        ''', m.UndefinedName)
 
319
 
 
320
    @skip("todo")
 
321
    def test_unused_global(self):
 
322
        """An unused global statement does not define the name."""
 
323
        self.flakes('''
 
324
        def f1():
 
325
            m
 
326
 
 
327
        def f2():
 
328
            global m
 
329
        ''', m.UndefinedName)
 
330
 
 
331
    def test_del(self):
 
332
        """Del deletes bindings."""
 
333
        self.flakes('a = 1; del a; a', m.UndefinedName)
 
334
 
 
335
    def test_delGlobal(self):
 
336
        """Del a global binding from a function."""
 
337
        self.flakes('''
 
338
        a = 1
 
339
        def f():
 
340
            global a
 
341
            del a
 
342
        a
 
343
        ''')
 
344
 
 
345
    def test_delUndefined(self):
 
346
        """Del an undefined name."""
 
347
        self.flakes('del a', m.UndefinedName)
 
348
 
 
349
    def test_delConditional(self):
 
350
        """
 
351
        Ignores conditional bindings deletion.
 
352
        """
 
353
        self.flakes('''
 
354
        context = None
 
355
        test = True
 
356
        if False:
 
357
            del(test)
 
358
        assert(test)
 
359
        ''')
 
360
 
 
361
    def test_delConditionalNested(self):
 
362
        """
 
363
        Ignored conditional bindings deletion even if they are nested in other
 
364
        blocks.
 
365
        """
 
366
        self.flakes('''
 
367
        context = None
 
368
        test = True
 
369
        if False:
 
370
            with context():
 
371
                del(test)
 
372
        assert(test)
 
373
        ''')
 
374
 
 
375
    def test_delWhile(self):
 
376
        """
 
377
        Ignore bindings deletion if called inside the body of a while
 
378
        statement.
 
379
        """
 
380
        self.flakes('''
 
381
        def test():
 
382
            foo = 'bar'
 
383
            while False:
 
384
                del foo
 
385
            assert(foo)
 
386
        ''')
 
387
 
 
388
    def test_delWhileTestUsage(self):
 
389
        """
 
390
        Ignore bindings deletion if called inside the body of a while
 
391
        statement and name is used inside while's test part.
 
392
        """
 
393
        self.flakes('''
 
394
        def _worker():
 
395
            o = True
 
396
            while o is not True:
 
397
                del o
 
398
                o = False
 
399
        ''')
 
400
 
 
401
    def test_delWhileNested(self):
 
402
        """
 
403
        Ignore bindings deletions if node is part of while's test, even when
 
404
        del is in a nested block.
 
405
        """
 
406
        self.flakes('''
 
407
        context = None
 
408
        def _worker():
 
409
            o = True
 
410
            while o is not True:
 
411
                while True:
 
412
                    with context():
 
413
                        del o
 
414
                o = False
 
415
        ''')
 
416
 
 
417
    def test_globalFromNestedScope(self):
 
418
        """Global names are available from nested scopes."""
 
419
        self.flakes('''
 
420
        a = 1
 
421
        def b():
 
422
            def c():
 
423
                a
 
424
        ''')
 
425
 
 
426
    def test_laterRedefinedGlobalFromNestedScope(self):
 
427
        """
 
428
        Test that referencing a local name that shadows a global, before it is
 
429
        defined, generates a warning.
 
430
        """
 
431
        self.flakes('''
 
432
        a = 1
 
433
        def fun():
 
434
            a
 
435
            a = 2
 
436
            return a
 
437
        ''', m.UndefinedLocal)
 
438
 
 
439
    def test_laterRedefinedGlobalFromNestedScope2(self):
 
440
        """
 
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
 
443
        a warning.
 
444
        """
 
445
        self.flakes('''
 
446
            a = 1
 
447
            def fun():
 
448
                global a
 
449
                def fun2():
 
450
                    a
 
451
                    a = 2
 
452
                    return a
 
453
        ''', m.UndefinedLocal)
 
454
 
 
455
    def test_intermediateClassScopeIgnored(self):
 
456
        """
 
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.
 
461
        """
 
462
        self.flakes('''
 
463
        def f():
 
464
            x = 1
 
465
            class g:
 
466
                def h(self):
 
467
                    a = x
 
468
                    x = None
 
469
                    print(x, a)
 
470
            print(x)
 
471
        ''', m.UndefinedLocal)
 
472
 
 
473
    def test_doubleNestingReportsClosestName(self):
 
474
        """
 
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.
 
479
        """
 
480
        exc = self.flakes('''
 
481
            def a():
 
482
                x = 1
 
483
                def b():
 
484
                    x = 2 # line 5
 
485
                    def c():
 
486
                        x
 
487
                        x = 3
 
488
                        return x
 
489
                    return x
 
490
                return x
 
491
        ''', m.UndefinedLocal).messages[0]
 
492
 
 
493
        # _DoctestMixin.flakes adds two lines preceding the code above.
 
494
        expected_line_num = 7 if self.withDoctest else 5
 
495
 
 
496
        self.assertEqual(exc.message_args, ('x', expected_line_num))
 
497
 
 
498
    def test_laterRedefinedGlobalFromNestedScope3(self):
 
499
        """
 
500
        Test that referencing a local name in a nested scope that shadows a
 
501
        global, before it is defined, generates a warning.
 
502
        """
 
503
        self.flakes('''
 
504
            def fun():
 
505
                a = 1
 
506
                def fun2():
 
507
                    a
 
508
                    a = 1
 
509
                    return a
 
510
                return a
 
511
        ''', m.UndefinedLocal)
 
512
 
 
513
    def test_undefinedAugmentedAssignment(self):
 
514
        self.flakes(
 
515
            '''
 
516
            def f(seq):
 
517
                a = 0
 
518
                seq[a] += 1
 
519
                seq[b] /= 2
 
520
                c[0] *= 2
 
521
                a -= 3
 
522
                d += 4
 
523
                e[any] = 5
 
524
            ''',
 
525
            m.UndefinedName,    # b
 
526
            m.UndefinedName,    # c
 
527
            m.UndefinedName, m.UnusedVariable,  # d
 
528
            m.UndefinedName,    # e
 
529
        )
 
530
 
 
531
    def test_nestedClass(self):
 
532
        """Nested classes can access enclosing scope."""
 
533
        self.flakes('''
 
534
        def f(foo):
 
535
            class C:
 
536
                bar = foo
 
537
                def f(self):
 
538
                    return foo
 
539
            return C()
 
540
 
 
541
        f(123).f()
 
542
        ''')
 
543
 
 
544
    def test_badNestedClass(self):
 
545
        """Free variables in nested classes must bind at class creation."""
 
546
        self.flakes('''
 
547
        def f():
 
548
            class C:
 
549
                bar = foo
 
550
            foo = 456
 
551
            return foo
 
552
        f()
 
553
        ''', m.UndefinedName)
 
554
 
 
555
    def test_definedAsStarArgs(self):
 
556
        """Star and double-star arg names are defined."""
 
557
        self.flakes('''
 
558
        def f(a, *b, **c):
 
559
            print(a, b, c)
 
560
        ''')
 
561
 
 
562
    @skipIf(version_info < (3,), 'new in Python 3')
 
563
    def test_definedAsStarUnpack(self):
 
564
        """Star names in unpack are defined."""
 
565
        self.flakes('''
 
566
        a, *b = range(10)
 
567
        print(a, b)
 
568
        ''')
 
569
        self.flakes('''
 
570
        *a, b = range(10)
 
571
        print(a, b)
 
572
        ''')
 
573
        self.flakes('''
 
574
        a, *b, c = range(10)
 
575
        print(a, b, c)
 
576
        ''')
 
577
 
 
578
    @skipIf(version_info < (3,), 'new in Python 3')
 
579
    def test_usedAsStarUnpack(self):
 
580
        """
 
581
        Star names in unpack are used if RHS is not a tuple/list literal.
 
582
        """
 
583
        self.flakes('''
 
584
        def f():
 
585
            a, *b = range(10)
 
586
        ''')
 
587
        self.flakes('''
 
588
        def f():
 
589
            (*a, b) = range(10)
 
590
        ''')
 
591
        self.flakes('''
 
592
        def f():
 
593
            [a, *b, c] = range(10)
 
594
        ''')
 
595
 
 
596
    @skipIf(version_info < (3,), 'new in Python 3')
 
597
    def test_unusedAsStarUnpack(self):
 
598
        """
 
599
        Star names in unpack are unused if RHS is a tuple/list literal.
 
600
        """
 
601
        self.flakes('''
 
602
        def f():
 
603
            a, *b = any, all, 4, 2, 'un'
 
604
        ''', m.UnusedVariable, m.UnusedVariable)
 
605
        self.flakes('''
 
606
        def f():
 
607
            (*a, b) = [bool, int, float, complex]
 
608
        ''', m.UnusedVariable, m.UnusedVariable)
 
609
        self.flakes('''
 
610
        def f():
 
611
            [a, *b, c] = 9, 8, 7, 6, 5, 4
 
612
        ''', m.UnusedVariable, m.UnusedVariable, m.UnusedVariable)
 
613
 
 
614
    @skipIf(version_info < (3,), 'new in Python 3')
 
615
    def test_keywordOnlyArgs(self):
 
616
        """Keyword-only arg names are defined."""
 
617
        self.flakes('''
 
618
        def f(*, a, b=None):
 
619
            print(a, b)
 
620
        ''')
 
621
 
 
622
        self.flakes('''
 
623
        import default_b
 
624
        def f(*, a, b=default_b):
 
625
            print(a, b)
 
626
        ''')
 
627
 
 
628
    @skipIf(version_info < (3,), 'new in Python 3')
 
629
    def test_keywordOnlyArgsUndefined(self):
 
630
        """Typo in kwonly name."""
 
631
        self.flakes('''
 
632
        def f(*, a, b=default_c):
 
633
            print(a, b)
 
634
        ''', m.UndefinedName)
 
635
 
 
636
    @skipIf(version_info < (3,), 'new in Python 3')
 
637
    def test_annotationUndefined(self):
 
638
        """Undefined annotations."""
 
639
        self.flakes('''
 
640
        from abc import note1, note2, note3, note4, note5
 
641
        def func(a: note1, *args: note2,
 
642
                 b: note3=12, **kw: note4) -> note5: pass
 
643
        ''')
 
644
 
 
645
        self.flakes('''
 
646
        def func():
 
647
            d = e = 42
 
648
            def func(a: {1, d}) -> (lambda c: e): pass
 
649
        ''')
 
650
 
 
651
    @skipIf(version_info < (3,), 'new in Python 3')
 
652
    def test_metaClassUndefined(self):
 
653
        self.flakes('''
 
654
        from abc import ABCMeta
 
655
        class A(metaclass=ABCMeta): pass
 
656
        ''')
 
657
 
 
658
    def test_definedInGenExp(self):
 
659
        """
 
660
        Using the loop variable of a generator expression results in no
 
661
        warnings.
 
662
        """
 
663
        self.flakes('(a for a in [1, 2, 3] if a)')
 
664
 
 
665
        self.flakes('(b for b in (a for a in [1, 2, 3] if a) if b)')
 
666
 
 
667
    def test_undefinedInGenExpNested(self):
 
668
        """
 
669
        The loop variables of generator expressions nested together are
 
670
        not defined in the other generator.
 
671
        """
 
672
        self.flakes('(b for b in (a for a in [1, 2, 3] if b) if b)',
 
673
                    m.UndefinedName)
 
674
 
 
675
        self.flakes('(b for b in (a for a in [1, 2, 3] if a) if a)',
 
676
                    m.UndefinedName)
 
677
 
 
678
    def test_undefinedWithErrorHandler(self):
 
679
        """
 
680
        Some compatibility code checks explicitly for NameError.
 
681
        It should not trigger warnings.
 
682
        """
 
683
        self.flakes('''
 
684
        try:
 
685
            socket_map
 
686
        except NameError:
 
687
            socket_map = {}
 
688
        ''')
 
689
        self.flakes('''
 
690
        try:
 
691
            _memoryview.contiguous
 
692
        except (NameError, AttributeError):
 
693
            raise RuntimeError("Python >= 3.3 is required")
 
694
        ''')
 
695
        # If NameError is not explicitly handled, generate a warning
 
696
        self.flakes('''
 
697
        try:
 
698
            socket_map
 
699
        except:
 
700
            socket_map = {}
 
701
        ''', m.UndefinedName)
 
702
        self.flakes('''
 
703
        try:
 
704
            socket_map
 
705
        except Exception:
 
706
            socket_map = {}
 
707
        ''', m.UndefinedName)
 
708
 
 
709
    def test_definedInClass(self):
 
710
        """
 
711
        Defined name for generator expressions and dict/set comprehension.
 
712
        """
 
713
        self.flakes('''
 
714
        class A:
 
715
            T = range(10)
 
716
 
 
717
            Z = (x for x in T)
 
718
            L = [x for x in T]
 
719
            B = dict((i, str(i)) for i in T)
 
720
        ''')
 
721
 
 
722
        if version_info >= (2, 7):
 
723
            self.flakes('''
 
724
            class A:
 
725
                T = range(10)
 
726
 
 
727
                X = {x for x in T}
 
728
                Y = {x:x for x in T}
 
729
            ''')
 
730
 
 
731
    def test_definedInClassNested(self):
 
732
        """Defined name for nested generator expressions in a class."""
 
733
        self.flakes('''
 
734
        class A:
 
735
            T = range(10)
 
736
 
 
737
            Z = (x for x in (a for a in T))
 
738
        ''')
 
739
 
 
740
    def test_undefinedInLoop(self):
 
741
        """
 
742
        The loop variable is defined after the expression is computed.
 
743
        """
 
744
        self.flakes('''
 
745
        for i in range(i):
 
746
            print(i)
 
747
        ''', m.UndefinedName)
 
748
        self.flakes('''
 
749
        [42 for i in range(i)]
 
750
        ''', m.UndefinedName)
 
751
        self.flakes('''
 
752
        (42 for i in range(i))
 
753
        ''', m.UndefinedName)
 
754
 
 
755
    @skipIf(version_info < (2, 7), 'Dictionary comprehensions do not exist')
 
756
    def test_definedFromLambdaInDictionaryComprehension(self):
 
757
        """
 
758
        Defined name referenced from a lambda function within a dict/set
 
759
        comprehension.
 
760
        """
 
761
        self.flakes('''
 
762
        {lambda: id(x) for x in range(10)}
 
763
        ''')
 
764
 
 
765
    def test_definedFromLambdaInGenerator(self):
 
766
        """
 
767
        Defined name referenced from a lambda function within a generator
 
768
        expression.
 
769
        """
 
770
        self.flakes('''
 
771
        any(lambda: id(x) for x in range(10))
 
772
        ''')
 
773
 
 
774
    @skipIf(version_info < (2, 7), 'Dictionary comprehensions do not exist')
 
775
    def test_undefinedFromLambdaInDictionaryComprehension(self):
 
776
        """
 
777
        Undefined name referenced from a lambda function within a dict/set
 
778
        comprehension.
 
779
        """
 
780
        self.flakes('''
 
781
        {lambda: id(y) for x in range(10)}
 
782
        ''', m.UndefinedName)
 
783
 
 
784
    def test_undefinedFromLambdaInComprehension(self):
 
785
        """
 
786
        Undefined name referenced from a lambda function within a generator
 
787
        expression.
 
788
        """
 
789
        self.flakes('''
 
790
        any(lambda: id(y) for x in range(10))
 
791
        ''', m.UndefinedName)
 
792
 
 
793
 
 
794
class NameTests(TestCase):
 
795
    """
 
796
    Tests for some extra cases of name handling.
 
797
    """
 
798
    def test_impossibleContext(self):
 
799
        """
 
800
        A Name node with an unrecognized context results in a RuntimeError being
 
801
        raised.
 
802
        """
 
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)