@@ -1507,6 +1507,60 @@ def python_3000_invalid_escape_sequence(logical_line, tokens):
15071507 pos = string .find ('\\ ' , pos + 1 )
15081508
15091509
1510+ @register_check
1511+ def python_3000_async_await_keywords (logical_line , tokens ):
1512+ """'async' and 'await' are reserved keywords starting with Python 3.7
1513+
1514+ W606: async = 42
1515+ W606: await = 42
1516+ Okay: async def read_data(db):\n data = await db.fetch('SELECT ...')
1517+ """
1518+ # The Python tokenize library before Python 3.5 recognizes async/await as a
1519+ # NAME token. Therefore, use a state machine to look for the possible
1520+ # async/await constructs as defined by the Python grammar:
1521+ # https://docs.python.org/3/reference/grammar.html
1522+
1523+ state = None
1524+ for token_type , text , start , end , line in tokens :
1525+ error = False
1526+
1527+ if state is None :
1528+ if token_type == tokenize .NAME :
1529+ if text == 'async' :
1530+ state = ('async_stmt' , start )
1531+ elif text == 'await' :
1532+ state = ('await' , start )
1533+ elif state [0 ] == 'async_stmt' :
1534+ if token_type == tokenize .NAME and text in ('def' , 'with' , 'for' ):
1535+ # One of funcdef, with_stmt, or for_stmt. Return to looking
1536+ # for async/await names.
1537+ state = None
1538+ else :
1539+ error = True
1540+ elif state [0 ] == 'await' :
1541+ if token_type in (tokenize .NAME , tokenize .NUMBER , tokenize .STRING ):
1542+ # An await expression. Return to looking for async/await names.
1543+ state = None
1544+ else :
1545+ error = True
1546+
1547+ if error :
1548+ yield (
1549+ state [1 ],
1550+ "W606 'async' and 'await' are reserved keywords starting with "
1551+ "Python 3.7" ,
1552+ )
1553+ state = None
1554+
1555+ # Last token
1556+ if state is not None :
1557+ yield (
1558+ state [1 ],
1559+ "W606 'async' and 'await' are reserved keywords starting with "
1560+ "Python 3.7" ,
1561+ )
1562+
1563+
15101564##############################################################################
15111565# Helper functions
15121566##############################################################################
0 commit comments