black
black copied to clipboard
with statement with type comment
Describe the bug
The following code can not be formatted
with (a,b): # type: something
pass
when run with these arguments:
$ black example.py
The error is:
error: cannot format example.py: INTERNAL ERROR: Black produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: /tmp/blk_o04ck2zv.log
Oh no! 💥 💔 💥
1 file failed to reformat.
Environment
python -m black, 23.3.1.dev10+geb32729 (compiled: no) Python (CPython) 3.11.3
Additional context
--- src
+++ dst
@@ -5,30 +5,29 @@
Pass(
) # /Pass
items=
withitem(
context_expr=
- Tuple(
+ Name(
ctx=
Load(
) # /Load
- elts=
- Name(
- ctx=
- Load(
- ) # /Load
- id=
- 'a', # str
- ) # /Name
- Name(
- ctx=
- Load(
- ) # /Load
- id=
- 'b', # str
- ) # /Name
- ) # /Tuple
+ id=
+ 'a', # str
+ ) # /Name
+ optional_vars=
+ None, # NoneType
+ ) # /withitem
+ withitem(
+ context_expr=
+ Name(
+ ctx=
+ Load(
+ ) # /Load
+ id=
+ 'b', # str
+ ) # /Name
optional_vars=
None, # NoneType
) # /withitem
type_comment=
'something', # str
This is arguably a bug in CPython. The issue is that when using ast.parse(type_comments=True), when there is a type comment, the parentheses change how the with statement is parsed:
In [7]: ast.dump(ast.parse('''with a,b: # type: something
...: pass
...: ''', type_comments=True))
Out[7]: "Module(body=[With(items=[withitem(context_expr=Name(id='a', ctx=Load())), withitem(context_expr=Name(id='b', ctx=Load()))], body=[Pass()], type_comment='something')], type_ignores=[])"
In [8]: ast.dump(ast.parse('''with (a,b): # type: something
...: pass
...: ''', type_comments=True))
Out[8]: "Module(body=[With(items=[withitem(context_expr=Tuple(elts=[Name(id='a', ctx=Load()), Name(id='b', ctx=Load())], ctx=Load()))], body=[Pass()], type_comment='something')], type_ignores=[])"
In [9]: ast.dump(ast.parse('''with a,b:
...: pass
...: ''', type_comments=True))
Out[9]: "Module(body=[With(items=[withitem(context_expr=Name(id='a', ctx=Load())), withitem(context_expr=Name(id='b', ctx=Load()))], body=[Pass()])], type_ignores=[])"
In [10]: ast.dump(ast.parse('''with (a,b):
...: pass
...: ''', type_comments=True))
Out[10]: "Module(body=[With(items=[withitem(context_expr=Name(id='a', ctx=Load())), withitem(context_expr=Name(id='b', ctx=Load()))], body=[Pass()])], type_ignores=[])"
Worse yet, this fails to parse:
In [11]: ast.dump(ast.parse('''with (a as c,b): # type: something
...: pass
...: ''', type_comments=True))
I'll report an upstream bug.