Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formatter: prefer_splitting_right_hand_side_of_assignments preview style #6975

Closed
Tracked by #6935 ...
MichaReiser opened this issue Aug 29, 2023 · 2 comments · Fixed by #8943
Closed
Tracked by #6935 ...

Formatter: prefer_splitting_right_hand_side_of_assignments preview style #6975

MichaReiser opened this issue Aug 29, 2023 · 2 comments · Fixed by #8943
Assignees
Labels
formatter Related to the formatter preview Related to preview mode features

Comments

@MichaReiser
Copy link
Member

MichaReiser commented Aug 29, 2023

Implement Black's improved linebreaks preview style. The style is gated behind the prefer_splitting_right_hand_side_of_assignments preview flag.

It seems that the right side now always gets parenthesized regardless if it makes the right fit or not (no longer has the optimisation to omit parentheses if the content still doesn't fit after adding the parentheses).

https://play.ruff.rs/36e390bc-b3d2-41b2-80d9-87608337727a

We may be able to get away by simply not returning BestFit if the expression is an assignment value.

I expect this change to improve the performance because there are fewer cases where we'll need to fall back to use Best Fitting.

Black (and our) stable style:

def f():
    """Black's `Preview.prefer_splitting_right_hand_side_of_assignments`"""
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[
        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    ] = cccccccc.ccccccccccccc.cccccccc

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[
        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    ] = cccccccc.ccccccccccccc().cccccccc

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[
        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    ] = cccccccc.ccccccccccccc(d).cccccccc

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
            cccccccc.ccccccccccccc(d).cccccccc + e
    )

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
            cccccccc.ccccccccccccc.cccccccc + e
    )
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
            cccccccc.ccccccccccccc.cccccccc
            + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
    )

    self._cache: dict[
        DependencyCacheKey, list[list[DependencyPackage]]
    ] = collections.defaultdict(list)
    self._cached_dependencies_by_level: dict[
        int, list[DependencyCacheKey]
    ] = collections.defaultdict(list)

Preview style, which consistently breaks the right side first:

def f():
    """Black's `Preview.prefer_splitting_right_hand_side_of_assignments`"""
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
        cccccccc.ccccccccccccc.cccccccc
    )

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
        cccccccc.ccccccccccccc().cccccccc
    )

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
        cccccccc.ccccccccccccc(d).cccccccc
    )

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
        cccccccc.ccccccccccccc(d).cccccccc + e
    )

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
        cccccccc.ccccccccccccc.cccccccc + e
    )
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (
        cccccccc.ccccccccccccc.cccccccc
        + eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
    )

    self._cache: dict[DependencyCacheKey, list[list[DependencyPackage]]] = (
        collections.defaultdict(list)
    )
    self._cached_dependencies_by_level: dict[int, list[DependencyCacheKey]] = (
        collections.defaultdict(list)
    )
@MichaReiser
Copy link
Member Author

MichaReiser commented Oct 30, 2023

We'll need to make best_fits_parenthesize break the right before the left when using preview style, similar to regular groups. This can be accomplished by measuring the parenthesized content instead of the unparenthesized content inside of fits_element. See #8182 (comment)

We should add a mode to BestFitsParenthesize to avoid exposing the preview flag to the printer (preview is a language specific concept)

@MichaReiser
Copy link
Member Author

MichaReiser commented Oct 31, 2023

Some more details. psf/black#4006

Overall, the assignment will be the odd one that uses a different parenthesizing layout (not applying the logic to omit parentheses if it exceeds the line width). This will be different from clause headers and await, return, etc where expressions should only be parenthesized if necessary. This can be implemented by returning Multline for the NeedsParentheses implementation that currently return BestFit if the parent is an assignment

@MichaReiser MichaReiser changed the title Improved line breaks Formattter: prefer_splitting_right_hand_side_of_assignments preview style Nov 29, 2023
@MichaReiser MichaReiser changed the title Formattter: prefer_splitting_right_hand_side_of_assignments preview style Formatter: prefer_splitting_right_hand_side_of_assignments preview style Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
formatter Related to the formatter preview Related to preview mode features
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant