Format string annotations and type aliases
Python type checkers supports enclosing type annotations in a string to make forward references possible. Although from __future__ import annotations makes that unnecessary in type annotations, it's still needed in type aliases.
Example:
# All these are equivalent from the point of view of the type checker
x: "Union[A, B, C, D]"
x: Union["A", 'B', """C""", '''D''']
x: Union[A, B, C, D]
# Same here
y: TypeAlias = Union[A, B, C, D]
y: TypeAlias = "Union[A, B, C, D]"
y: TypeAlias = Union["A", "B", "C", "D"]
I would like Black to format string-enclosed type annotations like if they were not string-enclosed.
Describe the solution you'd like
Format
annotation: "Union[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]"
alias: TypeAlias = "Union[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]"
to
annotation: """
Union[
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
]
"""
alias: TypeAlias = """
Union[
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
]
"""
Or maybe
annotation: (
"Union["
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,"
"]"
)
Describe alternatives you've considered
Black could detect what parts of a type are forward references and unstringify all the rest:
For example it could format
annotation: "Union[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]"
to
annotation: Union[
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
]
Note that in some cases the outer type of a generic type can be a forward reference, thus making this strategy impossible
annotation: TypeAlias = "ForwardRefToGenericType[int, str, None]" # cannot be unstringified
But my understanding is that Black does not have access to the information necessary to do this, so this is probably not possible.
Alternatively, Black could entirely stringify any type that has a string in it, if that string is not a Literal - BUT in the case of not using from __future__ import annotations, and in the case of type aliases, this could have a runtime impact.
Other context
The distinction between type aliases and normal variables is tricky, see https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases
This is a reasonable request, but such changes will produce changes to the AST, which goes against Black's general safety guarantee. We already make similar changes in docstrings, but it's harder to reliably recognize type annotations than docstrings.