I'm looking at CPython's behavior when an addition is called. From
what I understand, binary_op1
is eventually called, and it calls either slotv or slotw, which
seems to be the binaryfunc defined as nb_add in the field
tp_as_number of respectively v / w.
I have a few questions:
1) In the default case, tp_as_number->nb_add is defined by the
stemming from the macro expansion SLOT1BINFULL
defined in typeobject.c. Both binary_op1(v, w) and slot_nb_add(v, w)
appear to perform similar checks (if their second argument is a
subtype of the first, etc), to decide if v's add or w's reverse add
must be called and in which order. I find this repetition weird, and
I guess I'm missing something... Any ideas?
2) From the SLOT1BINFULL macro, both __add__ and __radd__ are
defined by the slot_nb_add function (with some argument swapping
done by wrap_binaryfunc_l / wrap_binaryfunc_r). If I want to define
a different behavior for the reverse operator during a definition
with a PyTypeObject, I guess I should add an "__radd__" method?
3) If I create a user-defined class A, having different methods
__add__ and __radd__, these methods are added in A's dictionary.
From what I understand, the function update_one_slot
is then called to change A's tp_as_number->nb_add to point to the
methods defined by __add__ and __radd__? From the code
documentation, I think that "a wrapper for the special methods is
installed". Where exactly is this wrapper applied, and how does it
know when to dispatch to __add__ or __radd__?