3

I use Black for Python, which conforms to PEP8. It removes the indentation from the second line of a two line long value string:

mydict = {
    'key0': 'value0',
    'key1': 'long-two-lines-string-value1-does-not-fit-in-one-line-has-to-continue'
            'value1'
}

to:

mydict = {
    'key0': 'value0',
    'key1': 'long-two-lines-string-value1-does-not-fit-in-one-line-has-to-continue'
    'value1',
}

A colleague questioned this change, and I am wondering if there is any resource/reference that I can use to backup Black's decision to format the code like?

Couldn't find something in PEP8 -- Style Guide for Python Code and The Black code style.

Demo

Related, but doesn't answer my question: What is the proper way to format a multi-line dict in Python?


PS: # fmt: off prevents Black from formatting line, but I don't want to use it, since my team doesn't use Black in general.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    If the rest of your team doesn't use Black, consider using something less opinionated. – chepner Oct 09 '20 at 20:21
  • 2
    I don't think you *can* defend it. In my view continuation should either be aligned with the opening (your before state) or have one level of extra indent, otherwise I read it as a key and get confused by the comma not the colon, then have to go back to work out it's a continuation. The wrapped element, which should follow the guidance in https://www.python.org/dev/peps/pep-0008/#indentation, is the *value*. I'd be inclined to raise this as a bug to see what the maintainers think. – jonrsharpe Oct 09 '20 at 20:22
  • @chepner I tried to use [other plugins](https://stackoverflow.com/questions/64177034/pep8-plugin-breaks-my-type-hint-code-in-sublime-3), but they would either break the code or slow down my text editor. Black really works awesome so far, apart from this case. However it's barely configurable, so the option of abandon it is on the table I am afraid. – gsamaras Oct 09 '20 at 20:26
  • 1
    @jonrsharpe I think turning your comment into an answer would make sense. I opened a [GitHub issue](https://github.com/psf/black/issues/1758). – gsamaras Oct 09 '20 at 20:37
  • Being barely configurable is considered a *feature* by Black. If you need to defend the choices it makes, then you aren't in its target audience. Your obligation is to your team, not a tool. – chepner Oct 09 '20 at 20:39
  • @chepner I used this phrase straight from Black's README, didn't meant it that way, just wanted to stress out that there is no user setting that would prevent Black from touching this line. :) – gsamaras Oct 09 '20 at 20:41

1 Answers1

2

The Black code style was the right place to check and you are right, it's not super clear for this use-case. I can say if you don't split the string of the value into two strings then Black will put it on one line which you may prefer. I'm not sure Black has a good way to know when it can concatenate 2 strings to one when it makes sense - see discussion here.

e.g

mydict = {
    "key0": "value0",
    "key1": "long-two-lines-string-value1-does-not-fit-in-one-line-has-to-continue value1",
}

Using parentheses will make value more readable too perhaps? (this is my go-to usually) e.g.

mydict = {
    "key0": "value0",
    "key1": (
        "long-two-lines-string-value1-does-not-fit-in-one-"
        "line-has-to-continue value1"
    ),
}

By the way, noticed black didn't replace your single quotes with double quotes; is that a setting you are using for your projects?

  • 1
    The one liner violates the max line length then in my case. As for the parentheses, I am not sure that they are really solving the issue or masking it here, but they do indeed the trick. I disabled string normalization, because team uses single quotes for strings, although I personally prefer the C methodology, but we have a democracy! :) – gsamaras Oct 09 '20 at 20:45
  • 1
    You submitted an issue too which is a good way to get more context. – Patrick Cullen Oct 09 '20 at 21:05