Thank you for your response Eryk. I did try using gdb in my original post, but using breakpoint() left me in the python layer (pdb), not the cpython layer (gdb) and I couldn't figure out how to drop down.
I see you're using the kernel32 library, so I assume you're on windows. I only have a mac and getting gdb functional on a mac seems to be onerous ( https://gist.github.com/mike-myers-tob/9a6013124bad7ff074d3297db2c98247), so I'm performing my testing on a linux container running ubuntu. The closest equivalent to putting kernel32.DebugBreak() in front of the x == y line in my test script is os.kill(os.getpid(), signal.SIGTRAP). Though, this drops me into the signal handling code in the cpython layer, and after several dozen steps I did not reach the richcompare-related functions. I'll make another attempt later today. Thanks to everyone's responses, I have a great idea of what's going on, now. I appreciate you all. My goal now is to be able to work with the debugger, like Erik is, so that next time I am able to perform this investigation in-full. Should I create a new thread for this question? Thank you, Jonathan On Sat, May 14, 2022 at 1:51 PM Eryk Sun <eryk...@gmail.com> wrote: > On 5/14/22, Jonathan Kaczynski <jonathan.kaczyn...@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 > -- https://mail.python.org/mailman/listinfo/python-list