Live data from Hacker News

Black – Uncompromising Python code formatter

github.com

191–200 of 251 posts

Re: Black – Uncompromising Python code formatter

#191
Automatic code formatting should be the norm in programming. Once you get used to format-on-save and CI enforcement (especially on a team) it's hard to imagine going back to having to think about how to format your code, or pestering collaborators to follow some nickpicky code style guide.

Re: Black – Uncompromising Python code formatter

#192
post #163

Earlier quoted context omitted.

Punctuation, or lack of it, can change the meaning in programming languages too. https://medium.freecodecamp.org/codebyte-why-are-explicit-se...

Yeah, but no one would remove punctuation from a program because they think it looks nicer. > Javascript developers Oh, of course.

I remove semicolons from JS b/c I feel like they are a bit of a hack. Except where it's required by the language (for loops, which are becoming less used quite rapidly), your code generally shouldn't be so complex as to require semicolons for readability.

Having said that, I've been introducing a lot more colons, since I use TypeScript.

Re: Black – Uncompromising Python code formatter

#193

Earlier quoted context omitted.

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…

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 })

That's exactly how I'd write it, and see it most commonly written.

Re: Black – Uncompromising Python code formatter

#194

Earlier quoted context omitted.

No, we can't. My (and, by the sound of it, CrLf's) favorite format relies on information that your pre-commit hook has artificially removed from the code. Eg: munge(gidget, thing1,thing2,thing3); cmplt(dtypeA,valueA, dtypeB,valueB); (Most cases are more subtle (and thus less amenable to "oh, you just need to build a complete static type checker into the formatter") than this, but I wanted an obvious example.)

It seems like the signature of the functions should be different, especially the second example. I would have written the cmplt function to take tuple pairs: cmplt( (type_a, value_a), (type_b, value_b), ) That's much more clear about the relationship between each pair of values either way, and would get formatted nicely by Black.

It would also have been a better way to define the function, in Python 2.

    def cmplt((type_a, value_a), (type_b, value_b)):
        return ...
I was sad when they removed argument unpacking in Python 3. I thought it was a really elegant feature of the language.

Re: Black – Uncompromising Python code formatter

#195

Earlier quoted context omitted.

> no-one likes what the autoformatter does to their code, everyone likes what the autoformatter does to their coworkers' code It always strikes me as strange that we spend our own effort and time on systems that mandate code style when my unambiguously correct style and my coworkers obviously incorrect style both end up converted to the same AST for any useful work. Why isn't style an entirely local choice, with a hi…

One term for this, I believe, is “structural editors.”

Actually, the term is “structure editor”:

https://en.wikipedia.org/wiki/Structure_editor

Re: Black – Uncompromising Python code formatter

#196

Earlier quoted context omitted.

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…

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 })

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

#197

Earlier quoted context omitted.

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…

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 })

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

#198

Earlier quoted context omitted.

It seems like the signature of the functions should be different, especially the second example. I would have written the cmplt function to take tuple pairs: cmplt( (type_a, value_a), (type_b, value_b), ) That's much more clear about the relationship between each pair of values either way, and would get formatted nicely by Black.

It would also have been a better way to define the function, in Python 2. def cmplt((type_a, value_a), (type_b, value_b)): return ... I was sad when they removed argument unpacking in Python 3. I thought it was a really elegant feature of the language.

Pretty much no one used it, and it was....weird.

what do you think the result of

    def cmplt((type_a, value_a), (type_b, value_b)):
        return locals()
is? Now granted, you shouldn't do that, but what you think it is? a dict with 4 keys, right? {'type_a': ..., 'value_b': ...}.

That's wrong. It has those four keys, and two more: '.0' and .1', whose values are the packed tuples.

!?!?!

Re: Black – Uncompromising Python code formatter

#199

Earlier quoted context omitted.

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 })

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…

[deleted]

Re: Black – Uncompromising Python code formatter

#200
Played around with it in the sandbox and immediately disliked its insistence on putting every item in a sufficiently-long array on its own line. For example, something like:

    foo = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 ]
Black formats it to something more like:

    foo = [
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29,
        30
    ]
That's, in my not-so-humble opinion, absolutely atrocious. Compare with how Emacs formats if it I press M-q (with python-mode and EditorConfig):

    foo = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
            19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 ]
More readable (again, IMO) and way more compact.

The default line length of 88 also seems weird, but at least that's readily configurable to my preferred 80.

Post reply on HN