44

I have this code:

some_list = range(a, b+1)

After checking my coding style with pep8 plugin for vim, I got this warning:

missing whitespace around operator

It seems that to be compliant with PEP 8 I should instead write this?

some_list = range(a, b + 1)

But I have read PEP 8 - Style Guide for Python Code several times and just can't find the rule applied to the warning above.

So I want to know: when using PEP-8 style, is whitespace needed around operators(+,-,*,/,etc) in a function's arguments?

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
wxl24life
  • 683
  • 1
  • 7
  • 13

3 Answers3

73

Your Vim plugin was wrong when you asked in 2013... but right in 2010, when it was authored. PEP 8 has changed on several occasions, and the answer to your question has changed as well.

Originally, PEP 8 contained the phrase:

Use spaces around arithmetic operators

Under that rule,

range(a, b+1)

is unambiguously wrong and should be written as

range(a, b + 1)

That is the rule that pycodestyle (the Python linter, previously known as pep8.py, that the asker's Vim plugin uses under the hood) implemented for several years.

However, this was changed in April 2012. The straightforward language that left no room for discretion was replaced with this much woollier advice:

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.

Confusingly, the examples that illustrate this rule were originally left unchanged (and hence in contradiction to the prose). This was eventually fixed, but not very well, and the examples remain confusing, seeming to imply a much stricter and less subjective rule than the prose does.

There is still a rule requiring whitespace around some particular operators:

Always surround these binary operators with a single space on either side: assignment ( = ), augmented assignment ( += , -= etc.), comparisons ( == , < , > , != , <> , <= , >= , in , not in , is , is not ), Booleans ( and , or , not ).

but note that this rule is explicit about which operators it refers to and arithmetic operators like + are not in the list.

Thus the PEP, in its current form, does not dictate whether or not you should use spaces around the + operator (or other arithmetic operators like * and / and **). You are free to "use your own judgement".

By the way, the pycodestyle linter changed its behaviour in late 2012 to reflect the change in the PEP, separating the rules about using whitespace around operators into two error codes, E225 (for failure to use whitespace around the operators that PEP 8 still requires whitespace around), which is on by default, and E226 (for failure to use whitespace around arithmetic operators), which is ignored by default. The question asker here must've been using a slightly outdated version of the linter when he asked this question in 2013, given the error that he saw.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
  • 10
    Thanks for the thorough answer. I came here considering the best way to whitespace x * y^2. I thought `x*y**2` was harder to read, and sometimes I consider `x * y ** 2` but space around `**` has always looked weird to me. I decided to go with `x * y**2` based on this answer. – Taylor D. Edmiston Feb 06 '17 at 23:17
  • but what about this case @Mark Amery ? so in [PEP8](https://www.python.org/dev/peps/pep-0008/#pet-peeves) it says that in a **slice** the **:** acts like a binary operator and should be treated as the operator with the **lowest priority**. Based on this and the space around the lowest priority operators would this be correct: `[2**2 * 4 + 2 : 2**4 * 2 + 75 : 3]` ? the `*` is lower than `**` so it has a space around and then `+` is lower than `*` so another space and `:` is the lowest therefore another.. chaining operators from most important to least adding space around the lowest each time – Marius Mucenicu Apr 18 '18 at 04:18
26

http://www.python.org/dev/peps/pep-0008/#other-recommendations

Always surround these binary operators with a single space on either side: assignment (=), augmented assignment (+=, -= etc.), comparisons (==, <, >, !=, <>, <=, >=, in, not in, is, is not), Booleans (and, or, not).

The exception to that is when = is used to set named parameters.

Edit:

I've looked through the source code of Python's standard library and found an occurrence of the scenario presented above:

http://hg.python.org/cpython/file/9ddc63c039ba/Lib/json/decoder.py#l203

            end = _w(s, end + 1).end()
mustafa.0x
  • 1,476
  • 2
  • 17
  • 30
  • 3
    Obviously, the rule you mentioned can't apply to my question, sorry – wxl24life Aug 11 '13 at 11:53
  • @wxl24life "**Always**" should do it, not sure what else you're looking for. Also, what are you apologizing for? :-) – mustafa.0x Aug 11 '13 at 12:05
  • "Always" (And also in a function's actual parameters.) ? :-) – John Faulkner Aug 11 '13 at 12:10
  • 11
    @John Faulkner `+ - * /` not in these operators. In fact, if you read the rule bellow this one, you will find code style like `a = a*b + c` is right – wxl24life Aug 11 '13 at 12:12
  • 1
    You are quite right that they don't mention + in that rule, but wrong to suggest that the rule below pertains to your question since they clearly state that this rule applies when there are clear differences in priority as in x*y + a*b. Note that x*y+a*b would be wrong and that i = i + 1 would be right. – John Faulkner Aug 11 '13 at 12:30
  • @wxl24life Make an answer based on your research, and accept it. It seems like your lint tool is broken. – Marcin Aug 11 '13 at 12:30
  • 4
    @wxl24life quite rightly, and then went on to point out that in the rule below `a = a*b + c` is right. but as I pointed out above, they are suggesting you should include white space when there is no difference in priority, and exclude it when there is such a difference in priority, by those conditions b+1 (as in your question) would be wrong, while a*b + 1 would be right. But honestly, will you be graded on this? if not use b+1 wherever you prefer :) – John Faulkner Aug 11 '13 at 12:54
  • @JohnFaulkner yeah, I got it, you are right, `a*b` should be right only when priorities being considered. Thank you very much:-) – wxl24life Aug 11 '13 at 12:56
  • my pleasure, and just to be clear, I think @mustafa.0x had the correct answer, however it requires both parts of that rule to be applied. It would always be required for the binary operators, and then usually be required for other operators (+-/*%, etc), except where excluding whitespace serves to punctuate operator priority. – John Faulkner Aug 11 '13 at 13:09
  • @wxl24life no reason to apologize. Also, I've added another reference/demonstration to my answer. – mustafa.0x Aug 11 '13 at 15:58
  • 4
    -1; the quoted passage and code simply don't support your conclusion. The passage from the PEP explicitly lists *particular operators* around which whitespace is mandatory, and that list does not include `+`. And the fact that an author *chose* to use whitespace around the `+` operator somewhere inside the Python source code by no means proves that such use of whitespace is *mandatory* under PEP 8. – Mark Amery Jun 22 '16 at 00:04
  • @MarkAmery: wxl24life brought this up and JohnFaulkner discussed it; see the comments above. – mustafa.0x Jun 22 '16 at 21:17
2

For arithmetic operators I usually put spaces around + and - but not in *, ** and /. Here's an example:

(...)
alpha__w = (wave__w - central_w_par*doppler_factor)/sig_par
e1__w = np.exp(-.5*(alpha__w**2))
Y1__w = norm*e1__w/(sig_par*(2*np.pi)**.5)
(...)