Normally special methods use slots of the PyTypeObject struct.
typeobject.c looks up all those methods on Python classes correctly.
In the case of __enter__ and __exit__, the compiler generates bytecode
to look them up, and that bytecode use PyObject_Getattr.
--
Daniel Stutzbach, Ph.D.
President, Stutzbach Enterprises, LLC