-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Call chain formatting in fluent style (#6151)
Implement fluent style/call chains. See the `call_chains.py` formatting for examples. This isn't fully like black because in `raise A from B` they allow `A` breaking can influence the formatting of `B` even if it is already multiline. Similarity index: | project | main | PR | |--------------|-------|-------| | build | ??? | 0.753 | | django | 0.991 | 0.998 | | transformers | 0.993 | 0.994 | | typeshed | 0.723 | 0.723 | | warehouse | 0.978 | 0.994 | | zulip | 0.992 | 0.994 | Call chain formatting is affected by #627, but i'm cutting scope here. Closes #5343 **Test Plan**: * Added a dedicated call chains test file * The ecosystem checks found some bugs * I manually check django and zulip formatting --------- Co-authored-by: Micha Reiser <[email protected]>
- Loading branch information
1 parent
35bdbe4
commit 99baad1
Showing
16 changed files
with
917 additions
and
517 deletions.
There are no files selected for viewing
157 changes: 157 additions & 0 deletions
157
crates/ruff_python_formatter/resources/test/fixtures/ruff/call_chains.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
# Test cases for call chains and optional parentheses, with and without fluent style | ||
|
||
raise OsError("") from a.aaaaa( | ||
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa | ||
).a(aaaa) | ||
|
||
raise OsError( | ||
"sökdjffffsldkfjlhsakfjhalsökafhsöfdahsödfjösaaksjdllllllllllllll" | ||
) from a.aaaaa( | ||
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa | ||
).a( | ||
aaaa | ||
) | ||
|
||
a1 = Blog.objects.filter(entry__headline__contains="Lennon").filter( | ||
entry__pub_date__year=2008 | ||
) | ||
|
||
a2 = Blog.objects.filter( | ||
entry__headline__contains="Lennon", | ||
).filter( | ||
entry__pub_date__year=2008, | ||
) | ||
|
||
raise OsError("") from ( | ||
Blog.objects.filter( | ||
entry__headline__contains="Lennon", | ||
) | ||
.filter( | ||
entry__pub_date__year=2008, | ||
) | ||
.filter( | ||
entry__pub_date__year=2008, | ||
) | ||
) | ||
|
||
raise OsError("sökdjffffsldkfjlhsakfjhalsökafhsöfdahsödfjösaaksjdllllllllllllll") from ( | ||
Blog.objects.filter( | ||
entry__headline__contains="Lennon", | ||
) | ||
.filter( | ||
entry__pub_date__year=2008, | ||
) | ||
.filter( | ||
entry__pub_date__year=2008, | ||
) | ||
) | ||
|
||
# Break only after calls and indexing | ||
b1 = ( | ||
session.query(models.Customer.id) | ||
.filter( | ||
models.Customer.account_id == account_id, models.Customer.email == email_address | ||
) | ||
.count() | ||
) | ||
|
||
b2 = ( | ||
Blog.objects.filter( | ||
entry__headline__contains="Lennon", | ||
) | ||
.limit_results[:10] | ||
.filter( | ||
entry__pub_date__month=10, | ||
) | ||
) | ||
|
||
# Nested call chains | ||
c1 = ( | ||
Blog.objects.filter( | ||
entry__headline__contains="Lennon", | ||
).filter( | ||
entry__pub_date__year=2008, | ||
) | ||
+ Blog.objects.filter( | ||
entry__headline__contains="McCartney", | ||
) | ||
.limit_results[:10] | ||
.filter( | ||
entry__pub_date__year=2010, | ||
) | ||
).all() | ||
|
||
# Test different cases with trailing end of line comments: | ||
# * fluent style, fits: no parentheses -> ignore the expand_parent | ||
# * fluent style, doesn't fit: break all soft line breaks | ||
# * default, fits: no parentheses | ||
# * default, doesn't fit: parentheses but no soft line breaks | ||
|
||
# Fits, either style | ||
d11 = x.e().e().e() # | ||
d12 = (x.e().e().e()) # | ||
d13 = ( | ||
x.e() # | ||
.e() | ||
.e() | ||
) | ||
|
||
# Doesn't fit, default | ||
d2 = ( | ||
x.e().esadjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkfsdddd() # | ||
) | ||
|
||
# Doesn't fit, fluent style | ||
d3 = ( | ||
x.e() # | ||
.esadjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk() | ||
.esadjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk() | ||
) | ||
|
||
# Don't drop the bin op parentheses | ||
e1 = (1 + 2).w().t() | ||
e2 = (1 + 2)().w().t() | ||
e3 = (1 + 2)[1].w().t() | ||
|
||
# Treat preserved parentheses correctly | ||
f1 = (b().c()).d(1,) | ||
f2 = b().c().d(1,) | ||
f3 = (b).c().d(1,) | ||
f4 = (a)(b).c(1,) | ||
f5 = (a.b()).c(1,) | ||
|
||
# Indent in the parentheses without breaking | ||
g1 = ( | ||
queryset.distinct().order_by(field.name).values_list(field_name_flat_long_long=True) | ||
) | ||
|
||
# Fluent style in subexpressions | ||
if ( | ||
not a() | ||
.b() | ||
.cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc() | ||
): | ||
pass | ||
h2 = ( | ||
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | ||
+ ccccccccccccccccccccccccc() | ||
.dddddddddddddddddddddd() | ||
.eeeeeeeeee() | ||
.ffffffffffffffffffffff() | ||
) | ||
|
||
# Parentheses aren't allowed on statement level, don't use fluent style here | ||
if True: | ||
(alias).filter(content_typeold_content_type).update( | ||
content_typenew_contesadfasfdant_type | ||
) | ||
|
||
zero( | ||
one, | ||
).two( | ||
three, | ||
).four( | ||
five, | ||
) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.