Live data from Hacker News

Black: An uncompromising Python code formatter

github.com

181–190 of 262 posts

Re: Black: An uncompromising Python code formatter

#181

Earlier quoted context omitted.

That's the #1 complaint I have (and hear) about Black. Everything else, I can live with. And honestly, I can live with using double quotes everywhere, especially when I can type single quotes and then let it re-write them. It's just that they currently look really, really odd to me because that's not how Python is traditionally written.

I prefer a quoting convention of single quotes for text identifiers (as they rarely contain quotes) and double quotes for English text (because contractions are common). Thus: key['first_name'] print("Isn't this clearer?")

I generally follow this convention:

1. Any string literal that contains either ' xor " will be delimited by the other one. 2. For all other string literals, delimit by " if it's meant for human eyes only, delimit by ' if it's meant for computers as well.

Re: Black: An uncompromising Python code formatter

#182

I really want to use Black, but we have a particular style point that we’d miss so much that we haven’t adopted it yet... Double quotes for strings that need to be human readable, single quotes otherwise. This makes it so obvious when something is going to be sent to the user, we find it really useful. That said, I think Black’s appeal is it’s uncompromising nature, so I wouldn’t ask it to change. Adding the option t…

Do you find your team enforcing the string quote rule consistently? It seems to me like it's easy to miss at times as automatic enforcement is impossible. Are there no cases where a string that wasn't originally planned to be user-visible ends up being so? I've heard this idea at times but when I looked at actual codebases it turns out it's more of an aspiration than an actual rule. And if you can't depend on it, why…

> And if you can't depend on it, why have it?

That's a bit rich. There are other conventions in programming that you can't depend on technically but serve a real purpose. Identifier naming and comments are the first that come to mind.

If a language gives you a choice of token that has no semantic distinction then different people will adopt different semantics by convention.

As an aside, calling a tool "opinionated" is code for "my conventions are better than yours". That's fine if I don't have any conventions or I can't decide, but if I have decided, then it's just offensive.

Re: Black: An uncompromising Python code formatter

#183

Earlier quoted context omitted.

Why black over yapf?

Black is a simple tool. It tries to implement a single code style well. It's not configurable. We tried YAPF before and could never roll it out for everybody. I even contributed the "facebook" style to the tool. There were a few reasons why YAPF didn't work out for us but the most important were: - YAPF would at times not produce deterministic formatting (formatting the same file the second time with no changes in be…

RE: non-deterministic formatting: I'm not familiar with YAPF, but what kind of behaviour does it have? Like if you run it on two copies of the same file you might get different results, or that it's not idempotent (i.e. sometimes YAPF(YAPF(source)) != YAPF(source))?

Re: Black: An uncompromising Python code formatter

#184
post #180

Has anyone rolled this out to an existing codebase? What's the best practice? A single commit that reformats the whole codebase? How do you avoid creating merge hell?

You can see how this was done for Fabric, PyPA/Warehouse, and pytest.

General guidelines:

1. One commit with only the automatic formatting. Afterwards you'll be able to skip over it easily with `git hyper-blame` or `git blame $BLACK_REV^ -- $FILE`.

2. Avoid leaving open pull requests. If you do, after landing the blackening commit, blacken all pull requests, too. They shouldn't conflict then.

3. Set up enforcement with pre-commit or CI (you can run `black --check` on Travis or similar).

4. Don't forget the repo badge ;-)

Re: Black: An uncompromising Python code formatter

#185
Love the idea of eliminating formatting debates when writing Python.

At the risk of being redundant, I also raise an eyebrow at the choice to prefer double quotes for strings. My company standardized on single quotes, mainly to be consistent with repr and also encourage the use of double quotes in messages displayed to the user.

Everything else seems in order. I might increase the line width to 90 just to use an easier value to remember when configuring editors and other tools ;)

Re: Black: An uncompromising Python code formatter

#186
post #155

Earlier quoted context omitted.

I agree about the noise, but, it's much easier to work with. raise FooException("Can't load bar") works, as does f"The flange is elevated by {flange['spronge']} degrees of spronge."

Goes both ways, sometimes there's text to quote: raise KeyError('"%s" not found.' % name) f'The flange is elevated by {flange["spronge"]} degrees of spronge.' I don't normally use many contractions or possessives in my code, but am willing to admit it happens occasionally.

Yep, that's why I like how repr() does it. Guido solved this nicely a long time ago :)

Re: Black: An uncompromising Python code formatter

#187
post #106

