[Python-Dev] Hooking into super() attribute resolution (original) (raw)

Ronald Oussoren ronaldoussoren at mac.com
Sat Jul 6 09:45:53 CEST 2013


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

References

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



More information about the Python-Dev mailing list