Skip to content

Commit 72acff0

Browse files
epsysigmavirus24
authored andcommitted
Fix "continue" and "break" checks ignoring py3.5's "async for" loop (#71)
1 parent d721eaf commit 72acff0

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

pyflakes/checker.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
PY2 = sys.version_info < (3, 0)
1313
PY32 = sys.version_info < (3, 3) # Python 2.5 to 3.2
1414
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
1516
try:
1617
sys.pypy_version_info
1718
PYPY = True
@@ -55,6 +56,11 @@ def getAlternatives(n):
5556
if isinstance(n, ast.Try):
5657
return [n.body + n.orelse] + [[hdl] for hdl in n.handlers]
5758

59+
if PY34:
60+
LOOP_TYPES = (ast.While, ast.For)
61+
else:
62+
LOOP_TYPES = (ast.While, ast.For, ast.AsyncFor)
63+
5864

5965
class _FieldsOrder(dict):
6066
"""Fix order of AST node fields."""
@@ -943,7 +949,7 @@ def CONTINUE(self, node):
943949
n = node
944950
while hasattr(n, 'parent'):
945951
n, n_child = n.parent, n
946-
if isinstance(n, (ast.While, ast.For)):
952+
if isinstance(n, LOOP_TYPES):
947953
# Doesn't apply unless it's in the loop itself
948954
if n_child not in n.orelse:
949955
return

pyflakes/test/test_other.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,63 @@ async def read_data(db):
17191719
return output
17201720
''')
17211721

1722+
@skipIf(version_info < (3, 5), 'new in Python 3.5')
1723+
def test_loopControlInAsyncFor(self):
1724+
self.flakes('''
1725+
async def read_data(db):
1726+
output = []
1727+
async for row in db.cursor():
1728+
if row[0] == 'skip':
1729+
continue
1730+
output.append(row)
1731+
return output
1732+
''')
1733+
1734+
self.flakes('''
1735+
async def read_data(db):
1736+
output = []
1737+
async for row in db.cursor():
1738+
if row[0] == 'stop':
1739+
break
1740+
output.append(row)
1741+
return output
1742+
''')
1743+
1744+
@skipIf(version_info < (3, 5), 'new in Python 3.5')
1745+
def test_loopControlInAsyncForElse(self):
1746+
self.flakes('''
1747+
async def read_data(db):
1748+
output = []
1749+
async for row in db.cursor():
1750+
output.append(row)
1751+
else:
1752+
continue
1753+
return output
1754+
''', m.ContinueOutsideLoop)
1755+
1756+
self.flakes('''
1757+
async def read_data(db):
1758+
output = []
1759+
async for row in db.cursor():
1760+
output.append(row)
1761+
else:
1762+
break
1763+
return output
1764+
''', m.BreakOutsideLoop)
1765+
1766+
@skipIf(version_info < (3, 5), 'new in Python 3.5')
1767+
def test_continueInAsyncForFinally(self):
1768+
self.flakes('''
1769+
async def read_data(db):
1770+
output = []
1771+
async for row in db.cursor():
1772+
try:
1773+
output.append(row)
1774+
finally:
1775+
continue
1776+
return output
1777+
''', m.ContinueInFinally)
1778+
17221779
@skipIf(version_info < (3, 5), 'new in Python 3.5')
17231780
def test_asyncWith(self):
17241781
self.flakes('''

0 commit comments

Comments
 (0)