Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • pycqa/pycodestyle
1 result
Show changes
Commits on Source (2)
Loading
Loading
@@ -9,6 +9,8 @@ New checks:
* Add W504 warning for checking that a break doesn't happen after a binary
operator. This check is ignored by default
* Add W605 warning for invalid escape sequences in string literals
* Add W606 warning for 'async' and 'await' reserved keywords being introduced
in Python 3.7
 
2.3.1 (2017-01-31)
------------------
Loading
Loading
Loading
Loading
@@ -419,6 +419,8 @@ This is the current list of error and warning codes:
+------------+----------------------------------------------------------------------+
| W605 | invalid escape sequence '\x' |
+------------+----------------------------------------------------------------------+
| W606 | 'async' and 'await' are reserved keywords starting with Python 3.7 |
+------------+----------------------------------------------------------------------+
 
 
**(*)** In the default configuration, the checks **E121**, **E123**, **E126**,
Loading
Loading
Loading
Loading
@@ -1507,6 +1507,60 @@ def python_3000_invalid_escape_sequence(logical_line, tokens):
pos = string.find('\\', pos + 1)
 
 
@register_check
def python_3000_async_await_keywords(logical_line, tokens):
"""'async' and 'await' are reserved keywords starting with Python 3.7
W606: async = 42
W606: await = 42
Okay: async def read_data(db):\n data = await db.fetch('SELECT ...')
"""
# The Python tokenize library before Python 3.5 recognizes async/await as a
# NAME token. Therefore, use a state machine to look for the possible
# async/await constructs as defined by the Python grammar:
# https://docs.python.org/3/reference/grammar.html
state = None
for token_type, text, start, end, line in tokens:
error = False
if state is None:
if token_type == tokenize.NAME:
if text == 'async':
state = ('async_stmt', start)
elif text == 'await':
state = ('await', start)
elif state[0] == 'async_stmt':
if token_type == tokenize.NAME and text in ('def', 'with', 'for'):
# One of funcdef, with_stmt, or for_stmt. Return to looking
# for async/await names.
state = None
else:
error = True
elif state[0] == 'await':
if token_type in (tokenize.NAME, tokenize.NUMBER, tokenize.STRING):
# An await expression. Return to looking for async/await names.
state = None
else:
error = True
if error:
yield (
state[1],
"W606 'async' and 'await' are reserved keywords starting with "
"Python 3.7",
)
state = None
# Last token
if state is not None:
yield (
state[1],
"W606 'async' and 'await' are reserved keywords starting with "
"Python 3.7",
)
##############################################################################
# Helper functions
##############################################################################
Loading
Loading
Loading
Loading
@@ -29,3 +29,48 @@ regex = r'''
\\.png$
'''
s = '\\'
#: W606
async = 42
#: W606
await = 42
#: W606
def async():
pass
#: W606
def await():
pass
#: W606
class async:
pass
#: W606
class await:
pass
#: Okay
async def read_data(db):
data = await db.fetch('SELECT ...')
#: Okay
if await fut:
pass
if (await fut):
pass
if await fut + 1:
pass
if (await fut) + 1:
pass
pair = await fut, 'spam'
pair = (await fut), 'spam'
with await fut, open():
pass
with (await fut), open():
pass
await foo()['spam'].baz()()
return await coro()
return (await coro())
res = await coro() ** 2
res = (await coro()) ** 2
func(a1=await coro(), a2=0)
func(a1=(await coro()), a2=0)
await foo() + await bar()
(await foo()) + (await bar())
-await foo()
-(await foo())