Why does ... == True return False in Python 3?

if-statement, python, python-3.x, truthiness

Solution

You're mixing two concepts: equality testing and truth-value testing. They are not the same in Python.

I think what triggered the question is that Python does an implicit casting when you do `if something` (it casts the something to `bool`) but it does not do implicit casting when you do `something1 == something2`.

Pythons data model actually explains how these operations are done:

Truth-value testing

- It starts by checking if the object implements the `__bool__` method and if it does it uses the returned boolean.

- If it doesn't define a `__bool__` method it looks at the `__len__` method. If it's implemented it will use the result of `len(obj) != 0`.

- If it doesn't have either the object is considered `True`.

For integers the `__bool__` method returns `True` except when the integer value is `0` (then it's `False`).

The Ellipsis object (`...` is the Ellipsis object) on the other hand doesn't implement `__bool__` or `__len__` so it's always `True`.

Equality testing

Equality testing relies on the `__eq__` method of both arguments. It's more a chain of operations:

- It checks if the first operand implements `__eq__` when the second operand is passed as argument.

- If it doesn't then it checks if the second operand implements `__eq__` when the first operand is passed as argument.

- If it doesn't then Python checks for object identity (if they are the same object - similar to pointer comparisons in C-like languages)

The order of these operations may vary.1

For built-in Python types these operations are explicitly implemented. For example `int`egers implement `__eq__` but the `CHECK_BINOP` makes sure that it returns `NotImplemented` if the other one isn't an `int`eger.

The `Ellipsis` object doesn't implement `__eq__` at all.

So when you compare integers and Ellipsis Python will always fallback to object identity and so it will always return `False`.

On the other hand `bool`eans are a subclass of `int`egers so they actually compare with `int` (they are another `int` after all). The booleans are implemented as `1` (`True`) and `0` (`False`). So they compare equal:

>>> 1 == True
True
>>> 0 == False
True

>>> 1 == False
False
>>> 0 == True
False

Even though the source code is probably hard to understand I hope I explained the concepts well enough (the source code is for the CPython implementation, the implementation in other Python implementations like PyPy, IronPython may differ!). The important take-away message should be that Python doesn't do implicit conversions in equality checks and equality testing is not related to truth value testing at all. The built-in types are implemented that they almost always give senseable results:

- all number-types implement equality in some way (floats compare to integers, complex compare to integers and floats)

- and everything not-zero and not-empty is `truthy`.

However if you create your own classes you can override equality and truth value testing as you like (and then you can spread a lot of confusion)!

1 In some cases the order is changed:

- If the second operand is a subclass of the first operand the first two steps are reversed.

- For some implicit equality checks the object identity is checked before any `__eq__` methods are called. For example when checking if some item is in a list, i.e. `1 in [1,2,3]`.

Problem

I am learning python, but I'm a bit confused by the following result. ``` In [41]: 1 == True Out[41]: True In [42]: if(1): ...: print('111') ...: 111 In [43]: ... == True Out[43]: False <===== why this is False while '1 == True' is True in previous sample In [44]: if (...): <==== here ... just behaves like True ...: print('...') ...: ... ``` According to the documentation, `...` has a truth value of True. But I still feel the above code a bit inconsistent. ...And something more interesting: ``` In [48]: 2==True Out[48]: False <===== why 1==True returns True while 2==True returns False? In [49]: if(2): ...: print('222') ...: 222 ```

Original source