Seeking deeper understanding of python equality (==)

Eryk Sun eryksun at gmail.com
Sat May 14 13:51:51 EDT 2022


On 5/14/22, Jonathan Kaczynski <jonathan.kaczynski at guildeducation.com> wrote:
>
> So, I'm still wondering how Py_TYPE(v)->tp_richcompare resolves to __eq__
> on a user-defined class. Conversely, my understanding is, for a type
> defined in cpython, like str, there is usually an explicitly
> defined tp_richcompare function.

Sometimes it's simplest to directly examine an object using a native
debugger (e.g. gdb in Linux; cdb/windbg in Windows).

With a debugger attached to the interpreter, create two classes, one
that doesn't override __eq__() and one that does:

    >>> class C:
    ...     pass
    ...
    >>> class D:
    ...     __eq__ = lambda s, o: False
    ...

In CPython, the id() of an object is its address in memory:

    >>> hex(id(C))
    '0x2806a705790'
    >>> hex(id(D))
    '0x2806a6bbfe0'

Break into the attached debugger to examine the class objects:

    >>> kernel32.DebugBreak()

    (1968.1958): Break instruction exception - code 80000003 (first chance)
    KERNELBASE!wil::details::DebugBreak+0x2:
    00007ffd`8818fd12 cc              int     3

Class C uses the default object_richcompare():

    0:000> ?? *((python310!PyTypeObject *)0x2806a705790)->tp_richcompare
    <function> 0x00007ffd`55cac288
     _object*  python310!object_richcompare+0(
            _object*,
            _object*,
            int)

Class D uses slot_tp_richcompare():

    0:000> ?? *((python310!PyTypeObject *)0x2806a6bbfe0)->tp_richcompare
    <function> 0x00007ffd`55cdef1c
     _object*  python310!slot_tp_richcompare+0(
            _object*,
            _object*,
            int)

Source code of slot_tp_richcompare():

https://github.com/python/cpython/blob/v3.10.4/Objects/typeobject.c#L7610-L7626


More information about the Python-list mailing list