What does the following evaluate to, and why?

>>> None is None is None
# A. True
# B. False
# C. None

>>> None is None == None
# A. True
# B. False
# C. None

>>> None is None == True
# A. True
# B. False
# C. None

Answers below the break.


Let’s find out!

$ python3
Python 3.7.4 (default, Jul 16 2019, 07:12:58)
[GCC 9.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> None is None is None
True
>>> None is None == None
True
>>> None is None == True
False

It turns out that while you may think these expressions parse like so:

(None is None) is None
None is (None is None)
(None is None) == True

They are actually chained comparisons:

(None is None) and (None is None)
(None is None) and (None == None)
(None is None) and (None == True)

You’re more likely to use them with comparisons:

3 < x < 5

In my opinion, chained comparions make more sense for comparison operators, not equality operators, but hey, there’s something to be said for consistency.