Restore ability to format code with legacy usage of async
as a name
Fixes #20 Fixes #42
This commit is contained in:
parent
155aa71db0
commit
d9c6b99073
@ -261,6 +261,10 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
|
|||||||
|
|
||||||
* added ability to pipe formatting from stdin to stdin (#25)
|
* added ability to pipe formatting from stdin to stdin (#25)
|
||||||
|
|
||||||
|
* restored ability to format code with legacy usage of `async` as
|
||||||
|
a name (#20, #42)
|
||||||
|
|
||||||
|
|
||||||
### 18.3a2
|
### 18.3a2
|
||||||
|
|
||||||
* changed positioning of binary operators to occur at beginning of lines
|
* changed positioning of binary operators to occur at beginning of lines
|
||||||
|
5
black.py
5
black.py
@ -486,8 +486,7 @@ def is_def(self) -> bool:
|
|||||||
return (
|
return (
|
||||||
(first_leaf.type == token.NAME and first_leaf.value == 'def')
|
(first_leaf.type == token.NAME and first_leaf.value == 'def')
|
||||||
or (
|
or (
|
||||||
first_leaf.type == token.NAME
|
first_leaf.type == token.ASYNC
|
||||||
and first_leaf.value == 'async'
|
|
||||||
and second_leaf is not None
|
and second_leaf is not None
|
||||||
and second_leaf.type == token.NAME
|
and second_leaf.type == token.NAME
|
||||||
and second_leaf.value == 'def'
|
and second_leaf.value == 'def'
|
||||||
@ -816,7 +815,7 @@ def visit_async_stmt(self, node: Node) -> Iterator[Line]:
|
|||||||
for child in children:
|
for child in children:
|
||||||
yield from self.visit(child)
|
yield from self.visit(child)
|
||||||
|
|
||||||
if child.type == token.NAME and child.value == 'async': # type: ignore
|
if child.type == token.ASYNC:
|
||||||
break
|
break
|
||||||
|
|
||||||
internal_stmt = next(children)
|
internal_stmt = next(children)
|
||||||
|
@ -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)*
|
||||||
|
Binary file not shown.
@ -5,5 +5,7 @@ Reasons for forking:
|
|||||||
- consistent handling of f-strings for users of Python < 3.6.2
|
- consistent handling of f-strings for users of Python < 3.6.2
|
||||||
- backport of BPO-33064 that fixes parsing files with trailing commas after
|
- backport of BPO-33064 that fixes parsing files with trailing commas after
|
||||||
*args and **kwargs
|
*args and **kwargs
|
||||||
|
- backport of GH-6143 that restores the ability to reformat legacy usage of
|
||||||
|
`async`
|
||||||
- better ability to debug (better reprs for starters)
|
- better ability to debug (better reprs for starters)
|
||||||
- ability to Cythonize
|
- ability to Cythonize
|
||||||
|
@ -62,8 +62,10 @@
|
|||||||
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--
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ def compat(self, token, iterable):
|
|||||||
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), '')
|
||||||
|
Loading…
Reference in New Issue
Block a user