There are so many variations on this theme that we would be silly to insist on One True Way of writing it. For example, in my own code, the most common variation is
if item is None:
item = default()
While there are many good ways to handle this, writing a double negative:
if not (item is not None):
is never one of them. That would be unspeakable. There’s no conundrum here, it’s a paddlin’.
Coming back to your suggestion, I am afraid that you seem to be working under a misapprehension about None. While it is true that None is now a keyword, it is also an object, like every other value in Python.
is None and
is not None are not special syntax forms, but plain old operators with an operand which happens to be the None object.
And so it would be for your proposed
is Any, which would have to check whether the expression on the left evaluates to the actual
Now, of course we could hypothetically make a special syntactic form
is Any which compiles to
is not None, but that sort of special case in the language is even more unspeakable than double negatives.
There is no “might introduce cognitive load” here. It would definitely introduce cognitive load.
It would complicate Python’s execution model. Instead of
is being a simple operator with which always checks whether the two operands are the same object, it would sometimes stand for the reverse test (“are they not the same object?”) with the second operand being unstated.
Worse, it would break backwards compatibility. “Any” is currently an ordinary name free for people to use. There’s a very important object in the stdlib by that name:
from typing import Any
With this proposal, you would make it impossible to test whether an object is the Any object using
is Any would have the special magical meaning.
Okay, perhaps not impossible. Maybe you could write:
Any is myobject
instead, but that leads to the worse result that now
is is no longer symmetric:
a is b
b is a
would no longer have the same meanings. (There are many non-symmetric operations in Python, and maths, such as subtraction, division, but for
is to be non-symmetric would be just weird.)
Fundamentally, this would be a confusing and strange “Wot?” operation that messes up the relatively clean Python execution model, for the sake of … what? Saving a few characters typing?
item is not None
item is Any
# doesn't actually test whether item is Any, but tests whether item is not None
One last thing…
is not None should not be read as involving
not None. The operator is
is not, and the operand is still None.
not None would result in True.