No time to read the PEP in detail but the motivation sound reasonable.

--Guido van Rossum (sent from Android phone)

On Jul 2, 2013 4:53 AM, "Ronald Oussoren" <ronaldoussoren@mac.com> wrote:
Hi,

Below is a very preliminary draft PEP for adding a special method that can be used to hook into the attribute resolution process of the super object.

The primary usecase for using this special method are classes that perform custom logic in their __getattribute__ method, where the default behavior of super (peekin the the class __dict__) is not appropriate.  The primary reason I wrote this proposal is PyObjC: it dynamicly looks up methods in its __getattribute__ and caches the result in the class __dict__, because of this super() will often not work correctly and therefore I'm currently shipping a custom subclass of super() that basicly contains an in-line implementation of the hook that would be used by PyObjC.

I have a partial implementation of the hook system in issue 18181  and a PyObjC patch that uses it. The implementation currently does not contain tests, and I'm sure that I'll find edge cases that I haven't thought about yet when I add tests.

Ronald




PEP: TODO
Title: Hooking into super attribute resolution
Version: $Revision$
Last-Modified: $Date$
Author: Ronald Oussoren <ronaldoussoren@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``,
otherwise it will peek in the class ``tp_dict``.

The slot has the following prototype::

    PyObject* (*getattrosuperfunc)(PyTypeObject* tp, PyObject* self, PyObject* name);

The function should perform attribute lookup 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.


In Python code
--------------

A Python class can contain a definition for a method ``__getattribute_super__`` with
the following prototype::

   def __getattribute_super__(self, cls, name): 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__*


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?


References
==========

* `Issue 18181`_ contains a prototype implementation

  The prototype uses different names than this proposal.


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
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org