[Python-Dev] Hooking into super() attribute resolution (original) (raw)
Ronald Oussoren ronaldoussoren at mac.com
Sat Jul 6 09:45:53 CEST 2013
- Previous message: [Python-Dev] Hooking into super() attribute resolution
- Next message: [Python-Dev] Hooking into super() attribute resolution
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I've updated the implementation in issue 18181 <http://bugs.python.org/issue18181> while adding some tests, and have updated the proposal as well.
The proposal has some open issues at the moment, most important of which is the actual signature for the new special method; in particular I haven't been able to decide if this should be an instance-, class- or static method. It is a static method in the proposal and prototype, but I'm not convinced that that is the right solution.
Ronald
PEP: TODO Title: Hooking into super attribute resolution Version: RevisionRevisionRevision Last-Modified: DateDateDate Author: Ronald Oussoren <ronaldoussoren at mac.com> Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 12-Jun-2013 Post-History: 2-Jul-2013, ?
Abstract
In current python releases the attribute resolution of the super class
_
peeks in the __dict__
attribute of classes on the MRO to look
for attributes. This PEP introduces a hook that classes can use
to override that behavior for specific classes.
Rationale
Peeking in the class __dict__
works for regular classes, but can
cause problems when a class dynamicly looks up attributes in a
__getattribute__
method.
The new hook makes it possible to introduce the same customization for
attribute lookup through the super class
_.
The superclass attribute lookup hook
In C code
A new slot tp_getattro_super
is added to the PyTypeObject
struct. The
tp_getattro
slot for super will call this slot when it is not NULL
,
and will raise an exception when it is not set (which shouldn't happen because
the method is implemented for :class:object
).
The slot has the following prototype::
PyObject* (*getattrosuperfunc)(PyTypeObject* cls, PyObject* name,
PyObject* object, PyObject* owner);
The function should perform attribute lookup on object for name, but only looking in type tp (which will be one of the types on the MRO for self) and without looking in the instance dict.
The function returns NULL
when the attribute cannot be found, and raises and
exception. Exception other than AttributeError
will cause failure of super's
attribute resolution.
The implementation of the slot for the :class:object
type is
PyObject_GenericGetAttrSuper
, which peeks in the tp_dict
for cls.
Note that owner and object will be the same object when using a class-mode super.
In Python code
A Python class can contain a definition for a static method
__getattribute_super__
with the following prototype::
def getattribute_super(cls, name, object, owner): pass
The method should perform attribute lookup for name on instance self while only looking at cls (it should not look in super classes or the instance dict
XXX: I haven't got a clue at the moment if the method should be an instance-, class- or staticmethod. The prototype uses a staticmethod.
XXX: My prototype automagicly makes this a static method, just like new is made into a static method. That's more convenient, but also (too?) magical.
XXX: Should this raise AttributeError or return a magic value to signal that an attribute cannot be found (such as NotImplemented, used in the comparison operators)? I'm currently using an exception, a magical return value would be slightly more efficient because the exception machinery is not invoked.
Alternative proposals
Reuse tp_getattro
.....................
It would be nice to avoid adding a new slot, thus keeping the API simpler and
easier to understand. A comment on Issue 18181
_ asked about reusing the
tp_getattro
slot, that is super could call the tp_getattro
slot of all
methods along the MRO.
AFAIK that won't work because tp_getattro
will look in the instance
__dict__
before it tries to resolve attributes using classes in the MRO.
This would mean that using tp_getattro
instead of peeking the class
dictionaries changes the semantics of the super class
_.
Open Issues
The names of the new slot and magic method are far from settled.
I'm not too happy with the prototype for the new hook.
Should
__getattribute_super__
be a class method instead?-> Yes? The method looks up a named attribute name of an object in a specific class. Is also likely needed to deal with @classmethod and super(Class, Class)
Should
__getattribute_super__
be defined on object?-> Yes: makes it easier to delegate to the default implementation
This doesn't necessarily work for class method super class (e.g. super(object, object))...
References
Issue 18181
_ contains a prototype implementation
Copyright
This document has been placed in the public domain.
.. _Issue 18181
: http://bugs.python.org/issue18181
.. _super class
: http://docs.python.org/3/library/functions.html?highlight=super#super
- Previous message: [Python-Dev] Hooking into super() attribute resolution
- Next message: [Python-Dev] Hooking into super() attribute resolution
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]