Skip to content

Black should add parentheses to long values in dict literalsΒ #620

Closed

Description

@ThomasMarques

Operating system: Linux CentOS 7
Python version: 3.6.6
Black version: 18.9b0
Does also happen on master: Yes (Example on master)

I have this code (line length is greater than allowed)

my_dict = {
    'a key in my dict': deformation_rupture_mean * constraint_rupture_mean / 100.0
}

So Black wrap the line, but without indent :

my_dict = {
    "a key in my dict": deformation_rupture_mean
    * constraint_rupture_mean
    / 100.0
}

I find this indent not very readable.

If I add paranthesis, I get the code below, nice formatted in my opinion.

my_dict = {
    "a key in my dict": (
        deformation_rupture_mean * constraint_rupture_mean / 100.0
    )
}

Should not Black add paranthesis in this case?

Activity

  1. romaingz commented on Nov 26, 2018

    @romaingz

    Going one step further we can observe that with even longer lines, black will propose the following formatting:

    my_dict = {
        "a very very long key in my dict": (
            another_long_operand
            + deformation_rupture_mean * constraint_rupture_mean / 100.0
        )
    }

    Even if black did not add parenthesis, it would be nice if it added that little bit of extra indent.
    It provides more readability in my opinion.

  2. jdufresne commented on Dec 12, 2018

    @jdufresne
    Contributor

    I've found this issue shows up in Django projects that chain a lot of queryset methods together. For example, black was found to produce the following:

    class MyView:
        def get_context_data(self, *args, **kwargs):
            context = {
                "filtered_users": User.objects.all()
                .archived()
                .filter(groups__in=get_groups())
            }

    I think this would be more readable if the chained methods were indented.

  3. added
    F: parenthesesToo many parentheses, not enough parentheses, and so on.
    on Feb 14, 2019
  4. zsol commented on Feb 14, 2019

    @zsol
    Collaborator

    Black should totally add parenthesis in all these cases

  5. changed the title [-]Indent in dictionnary[/-] [+]Black should add parenthesis to long values in dict literals[/+] on Feb 14, 2019
  6. changed the title [-]Black should add parenthesis to long values in dict literals[/-] [+]Black should add parentheses to long values in dict literals[/+] on Feb 14, 2019
  7. uhbif19 commented on Apr 10, 2019

    @uhbif19

    There is probably similar problem with string lines in dictionary. Example:

    REST_FRAMEWORK = {
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
        'PAGE_SIZE': 100,
    }
    

    When I set line-length = 79, black does not try to fix this line, while parenthesis could help to fit line-length restriction. In cases of more long lines, splitting string to more parts is required too.

    @zsol Not sure if this should be separate issue, or just part of this one.

  8. ljades commented on Aug 12, 2019

    @ljades

    Is there any update or fix planned for this issue? A lot of issues were created, closed and referenced to this one at this point. And manually fixing the lines still causes black to undo those fixes and violate its line-length rule.

  9. zsol commented on Aug 12, 2019

    @zsol
    Collaborator

    AFAIK nobody is actively working on this right now, but I'm happy to review a pr if you're interested in contributing

  10. and-semakin commented on Aug 28, 2019

    @and-semakin

    Another annoying case when black decreases readability is this.

    Original code:

    my_function(
        my_kwarg=1 if True else 2
    )

    Blackified code (at first glance it looks like function takes 3 args!):

    my_function(
        my_kwarg=1
        if True
        else 2,
    )

    What I would expect it to look like:

    my_function(
        my_kwarg=(
            1
            if True
            else 2,
        ),
    )

    It happens with black==19.3b0 when function call is indented enough so lines start to wrap.

  11. Holt59 commented on Nov 28, 2019

    @Holt59

    This also happens without string literals or even complex operations. This simple example is not split on multiple lines by black:

    a = {
        SomeLongEnumeration.SOME_LONG_ENUM_NAME: another_pkg.subpkg.another_enum.another_enum_name
    }
    
  12. nourspace commented on Sep 9, 2020

    @nourspace

    Another example

    max_prediction_rank_to_save = self.metadata['additional_params'][
        'max_prediction_rank_to_save'
    ]

    which would look better if parentheses were used

    max_prediction_rank_to_save = (
        self.metadata['additional_params']['max_prediction_rank_to_save']
    )

    If there are too many keys, each could go on a separate line

    max_prediction_rank_to_save = (
        self.metadata['additional_params']
        ['max_prediction_rank_to_save']
        ['another']
        ['looooooooooong_key']
    )
  13. kmulka-medigo commented on Feb 4, 2021

    @kmulka-medigo
  14. zsol commented on Feb 4, 2021

    @zsol
    Collaborator

    To be clear this issue is about dictionary literals. The previous two comments are not examples relevant for this issue (they are about long subscript expressions)

  15. kmulka-medigo commented on Feb 4, 2021

    @kmulka-medigo

    @zsol Ok, I've created a new issue here: #1965

  16. sodul commented on Apr 22, 2021

    @sodul

    I see folks mentioning that parentheses should be added, but they are completely unecessary inside a dictionary since Python already knows the dictonary is not closed until the final }.

    my_dict = {
        "a key in my dict": (
            deformation_rupture_mean * constraint_rupture_mean / 100.0
        )
    }
    

    Should just be:

    my_dict = {
        "a key in my dict":
            deformation_rupture_mean * constraint_rupture_mean / 100.0,
    }
    

    And:

    my_dict = {
        "a very very long key in my dict": (
            another_long_operand
            + deformation_rupture_mean * constraint_rupture_mean / 100.0
        ),
        "other": 42
    }
    

    Should be:

    my_dict = {
        "a very very long key in my dict":
            another_long_operand
            + deformation_rupture_mean * constraint_rupture_mean / 100.0,
        "other": 42,
    }
    

    The indentation makes it really clear that the data belongs to the key without the need for the extra parentheses.

    This issue is mentioned in #2063.

    So far this is the single issue that prevents us from adopting Black for auto formatting our codebase since the longer lines break our other CI checks.

  17. added
    S: acceptedThe changes in this design / enhancement issue have been accepted and can be implemented
    T: styleWhat do we want Blackened code to look like?
    and removed on May 30, 2021
  18. felix-hilden commented on Nov 5, 2021

    @felix-hilden
    Collaborator

    Another case would be fluent interfaces like in #2591.

  19. roganartu commented on Mar 23, 2022

    @roganartu

    Another place I had this happen recently that I didn't see mentioned above but seems related was in a list.

    Given this:

    ["foo", "bar", "baz" if some_really_long_variable else "some other long value"]
    

    black will generate this:

    [
        "foo",
        "bar",
        "baz"
        if some_really_long_variable
        else "some other long value",
    ]
    

    Which is difficult to read, easy to miss in review, and easy to accidentally break by adding a comma in the wrong place in future. Manually adding parens results in black generating this, which is much clearer:

    [
        "foo",
        "bar",
        (
            "baz"
            if some_really_long_variable
            else "some other long value"
        ),
    ]
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    F: parenthesesToo many parentheses, not enough parentheses, and so on.S: acceptedThe changes in this design / enhancement issue have been accepted and can be implementedT: styleWhat do we want Blackened code to look like?

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions