News for hackers. Stuff that matters.
Re:Black – Uncompromising Python code formatter by camgunz on Friday May 17, 2019 @12:25PM (#19941068)
Against my better judgment I'll bite.

I super dislike black's formatting, and I think it's really rare to actually see it in codebases. It wraps weirdly (sometimes not at all). I'd prefer to use yapf, but last I checked it still crashes on "f-strings".

Here's a small example:

    basket.add({
        apple.stem
        for satchel in satchels
        for apple in satchel
    })
Black formats this as:

    basket.add(
        {
            apple.stem
            for satchel in satchels
            for apple in satchel
        }
    )
        
I've never seen Python code like that.

I totally believe using a formatter is good practice. Black is in a challenging position of coming into a community with a lot of existing code and customs, and I get that. But I also think that's an opportunity, rather than having to guess at what is good, there's a wealth of prior art to look at. I wish it had done this, rather than essentially codify the author's style.

Re:Black – Uncompromising Python code formatter by bunderbunder on Friday May 17, 2019 @12:59PM (#19941424)
That one actually makes a lot of sense to me, even if I've got to admit that I tend to go with the first option in my own code. It looks to me like a result of a couple rules that, in general, are sound: First, if an argument list can't fit all on one line, then every argument needs to go on a new line. And all the arguments need to be indented to the same level. The argument to that function includes the braces, so the opening one needs to go on a new line, and the closing one needs to be indented as well.

In this particular case, that may result in code that breaks with tradition. But I can't see a way to preserve the tradition without creating special or edge cases. For example, we can't follow the first option and get clean formatting with a function like zip. You'll have a train wreck of bad options about where to put the braces and how to place the comprehension's body in relation to the braces that enclose it. Versus, with Black's style, the answer is easy and straightforward, because you just do it the same way you would anywhere else:

  zipped = zip(
      {
          apple.stem
          for satchel in satchels
          for apple in satchel
      },
      {
          apple.core
          for satchel in satchels
          for apple in satchel
      }
  )
IMO, that's good, even if it isn't what we're all used to. Having a bunch of special cases just to match what someone might think is more aesthetically pleasing in specific situations is not a desirable feature in a set of autoformatting rules.
Re:Black – Uncompromising Python code formatter by jdmichal on Friday May 17, 2019 @06:41PM (#19944315)
OTOH, something like this looks fine also, and is internally consistent with GP's single-block example:

    zipped = zip({
        apple.stem
        for satchel in satchels
        for apple in satchel
    }, {
        apple.core
        for satchel in satchels
        for apple in satchel
    })
Re:Black – Uncompromising Python code formatter by bunderbunder on Friday May 17, 2019 @07:22PM (#19944516)
That works if they're both comprehensions, but starts looking more gross when the 2nd argument isn't a comprehension, and now you're looking at deciding among options like

    zipped = zip({
        apple.stem
        for satchel in satchels
        for apple in satchel
    }, 
        someList
    )
or

    zipped = zip({
        apple.stem
        for satchel in satchels
        for apple in satchel
    }, someList)
(Which admittedly looks reasonably tidy, but starts to get gross again if we start looking at 3-ary functions.)

You've also got to contend with the first not being a comprehension meaning that the comprehension's indenting can't so easily be kept the same:

    zipped = zip(
        someList,
        {
            apple.stem
            for satchel in satchels
            for apple in satchel
        }
    )

Which is where I was going with the comment about edge cases. Personally, I don't want formatting rules where you might decide to format the arguments to a function in different ways depending on the specifics of what other arguments the function has. I like simple. Give me one rule for when it all fits on one line, and another rule for when it doesn't. And make sure neither of the rules causes me to have to re-indent things just because a function picked up an additional argument. And make sure that the rules are completely oblivious to the function's arity.
Re:Black – Uncompromising Python code formatter by JoBrad on Friday May 17, 2019 @07:07PM (#19944444)
Haven't had the chance to use Python much lately, and immediately thought of how much JS/TS could benefit from comprehensions like this:

  zipped = {apple.stem: apple.core
              for satchel in satchels
                for apple in satchel}
Re:Black – Uncompromising Python code formatter by auscompgeek on Saturday May 18, 2019 @01:10AM (#19945788)
There was a proposal a few years ago to add array comprehensions to the language, but it was ultimately rejected in favour of using .map/.filter instead.

Not sure what came about of object comprehensions though.

Re:Black – Uncompromising Python code formatter by zestyping on Friday May 17, 2019 @06:59PM (#19944411)
That's exactly how I'd write it, and see it most commonly written.
Re:Black – Uncompromising Python code formatter by jimbo1qaz on Saturday May 18, 2019 @05:36AM (#19946528)
Why not "if a multi-argument list is too long to go on 1 line, each argument must go on its own line"?

Maybe that would fail to put long strings on their own line?

Re:Black – Uncompromising Python code formatter by rav on Friday May 17, 2019 @12:34PM (#19941165)
I completely agree that black does not format all examples in a nice manner, and your example is something I see pretty often. Whenever black adds too many indentation levels and line breaks in what should be a simple-enough statement, I simply refactor into multiple statements, e.g.

    stems = {
        apple.stem for satchel in satchels for apple in satchel
    }
    basket.add(stems)
I concede that without black it wouldn't have made sense to make that refactoring, but since I really want to use an autoformatter, and black is the best autoformatter I have, I'd rather restructure my code slightly so that I can just use black 100% all the time.
Re:Black – Uncompromising Python code formatter by tedmiston on Friday May 17, 2019 @12:39PM (#19941221)
It's an interesting meta thought that using the autoformatter changes the way you write your code. Not that that's implicitly a good or a bad thing, I just find it interesting.
Re:Black – Uncompromising Python code formatter by acdha on Friday May 17, 2019 @08:29PM (#19944823)
I think it’s under-appreciated when comparing tools like this. I’ve noticed that a bit since adopting Prettier and Black and one thing I’ve noticed during code review is that usually when I end up changing code structure to get better results from the tool, it’s a refactor that I probably would felt like I should have done but might have put off due to laziness even though it’s really not that much work.

I’m kind of thinking of it as something like baking some exercise into your day by putting a walk into your commute: the little nudge of not fighting the tool on something minor means you don’t skip little things, and over time that adds up more than it seems at first.

Re:Black – Uncompromising Python code formatter by setr on Friday May 17, 2019 @02:25PM (#19942203)
Every metatool you use does that - syntax highlighting, linters, formatters, ide’s, etc

You always end up adapting to the tool, while adapting the tool to you

Until you oneday reach a perfect harmony with your tool... until you introduce another one, and the equilibrium must once again be found.

Also of note, this is a general principle/behavior (eg you and your furniture..!)

Re:Black – Uncompromising Python code formatter by ali_m on Friday May 17, 2019 @01:34PM (#19941762)
I actually much prefer Black's version in this case. I find nested comprehensions quite a lot easier to read if they are broken onto multiple lines.
Re:Black – Uncompromising Python code formatter by jordic on Saturday May 18, 2019 @12:48AM (#19945717)
I'm doing the same :/
Re:Black – Uncompromising Python code formatter by switch007 on Friday May 17, 2019 @12:38PM (#19941207)
> Black formats this as:

To be clear though, in your example, it would format it as:

  basket.add({apple.stem for satchel in satchels for apple in satchel})
It might also format it as

  basket.add(
      {apple.stem for satchel in satchels for apple in satchel}
  )
It only formats like your example if the statement is much further indented I believe
Re:Black – Uncompromising Python code formatter by tedmiston on Friday May 17, 2019 @12:37PM (#19941206)
I think that's why it self-describes as an opinionated formatter vs YAPF where one has very granular control.

My understanding is that by using Black you're saying I choose to not express my opinions about formatting aesthetics and delegate that decision to Black instead.

Re:Black – Uncompromising Python code formatter by asdkhadsj on Friday May 17, 2019 @01:06PM (#19941490)
I'm not a python person (for many years, at least), but I'd choose black for a completely different reason. By using Black, I'm choosing standardization over my whims.

Which, as a longtime Go dev and now Rust dev, I love formatters that are opinionated. I don't always love what Gofmt or Rustfmt do, but I definitely like consistency that the community has in code style.

So I don't care what Black thinks - I care what, hopefully, everyone uses. Though, I could see a situation where formatting can be altered and the project has a format config. Meaning that while code fmt differs between projects, it would be consistent among all devs working on X projects.

Re:Black – Uncompromising Python code formatter by fjp on Friday May 17, 2019 @02:32PM (#19942253)
Our test pipeline fails any Python service trying to deploy if the black style check fails.

I was initially grumpy about my org adopting black because I preferred single quotes, but the level of standardization is a huge win in my book. I never even think about my code style anymore, I just write it and then run black.

Re:Black – Uncompromising Python code formatter by meowface on Friday May 17, 2019 @05:41PM (#19943830)
I've always been a double-quoter, in contrast to most Python devs I know/work with. After we standardized on black, I got some satisfaction seeing all of my coworkers bend to my will (/s).
Re:Black – Uncompromising Python code formatter by detaro on Friday May 17, 2019 @05:44PM (#19943850)
How narrow those two choices are! The correct answer is obviously to use single-quotes for keys and key-like cases and double-quotes for values. Make formatters impossible to write! (last sentence very /s, but that style actually exists)
Re:Black – Uncompromising Python code formatter by kbd on Saturday May 18, 2019 @01:27AM (#19945835)
That actually seems to be the de-facto Python style. Even Guido said at some point that that's his convention.
Re:Black – Uncompromising Python code formatter by witten on Friday May 17, 2019 @10:27PM (#19945222)
You can disable string normalization with Black, and then continue using single quotes all day. But then, yeah, you give up enforced standardization on that.
Re:Black – Uncompromising Python code formatter by prirun on Saturday May 18, 2019 @01:14PM (#19948501)
I started out double quoting but it takes longer to type Shift " vs ' so I switched early on.
Re:Black – Uncompromising Python code formatter by andbberger on Friday May 17, 2019 @01:24PM (#19941660)
Counterpoint: I do this all the time, and I write a lot of Python
Re:Black – Uncompromising Python code formatter by ebg13 on Friday May 17, 2019 @02:18PM (#19942149)
I write code like that, because lumping brackets together absolutely makes it harder to see what they are.
Re:Black – Uncompromising Python code formatter by OhSoHumble on Friday May 17, 2019 @01:52PM (#19941921)
Honestly, I write my code like that. It could be because I write in other languages but I find that the right amount of indentation and vertical white space just makes the code infinitely better to read.
Re:Black – Uncompromising Python code formatter by ForHackernews on Friday May 17, 2019 @06:49PM (#19944361)
> I wish it had done this, rather than essentially codify the author's style.

Yeah, I keep seeing people singing the praises of black and I'm really dreading the inevitable future where people start acting like this dude's opinion is Correct Official Python Style.

Re:Black – Uncompromising Python code formatter by mixmastamyk on Friday May 17, 2019 @12:40PM (#19941230)
Agreed. Would also like an alternative that used single-quotes instead. Do yapf or autopep8 have that option?
Re:Black – Uncompromising Python code formatter by thisjeremiah on Friday May 17, 2019 @12:35PM (#19941182)
if the progress of prettier (js) over the past few years is any indicator of what will happen with black, there will likely be incremental improvements in black that address the poor formatting cases you’re concerned about. i remember when prettier first came out, i was not convinced until my “standard” for formatting was met. but it was met eventually.
Re:Black – Uncompromising Python code formatter by zaphar on Friday May 17, 2019 @12:30PM (#19941124)
While I agree that the formatting choice looks a little weird. The primary benefit of a formatter is that the formatting is always the same not. It's less important that it matches everyone's preferences and more important that it always formats the code the same way.
Re:Black – Uncompromising Python code formatter by Demiurge on Friday May 17, 2019 @12:34PM (#19941175)
If most people dislike it on my team, we simply won't use it :(
Re:Black – Uncompromising Python code formatter by zaphar on Friday May 17, 2019 @03:51PM (#19942952)
It must be nice to work on a team where everyone agrees on the formatting. I don't think I've ever worked with a team where that was true. The exception being languages where the formatting was enforced by the language tooling itself. Those occasions no one even discussed it so I wouldn't exactly know if they agreed with it or not.
Re:Black – Uncompromising Python code formatter by GeorgeTirebiter on Friday May 17, 2019 @06:29PM (#19944205)
> there's a wealth of prior art to look at

Precisely. I wonder why ML has not been applied here.

Re:Black – Uncompromising Python code formatter by theelous3 on Saturday May 18, 2019 @05:05PM (#19949708)
Because codebases are rarely even consistent amongst themselves. Getting good examples would be harder than just making the decisions yourself the way you like them. There aren't that many structures to consider.
Re:Black – Uncompromising Python code formatter by objektif on Friday May 17, 2019 @01:13PM (#19941562)
Thats how I code in production.
Re:Black – Uncompromising Python code formatter by Demiurge on Friday May 17, 2019 @12:33PM (#19941157)
It's a very valid point. If there is a universal format, it should not do things so rare. The above example should be easy to address, check if the method argument is a single dictionary or multiple.
Re:Black – Uncompromising Python code formatter by jordic on Saturday May 18, 2019 @12:48AM (#19945711)
same here! anyway, having a default formatter is awesome!
Re:Black – Uncompromising Python code formatter by emplynx on Friday May 17, 2019 @12:34PM (#19941173)
I use it with f-strings all day long...
Re:Black – Uncompromising Python code formatter by camgunz on Friday May 17, 2019 @01:13PM (#19941559)
Oh that's interesting. I looked up the Issue [1] and it looks like it was an upstream bug, but also if you're using that version of Python (which, of course, we are) you'll still have that problem. Thanks for chiming in, you're gonna make my life a lot better haha.

[1]: https://github.com/google/yapf/issues/342

Re:Black – Uncompromising Python code formatter by jrootabega on Friday May 17, 2019 @01:02PM (#19941460)
Your examples read like a poem
Re:Black – Uncompromising Python code formatter by mlevental on Friday May 17, 2019 @12:29PM (#19941117)
who cares what it looks like. it's meaningless (as long as it doesn't break things, which black doesn't). the only thing that matters is consistency.
Re:Black – Uncompromising Python code formatter by darepublic on Friday May 17, 2019 @12:46PM (#19941294)
the outputted code should at least be decently readable and predictable, otherwise I don't see the point of having a formatter at all.
Re:Black – Uncompromising Python code formatter by mlevental on Friday May 17, 2019 @02:03PM (#19942030)
>the outputted code should at least be decently readable

black isn't an uglifier/minifier. it's undoubtedly readable.

>predictable

why?

Re:Black – Uncompromising Python code formatter by anoncake on Friday May 17, 2019 @04:29PM (#19943276)
> I'd prefer to use yapf, but last I checked it still crashes on "f-strings".

There is a great autoformatter that does not have this issue. Using it guarantees that you'll never have to stick with an outdated version of a language because your autoformatter of choice hasn't been updated for the current one, or even worse, is not maintained anymore.

It's called "cat".