Eryk Sun added the comment:
> assignment of "__lt__" change the value of the tp_richcompare slot?
Yes. CPython doesn't implement individual dispatching of the rich-comparison
functions. There's a single tp_richcompare slot, so overriding one rich
comparison forces the use of slot_tp_richcompare. For built-in types this
incurs the performance penalty of using a wrapper_descriptor for the other rich
comparisons. For example, overriding F.__lt__ forces calling float.__gt__ for
the greater-than comparison.
Before:
>>> F() > 1
Breakpoint 0 hit
python37_d!float_richcompare:
00000000`6099d930 4489442418 mov dword ptr [rsp+18h],r8d
ss:00000056`cefef280=a1670058
0:000> kc 3
Call Site
python37_d!float_richcompare
python37_d!do_richcompare
python37_d!PyObject_RichCompare
0:000> g
False
After:
>>> F.__lt__ = lambda a, b: 0
>>> F() > 1
Breakpoint 0 hit
python37_d!float_richcompare:
00000000`6099d930 4489442418 mov dword ptr [rsp+18h],r8d
ss:00000056`cefef0a0=a39d7c70
0:000> kc 9
Call Site
python37_d!float_richcompare
python37_d!wrap_richcmpfunc
python37_d!richcmp_gt
python37_d!wrapper_call
python37_d!_PyObject_FastCallDict
python37_d!call_unbound
python37_d!slot_tp_richcompare
python37_d!do_richcompare
python37_d!PyObject_RichCompare
The __gt__ wrapper_descriptor gets bound as a method-wrapper, and the
method-wrapper tp_call is wrapper_call, which calls the wrapper function (e.g.
richcmp_gt) with the wrapped function (e.g. float_richcompare). The object ID
in CPython is the object address, so we can easily get the address of the
__gt__ wrapper_descriptor to confirm how these C function pointers are stored
in it:
>>> id(vars(float)['__gt__'])
2154486684248
0:001> ln @@(((PyWrapperDescrObject *)2154486684248)->d_base->wrapper)
(00000000`60a20580) python37_d!richcmp_gt |
(00000000`60a205c0) python37_d!slot_tp_finalize
Exact matches:
python37_d!richcmp_gt (struct _object *, struct _object *, void *)
0:001> ln @@(((PyWrapperDescrObject *)2154486684248)->d_wrapped)
(00000000`6099d930) python37_d!float_richcompare |
(00000000`6099e6f0) python37_d!float_getzero
Exact matches:
python37_d!float_richcompare (struct _object *, struct _object *, int)
----------
nosy: +eryksun
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue28685>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com