File tree Expand file tree Collapse file tree 2 files changed +36
-16
lines changed Expand file tree Collapse file tree 2 files changed +36
-16
lines changed Original file line number Diff line number Diff line change @@ -480,30 +480,29 @@ def handleNodeLoad(self, node):
480
480
name = getNodeName (node )
481
481
if not name :
482
482
return
483
- # try local scope
484
- try :
485
- self .scope [name ].used = (self .scope , node )
486
- except KeyError :
487
- pass
488
- else :
489
- return
490
483
491
- scopes = [scope for scope in self .scopeStack [:- 1 ]
492
- if isinstance (scope , (FunctionScope , ModuleScope , GeneratorScope ))]
493
- if isinstance (self .scope , GeneratorScope ) and scopes [- 1 ] != self .scopeStack [- 2 ]:
494
- scopes .append (self .scopeStack [- 2 ])
484
+ in_generators = None
485
+ importStarred = None
495
486
496
487
# try enclosing function scopes and global scope
497
- importStarred = self .scope .importStarred
498
- for scope in reversed (scopes ):
499
- importStarred = importStarred or scope .importStarred
488
+ for scope in self .scopeStack [- 1 ::- 1 ]:
489
+ # only generators used in a class scope can access the names
490
+ # of the class. this is skipped during the first iteration
491
+ if in_generators is False and isinstance (scope , ClassScope ):
492
+ continue
493
+
500
494
try :
501
495
scope [name ].used = (self .scope , node )
502
496
except KeyError :
503
497
pass
504
498
else :
505
499
return
506
500
501
+ importStarred = importStarred or scope .importStarred
502
+
503
+ if in_generators is not False :
504
+ in_generators = isinstance (scope , GeneratorScope )
505
+
507
506
# look in the built-ins
508
507
if importStarred or name in self .builtIns :
509
508
return
Original file line number Diff line number Diff line change @@ -481,8 +481,20 @@ def test_definedInGenExp(self):
481
481
Using the loop variable of a generator expression results in no
482
482
warnings.
483
483
"""
484
- self .flakes ('(a for a in %srange(10) if a)' %
485
- ('x' if version_info < (3 ,) else '' ))
484
+ self .flakes ('(a for a in [1, 2, 3] if a)' )
485
+
486
+ self .flakes ('(b for b in (a for a in [1, 2, 3] if a) if b)' )
487
+
488
+ def test_undefinedInGenExpNested (self ):
489
+ """
490
+ The loop variables of generator expressions nested together are
491
+ not defined in the other generator.
492
+ """
493
+ self .flakes ('(b for b in (a for a in [1, 2, 3] if b) if b)' ,
494
+ m .UndefinedName )
495
+
496
+ self .flakes ('(b for b in (a for a in [1, 2, 3] if a) if a)' ,
497
+ m .UndefinedName )
486
498
487
499
def test_undefinedWithErrorHandler (self ):
488
500
"""
@@ -537,6 +549,15 @@ class A:
537
549
Y = {x:x for x in T}
538
550
''' )
539
551
552
+ def test_definedInClassNested (self ):
553
+ """Defined name for nested generator expressions in a class."""
554
+ self .flakes ('''
555
+ class A:
556
+ T = range(10)
557
+
558
+ Z = (x for x in (a for a in T))
559
+ ''' )
560
+
540
561
def test_undefinedInLoop (self ):
541
562
"""
542
563
The loop variable is defined after the expression is computed.
You can’t perform that action at this time.
0 commit comments