PyCQA / pycodestyle

Simple Python style checker in one Python file

Home Page:https://pycodestyle.pycqa.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

E251: keyword `=` vs. expressions with spaces

adamsol opened this issue · comments

Sometimes I see a code like this:

f(x=a * b)

Or a more real-life example with Django:

Order.objects.filter(timestamp__gt=timezone.now() - timedelta(minutes=30))

Though this formatting seems to be in accordance with PEP8, it always strikes me as illogical and hard to read, as the spacing contradicts the operator precedence, with the LHS being glued to the parameter name.

In cases like this, I tend to introduce an additional variable or at least add parentheses around the expression. However, it's difficult to ensure this approach within a team without linter's help.

To further analyse the situation:

  • In https://peps.python.org/pep-0008/#other-recommendations, PEP8 recommends using spaces around operators according to their precedence, which is the opposite of what happens in the examples above (if we consider = to be an operator).

    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: [...]

  • Also in https://peps.python.org/pep-0008/#other-recommendations, PEP8 recommends adding spaces around = for type-annotated default values, in contrary to standard default values (as the value would be glued to the type otherwise), therefore creating somewhat clashing rules.

    Don’t use spaces around the = sign when used to indicate a keyword argument, or when used to indicate a default value for an unannotated function parameter:
    [...]
    When combining an argument annotation with a default value, however, do use spaces around the = sign: [...]

  • In this SO thread, the poor readability of long keyword arguments is discussed, with some views that putting spaces around the equals sign in every case would be more beneficial.


What is pycodestyle's recommendation on this subject?

Would it be feasible to implement one of the following solutions?

A. Introduce a rule to detect and report whitespace usage that contradicts operator precedence. User could then manually assign the expression to a variable: x = a * b; f(x=x), add parentheses around it: f(x=(a * b)), or just remove spaces around the operator: f(x=a*b). The rule could also detect poor formatting in other contexts, like x+a * b.

B. Introduce a rule to always require spaces around the equals sign: f(x = a * b), which would violate PEP8, but allow for a more consistent (and arguably more readable) code style. It's worth noting that spaces around = for default arguments is the standard convention in other popular programming languages, like JavaScript, C++, C#.

this isn't changing, this would break too many things plus I don't agree with you that whitespace should follow operator precedence