Revert "bpo-30406: Make async and await proper keywords (GH-1669)" (GH-6143)

This reverts commit ac317700ce.

(Reverts only the lib2to3 part.)
(cherry picked from commit f64aae46da)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
Miss Islington (bot) 2018-03-18 12:15:52 -07:00 committed by GitHub
parent 773573e9ac
commit a90df5085b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 20 deletions

View File

@ -15,7 +15,7 @@ eval_input: testlist NEWLINE* ENDMARKER
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+ decorators: decorator+
decorated: decorators (classdef | funcdef | async_funcdef) decorated: decorators (classdef | funcdef | async_funcdef)
async_funcdef: 'async' funcdef async_funcdef: ASYNC funcdef
funcdef: 'def' NAME parameters ['->' test] ':' suite funcdef: 'def' NAME parameters ['->' test] ':' suite
parameters: '(' [typedargslist] ')' parameters: '(' [typedargslist] ')'
typedargslist: ((tfpdef ['=' test] ',')* typedargslist: ((tfpdef ['=' test] ',')*
@ -66,7 +66,7 @@ exec_stmt: 'exec' expr ['in' test [',' test]]
assert_stmt: 'assert' test [',' test] assert_stmt: 'assert' test [',' test]
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt
async_stmt: 'async' (funcdef | with_stmt | for_stmt) async_stmt: ASYNC (funcdef | with_stmt | for_stmt)
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
while_stmt: 'while' test ':' suite ['else' ':' suite] while_stmt: 'while' test ':' suite ['else' ':' suite]
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
@ -105,7 +105,7 @@ shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)* arith_expr: term (('+'|'-') term)*
term: factor (('*'|'@'|'/'|'%'|'//') factor)* term: factor (('*'|'@'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power factor: ('+'|'-'|'~') factor | power
power: ['await'] atom trailer* ['**' factor] power: [AWAIT] atom trailer* ['**' factor]
atom: ('(' [yield_expr|testlist_gexp] ')' | atom: ('(' [yield_expr|testlist_gexp] ')' |
'[' [listmaker] ']' | '[' [listmaker] ']' |
'{' [dictsetmaker] '}' | '{' [dictsetmaker] '}' |
@ -142,7 +142,7 @@ argument: ( test [comp_for] |
star_expr ) star_expr )
comp_iter: comp_for | comp_if comp_iter: comp_for | comp_if
comp_for: ['async'] 'for' exprlist 'in' or_test [comp_iter] comp_for: [ASYNC] 'for' exprlist 'in' or_test [comp_iter]
comp_if: 'if' old_test [comp_iter] comp_if: 'if' old_test [comp_iter]
# As noted above, testlist_safe extends the syntax allowed in list # As noted above, testlist_safe extends the syntax allowed in list
@ -161,7 +161,7 @@ comp_if: 'if' old_test [comp_iter]
# #
# See https://bugs.python.org/issue27494 # See https://bugs.python.org/issue27494
old_comp_iter: old_comp_for | old_comp_if old_comp_iter: old_comp_for | old_comp_if
old_comp_for: ['async'] 'for' exprlist 'in' testlist_safe [old_comp_iter] old_comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [old_comp_iter]
old_comp_if: 'if' old_test [old_comp_iter] old_comp_if: 'if' old_test [old_comp_iter]
testlist1: test (',' test)* testlist1: test (',' test)*

View File

@ -62,8 +62,10 @@ OP = 52
COMMENT = 53 COMMENT = 53
NL = 54 NL = 54
RARROW = 55 RARROW = 55
ERRORTOKEN = 56 AWAIT = 56
N_TOKENS = 57 ASYNC = 57
ERRORTOKEN = 58
N_TOKENS = 59
NT_OFFSET = 256 NT_OFFSET = 256
#--end constants-- #--end constants--

View File

@ -234,7 +234,7 @@ class Untokenizer:
for tok in iterable: for tok in iterable:
toknum, tokval = tok[:2] toknum, tokval = tok[:2]
if toknum in (NAME, NUMBER): if toknum in (NAME, NUMBER, ASYNC, AWAIT):
tokval += ' ' tokval += ' '
if toknum == INDENT: if toknum == INDENT:
@ -380,6 +380,12 @@ def generate_tokens(readline):
contline = None contline = None
indents = [0] indents = [0]
# 'stashed' and 'async_*' are used for async/await parsing
stashed = None
async_def = False
async_def_indent = 0
async_def_nl = False
while 1: # loop over lines in stream while 1: # loop over lines in stream
try: try:
line = readline() line = readline()
@ -420,6 +426,10 @@ def generate_tokens(readline):
pos = pos + 1 pos = pos + 1
if pos == max: break if pos == max: break
if stashed:
yield stashed
stashed = None
if line[pos] in '#\r\n': # skip comments or blank lines if line[pos] in '#\r\n': # skip comments or blank lines
if line[pos] == '#': if line[pos] == '#':
comment_token = line[pos:].rstrip('\r\n') comment_token = line[pos:].rstrip('\r\n')
@ -443,8 +453,18 @@ def generate_tokens(readline):
("<tokenize>", lnum, pos, line)) ("<tokenize>", lnum, pos, line))
indents = indents[:-1] indents = indents[:-1]
if async_def and async_def_indent >= indents[-1]:
async_def = False
async_def_nl = False
async_def_indent = 0
yield (DEDENT, '', (lnum, pos), (lnum, pos), line) yield (DEDENT, '', (lnum, pos), (lnum, pos), line)
if async_def and async_def_nl and async_def_indent >= indents[-1]:
async_def = False
async_def_nl = False
async_def_indent = 0
else: # continued statement else: # continued statement
if not line: if not line:
raise TokenError("EOF in multi-line statement", (lnum, 0)) raise TokenError("EOF in multi-line statement", (lnum, 0))
@ -464,10 +484,18 @@ def generate_tokens(readline):
newline = NEWLINE newline = NEWLINE
if parenlev > 0: if parenlev > 0:
newline = NL newline = NL
elif async_def:
async_def_nl = True
if stashed:
yield stashed
stashed = None
yield (newline, token, spos, epos, line) yield (newline, token, spos, epos, line)
elif initial == '#': elif initial == '#':
assert not token.endswith("\n") assert not token.endswith("\n")
if stashed:
yield stashed
stashed = None
yield (COMMENT, token, spos, epos, line) yield (COMMENT, token, spos, epos, line)
elif token in triple_quoted: elif token in triple_quoted:
endprog = endprogs[token] endprog = endprogs[token]
@ -475,6 +503,9 @@ def generate_tokens(readline):
if endmatch: # all on one line if endmatch: # all on one line
pos = endmatch.end(0) pos = endmatch.end(0)
token = line[start:pos] token = line[start:pos]
if stashed:
yield stashed
stashed = None
yield (STRING, token, spos, (lnum, pos), line) yield (STRING, token, spos, (lnum, pos), line)
else: else:
strstart = (lnum, start) # multiple lines strstart = (lnum, start) # multiple lines
@ -492,22 +523,63 @@ def generate_tokens(readline):
contline = line contline = line
break break
else: # ordinary string else: # ordinary string
if stashed:
yield stashed
stashed = None
yield (STRING, token, spos, epos, line) yield (STRING, token, spos, epos, line)
elif initial in namechars: # ordinary name elif initial in namechars: # ordinary name
yield (NAME, token, spos, epos, line) if token in ('async', 'await'):
if async_def:
yield (ASYNC if token == 'async' else AWAIT,
token, spos, epos, line)
continue
tok = (NAME, token, spos, epos, line)
if token == 'async' and not stashed:
stashed = tok
continue
if token == 'def':
if (stashed
and stashed[0] == NAME
and stashed[1] == 'async'):
async_def = True
async_def_indent = indents[-1]
yield (ASYNC, stashed[1],
stashed[2], stashed[3],
stashed[4])
stashed = None
if stashed:
yield stashed
stashed = None
yield tok
elif initial == '\\': # continued stmt elif initial == '\\': # continued stmt
# This yield is new; needed for better idempotency: # This yield is new; needed for better idempotency:
if stashed:
yield stashed
stashed = None
yield (NL, token, spos, (lnum, pos), line) yield (NL, token, spos, (lnum, pos), line)
continued = 1 continued = 1
else: else:
if initial in '([{': parenlev = parenlev + 1 if initial in '([{': parenlev = parenlev + 1
elif initial in ')]}': parenlev = parenlev - 1 elif initial in ')]}': parenlev = parenlev - 1
if stashed:
yield stashed
stashed = None
yield (OP, token, spos, epos, line) yield (OP, token, spos, epos, line)
else: else:
yield (ERRORTOKEN, line[pos], yield (ERRORTOKEN, line[pos],
(lnum, pos), (lnum, pos+1), line) (lnum, pos), (lnum, pos+1), line)
pos = pos + 1 pos = pos + 1
if stashed:
yield stashed
stashed = None
for indent in indents[1:]: # pop remaining indent levels for indent in indents[1:]: # pop remaining indent levels
yield (DEDENT, '', (lnum, 0), (lnum, 0), '') yield (DEDENT, '', (lnum, 0), (lnum, 0), '')
yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '')

View File

@ -181,33 +181,33 @@ class TestAsyncAwait(GrammarTest):
async def foo(): await x async def foo(): await x
""") """)
self.validate("await x") self.invalid_syntax("await x")
self.validate("""def foo(): self.invalid_syntax("""def foo():
await x""") await x""")
self.validate("""def foo(): self.invalid_syntax("""def foo():
def foo(): pass def foo(): pass
async def foo(): pass async def foo(): pass
await x await x
""") """)
def test_async_var(self): def test_async_var(self):
self.invalid_syntax("""async = 1""") self.validate("""async = 1""")
self.invalid_syntax("""await = 1""") self.validate("""await = 1""")
self.invalid_syntax("""def async(): pass""") self.validate("""def async(): pass""")
def test_async_with(self): def test_async_with(self):
self.validate("""async def foo(): self.validate("""async def foo():
async for a in b: pass""") async for a in b: pass""")
self.validate("""def foo(): self.invalid_syntax("""def foo():
async for a in b: pass""") async for a in b: pass""")
def test_async_for(self): def test_async_for(self):
self.validate("""async def foo(): self.validate("""async def foo():
async with a: pass""") async with a: pass""")
self.validate("""def foo(): self.invalid_syntax("""def foo():
async with a: pass""") async with a: pass""")