This is a follow up of issue https://github.com/ambv/black/issues/148 (see in particular https://github.com/ambv/black/issues/148#issuecomment-384184113 by @njsmith)
Black still adds spaces around the operator **.
It is really bad for readability of math formula and it is not consistent with PEP 8 (https://www.python.org/dev/peps/pep-0008/#other-recommendations).
This operator has a so high precedence (https://docs.python.org/3/reference/expressions.html#operator-precedence) so I think it should be allowed not to put spaces around it.
I know that we can use
# fmt: off
t = a**2 + b**3
# fmt: on
for math, but many times, the spaces around ** are the worst problems, so allowing a**2 would save us from adding too many # fmt: off ... # fmt: on.
Black does not take existing formatting into account, instead it applies uniform formatting everywhere. Hugging math operators is hard to do uniformly. See this and the next comment:
https://github.com/ambv/black/issues/148#issuecomment-383332150
I am not philosophically opposed to making Black smarter about this but I'm afraid this is less obvious if you include non-trivial operands.
Oh, and in case this is not clear: it's out of the question for Black to "preserve user's choice". The entire program is built around the tenet of consistent formatting without looking at preexisting style. The only place where we break this rule is vertical whitespace (people are really attached to their blank lines!) and this was a source of a lot of pain for awhile (still not fully solved but mostly fine).
We want to solve this but it's rather tricky: we will need to model an approach that Black can execute on its own. Currently Black decides on whitespace for all tokens just by looking at the current one and sometimes also at its immediate predecessor. We are not looking at what comes after the current token (we'd have to change the algorithm not to be simply visitor-based anymore) nor make decisions based on whether other tokens received whitespace or not (with the exception of a simple hack around type-annotated function arguments).
OK. I now understand that it is out of the question for Black to "preserve user's choice".
Then a simple solution would be to just remove white spaces around **.
I realize that it wouldn't always be consistent with PEP 8 (actually only when ** is the only operator in the expression) but most of the time it would give a nicer result than with spaces around **.
Thinking about it some more (actually, a lot more) it seems to me like the easiest improvement here is to do what @paugier was suggesting all along, especially clearly in his latest comment, with the following additional twist: if ** is the only operator in the expression, then don't hug.
@ambv, that's a solution many could probably live with! 馃憤
@grothesque, you might find this one interesting.
@basnijholt @ambv Can I try to take on this issue?
Of course you can, I don鈥檛 think anybody else is working on it 馃コ
Most helpful comment
Thinking about it some more (actually, a lot more) it seems to me like the easiest improvement here is to do what @paugier was suggesting all along, especially clearly in his latest comment, with the following additional twist: if
**is the only operator in the expression, then don't hug.