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 ```