In case of credit where credit’s due, is gofmt where the concept of auto-formatting syntax became mainstream? At first I hated it because I thought I had a style, but later on I enjoyed the consistency far more than I enjoyed my signature approach. A programming language has an opinion on how you build software with it, so it’s appreciated that it also has an opinion on how you should write it so that it remains cons…

Go is probably where it went mainstream in the current generation, yeah, but the idea has definitely been around for a while. The earliest implementation I know of was COMAL, a very clean and tidy version of BASIC, I think dating from around 1980. A lot of 80s micro BASICs did some level of auto-formatting purely as a side-effect of the source code being stored in tokenized form to save memory.

A friend had COMAL on his C-64. It was very impressive.

Microware Systems Corporation's BASIC09 from about the same time took the code you entered and converted it into "I-code". It's VM code, Jim, but not quite as we know it. The basic09 program didn't do the things we expect from IDEs now, but it did let you modify code etc., so its internal form reflected the BASIC09 statements and control structures rather than having lower-level branch and conditional branch instructions. That let it prettyprint your code with a consistent format when you listed it. (It also let it avoid the insane interpretation and symbol table lookup overhead of Microsoft BASICs of the era, inherited from the days when Altair BASIC had to run on a system with 4K of RAM.)

Re: Black: An uncompromising Python code formatter

#188

This is great except for the enforcement of double-quotes around all strings and spaces around slice operators. These two choices contradict the standard Python documentation, most of the standard library, and the behaviour of the interpreter itself. When the language itself has an established convention, Black should follow that convention, not fight it. These two weird choices just generate needless churn, which is…

Colons in slices are implemented to the letter of PEP 8. Your disagreement here probably stems from pycodestyle mistakenly enforcing a different rule (no spaces before colons on if-statements, defs, and so on) in the slice context. The language itself doesn't have an established standard in terms of string quote usage. If it did, Black would follow it. What repr() does is a weak indicator and how the documentation is…

I thought of another way to express this that might resonate better.

What I like about the Black philosophy is that it wants to make code style _uninteresting_. People should think about other things, not formatting. That's a great goal. So it seems to me that the best style choice is the most _boring_ choice. The least creative, least novel way. It should try to avoid inventing new formatting algorithms.

What's the most boring way to format a string literal?

The way the language already does it. The way every Python programmer has already seen string literals formatted from the very first day they started typing things into a Python interpreter.

Even if half of us liked single-quotes and half of us liked double-quotes, you can guarantee that every Python programmer on the planet has seen and lived with strings that are formatted the repr() way, including the double-quote fans. You can't guarantee the opposite.

No one could fault you for doing it the repr() way. Blame Guido :) he made that choice decades ago, and everyone has already had to make their peace with it. It's a solved problem. For anyone writing a program that emits Python code, it's the default way to format a string. It's the least assailable option, and that's a good thing.

How does that sit with you?

Re: Black: An uncompromising Python code formatter

#189
post #119

Earlier quoted context omitted.

Hmm. My reading of PEP 8 on slices is that the spaces surrounding : in slices are optional, and used to implement the later rule "If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator." This leads to th…

Black does not take existing formatting into account. Doing so would cause non-deterministic formatting (Black would sometimes change its mind about its own formatting and a second pass would cause a different formatting than the first). With this in mind, it has to enforce a rule around operators. Since any operand might be complex, it's more robust to default to spaces around operands always. Otherwise we would ine…

> Black would sometimes change its mind about its own formatting and a second pass would cause a different formatting than the first

Why not? I mean, I never built a formatter so idk about the complexity involved, but to me it seems that if Black had a rule like "if you see `a+b` (no spaces), just leave it alone", applying the rule twice shouldn't change anything.

(though I imagine that the interactions of such rules could become hard to understand...)

Re: Black: An uncompromising Python code formatter

#190
post #189

Earlier quoted context omitted.

Black does not take existing formatting into account. Doing so would cause non-deterministic formatting (Black would sometimes change its mind about its own formatting and a second pass would cause a different formatting than the first). With this in mind, it has to enforce a rule around operators. Since any operand might be complex, it's more robust to default to spaces around operands always. Otherwise we would ine…

> Black would sometimes change its mind about its own formatting and a second pass would cause a different formatting than the first Why not? I mean, I never built a formatter so idk about the complexity involved, but to me it seems that if Black had a rule like "if you see `a+b` (no spaces), just leave it alone", applying the rule twice shouldn't change anything. (though I imagine that the interactions of such rules…

The whole idea is to _prevent_ people from thinking about formatting, by actually making it impossible to make any formatting decisions. There's exactly one way to format the program and that's it. It's draconian, but that's what's great about it.
Post reply on HN