Repository navigation
Closed
Labels
F: linebreakHow should we split up lines?How should we split up lines?F: parenthesesToo many parentheses, not enough parentheses, and so on.Too many parentheses, not enough parentheses, and so on.T: styleWhat do we want Blackened code to look like?What do we want Blackened code to look like?
Milestone
Description
Describe the style change
Long PEP 604 annotations (X | Y) in function definitions (and probably other contexts) are currently broken into multiple lines without extra indentation. This makes it hard to recognize the arguments in the signature. My suggestion would be to treat those annotations similar to regular bitwise or operators inside type annotations: Indent followup lines and possibly use parentheses.
Examples in the current Black style
def foo(
i: int,
x: Loooooooooooooooooooooooong
| Looooooooooooooooong
| Looooooooooooooooooooong
| Looooooong,
*,
s: str
) -> None:
passA practical example (with shorter line width):
def create_medical_record_entries(
context: RequestContext,
db_entries: Iterable[CharlyMedicalRecordEntry]
| Iterable[CharlyLabRecordEntry],
*,
ignore_signs: bool = True
) -> list[MedicalRecordEntry]:
...Desired style (without extra arguments)
def foo(
x: (
Loooooooooooooooooooooooong
| Looooooooooooooooong
| Looooooooooooooooooooong
| Looooooong
),
) -> None:
passOr maybe:
def foo(
x:
Loooooooooooooooooooooooong
| Looooooooooooooooong
| Looooooooooooooooooooong
| Looooooong,
) -> None:
passOr:
def foo(
x: Loooooooooooooooooooooooong
| Looooooooooooooooong
| Looooooooooooooooooooong
| Looooooong,
) -> None:
passReacted by Jakub Kuczys, Jay Lee, Illviljan, Matthew Gamble, Stanislav Zmiev, Yilei, KotlinIsland, John Hagen, Mark, davidlengel and 5 more
Metadata
Metadata
Assignees
Labels
F: linebreakHow should we split up lines?How should we split up lines?F: parenthesesToo many parentheses, not enough parentheses, and so on.Too many parentheses, not enough parentheses, and so on.T: styleWhat do we want Blackened code to look like?What do we want Blackened code to look like?
Activity
srittau commentedon Jun 8, 2021
Options 2 or 3 would only work within function defs, not in variable annotations, though.
felix-hilden commentedon Jun 8, 2021
To me 1 and 3 look good, 2 is a bit weird. But I agree variable annotations should work similarly.
srittau commentedon Jun 8, 2021
Option 3 looks clearer to me in function annotations, but I don't know if there should be separate styles for function arguments and other annotations.
Zeta611 commentedon Jan 8, 2022
Current Black line-break is awkward with a short type hinting with a long default value as well:
IMHO the following is better:
It is how it is done without the type annotation.
MarcDufresne commentedon Apr 19, 2022
Any progress or solution on this? We are facing this issue now that we are switching to Python 3.10.
ichard26 commentedon Apr 19, 2022
None as far as I am aware.
johnthagen commentedon Dec 12, 2022
We've begun porting our type annotations to Python 3.10+
|unions, and we have hit this as well. It really decreases readability compared to how Black formatsOptional[T], hiding type information on another line. Here's a small snippet from a Typer CLI app:@Zeta611's suggestion is what we were going to propose as well.
EnderASz commentedon Jun 6, 2023
Hey, I see
Release 23.1.0is assigned here, but this update was a bit time ago.Is there any progress?
I'm working with some FastAPI project right now, and this issue seems to be the only thing really really stopping me from using Black.
jakkdl commentedon Sep 17, 2023
I've started looking at this - sharing some WIP thoughts:
compared to variable annotations
variable annotations have to include parentheses (because you cannot write inline annotations, e.g.
(x: int, y: float) = (3, 3.7)is illegal, walrus expressions also cannot be annotated), which is a pretty decent reason to differentiate the formatting between them. They're currently formatted as:So a relatively straightforward implementation would be to do option 1 (I'm confused why @srittau says it won't work in variable annotations), but we're adding two unnecessary lines - so IMO option 3 is the superior one.
other scenarios not specific to pep604
I tried to come up with scenarios where you get the same behavior without being in a function definition, or where the
|is wrapped in parentheses, and I'm pretty sure this is the exact same problem popping up:which probably should be formatted as
implementation
Going with option 1, we'd insert brackets whenever encountering this situation - but I think even with option 3 the best way to implement it within the current logic is to add a special pair of "invisible" brackets so the logic for indenting and nested brackets (be they "real" or not) and similar can be reused.
srittau commentedon Sep 17, 2023
Option 1 works in variable annotations, options 2 and 3 don't, because of the missing parentheses.
jakkdl commentedon Sep 17, 2023
Ah sorry, I misinterpreted it as you saying the other way around. 👍
Zac-HD commentedon Sep 25, 2023
I really like the (preview) style changes from #3899
That's essentially option (1) above - it has the advantages of being easy to implement (and indeed implemented), working well with default values, and consistency with variable annotations (though IMO this is a minor concern at most). My favorite style is actually option (3), which omits the parens - but it's unclear what should happen when there's a default value.
I propose that we either stick with the parens-using new status quo, or adopt the
nextlineformatting above, and either way close this issue for good before the next style update / major version.Please comment, or react ❤️ for "keep status-quo parens", or 🚀 for "change and use
nextline".jakkdl commentedon Oct 9, 2023
After implementing
nextlinein #3930 and seeing diffs on real live code we agreed that it in fact was not an improvement in the majority of cases, so we can close this issue as resolved as of #3899, that resolved this in "style 1" with parentheses.srittau commentedon Oct 9, 2023
Thanks everyone, and especially @jakkdl for making this happen!
tekumara commentedon Nov 28, 2023
ICYMI like I did, for short type hints, eg:
you can now add parens around the argument type hints to get this:
jakkdl commentedon Nov 28, 2023
@tekumara you can get that automatically by running black with
--previewto enable the fixes from #3899