Skip to content

Warn about if x is None == y is None #6559

Closed
@fischbacher

Description

@fischbacher

Current problem

We sometimes see code like this:

def foo(*, left=None, right=None):
  """ ... """
  if (left is None) != (right is None):
    raise ValueError('Either both left= and right= need to be provided or none should.')

It is very easy to make the mistake of writing the check as:

def foo(*, left=None, right=None):
  """ ... """
  if left is None != right is None:
    raise ValueError('Either both left= and right= need to be provided or none should.')

This actually is a chained comparison: (left is None != right is None) is equivalent to:

(left is None) and (None != right) and (right is None)

...which is unsatisfiable, since right is None implies not(None != right).

Desired solution

According to the comparison rule in the Python grammar (https://docs.python.org/3/reference/grammar.html),
these comparison operators have the same precedence, and would lead to chained comparisons:

in, not in, is, is not, <, <=, >, >=, !=, ==

There are three groups: {'in', 'not in'}, {'is', 'is not'}, {'<', '<=', '>', '>=', '!=', '=='}.

If the linter warned about chained comparisons where one expression is part of two comparisons that belong to different groups, this would flag up checks such as "left is None != right is None".

The price to pay is that this would also trigger on code such as...:

if None is not f(x) > 0:
  ...

...but overall, it might be justified in those rare cases where a conditional just like that is appropriate to expect the author to silence the linter on that line.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Good first issueFriendly and approachable by new contributorsHacktoberfestHelp wanted 🙏Outside help would be appreciated, good for new contributorsNeeds PRThis issue is accepted, sufficiently specified and now needs an implementationOptional CheckersRelated to a checked, disabled by default

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions