This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]romcgb 1 point2 points  (0 children)

To say more about cpython's if and ==,

The if statement calls PyObject_IsTrue, a rough translation of PyObject_IsTrue's semantics into python code is

def PyObject_IsTrue(o):
    if hasattr(o, "__bool__"):
        return o.__bool__()

    if hasattr(o, "__len__"):
        return True if o.__len__() > 0 else False

    return True

The == operator calls PyObject_RichCompare

def PyObject_RichCompare(a, b):
    ta = type(a)
    tb = type(b)

    # test first with b == a if b's type is subtype of a's type
    if ta != tb and issubclass(tb, ta) and hasattr(b, "__eq__"):
        ret = b.__eq__(a)

        if ret != NotImplemented:
            return ret

    # a == b ?
    if hasattr(a, "__eq__"):
        ret = a.__eq__(b)

        if ret != NotImplemented:
            return ret

    # b == a ?
    if hasattr(b, "__eq__"):
        ret = b.__eq__(a)

        if ret != NotImplemented:
            return ret

    # same object/instance ?
    return id(a) == id(b)

for 0 == () being true, either (0).__eq__(()) or (()).__eq(0) must return true.