I got curious about what 'slot wrapper' objects are after I encountered them in FindingMethodProviderII , so I went digging in the CPython source. It turns out that the answer requires understanding the internal structure of CPython.
Python types written in C start with a big structure that defines various details about them, including a large number of pointers to functions that implement various basic operations such as deallocating objects of this type, getting and setting attributes, comparison, and so on. Many but not all of these correspond to Python level canonical methods like
__repr__
; however, when CPython actually calls these core functions it doesn't go through a Python-level method lookup and instead makes a direct call to the C function pointed to by, eg,
type->tp_repr
.
As a service, the CPython core that registers a new type automatically creates a
__dict__
object and populates it with names for all of the function slot pointers that correspond to the canonical methods, so that you can actually do things like get and invoke the
__init__
function of a built in type. These names can't point directly to the C functions; instead they point to (you guessed it) special 'slot wrapper' objects, which encapsulate all the information necessary to actually call the C functions from Python.
The one exception to this is
__new__
, which is done differently for reasons that I'll cover in a future entry.