Skip to content

Internal error in the formatting of the if expression within a type annotation #4647

@15r10nk

Description

@15r10nk

Describe the bug

The following code can not be parsed/formatted by black:

def name_3[name_0: [] if name_2 else name_3]():
    pass

(playground)

black reported the following error:

> black -l 46 -t py313 bug.py
error: cannot format bug.py: INTERNAL ERROR: Black 25.1.1.dev21+g944a38e.d20250317 on Python (CPython) 3.13.1 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_0ajkvzbr.log

Oh no! 💥 💔 💥
1 file failed to reformat.

the reported diff in /tmp/blk_0ajkvzbr.log is:

--- src
+++ dst
@@ -24,35 +24,41 @@
         type_comment=
         None,  # NoneType
         type_params=
         TypeVar(
             bound=
-            IfExp(
-                body=
-                List(
-                    ctx=
-                    Load(
-                    )  # /Load
-                    elts=
-                )  # /List
-                orelse=
-                Name(
-                    ctx=
-                    Load(
-                    )  # /Load
-                    id=
-                    'name_3',  # str
-                )  # /Name
-                test=
-                Name(
-                    ctx=
-                    Load(
-                    )  # /Load
-                    id=
-                    'name_2',  # str
-                )  # /Name
-            )  # /IfExp
+            Tuple(
+                ctx=
+                Load(
+                )  # /Load
+                elts=
+                IfExp(
+                    body=
+                    List(
+                        ctx=
+                        Load(
+                        )  # /Load
+                        elts=
+                    )  # /List
+                    orelse=
+                    Name(
+                        ctx=
+                        Load(
+                        )  # /Load
+                        id=
+                        'name_3',  # str
+                    )  # /Name
+                    test=
+                    Name(
+                        ctx=
+                        Load(
+                        )  # /Load
+                        id=
+                        'name_2',  # str
+                    )  # /Name
+                )  # /IfExp
+            )  # /Tuple
             default_value=
             None,  # NoneType
             name=
             'name_0',  # str
         )  # /TypeVar

but it can be parsed by cpython:

from ast import parse
parse(
    'def name_3[name_0: [] if name_2 else name_3]():\n'
    '    pass\n'
)

The code can be formatted with black -l 46 -t py313 bug.py --fast:

def name_3[name_0: (
    [] if name_2 else name_3,
)]():
    pass

Environment

  • Black's version: current main (d0ff3bd)
  • OS and Python version: Linux/Python 3.13.1 (main, Jan 14 2025, 22:47:38) [Clang 19.1.6 ]

Additional context

The bug was found by pysource-codegen (see #3908)
The above problem description was created from a script,
let me know if you think it can be improved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T: bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions