[Python-Dev] PEP 447: Add __getdescriptor__ to metaclasses
ronaldoussoren at mac.com
Sat Jul 23 08:26:31 EDT 2016
It’s getting a tradition for me to work on PEP 447 during the EuroPython sprints and disappear afterwards. Hopefully I can manage to avoid the latter step this year…
Last year the conclusion appeared to be that this is an acceptable PEP, but Mark Shannon had a concern about a default implementation for __getdescriptor__ on type in <https://mail.python.org/pipermail/python-dev/2015-July/140938.html> (follow the link for more context):
> "__getdescriptor__" is fundamentally different from "__getattribute__" in that
> is defined in terms of itself.
> object.__getattribute__ is defined in terms of type.__getattribute__, but
> type.__getattribute__ just does
> dictionary lookups. However defining type.__getattribute__ in terms of
> __descriptor__ causes a circularity as
> __descriptor__ has to be looked up on a type.
> So, not only must the cycle be broken by special casing "type", but that
> "__getdescriptor__" can be defined
> not only by a subclass, but also a metaclass that uses "__getdescriptor__" to
> define "__getdescriptor__" on the class.
> (and so on for meta-meta classes, etc.)
My reaction that year is in <https://mail.python.org/pipermail/python-dev/2015-August/141114.html>. As I wrote there I did not fully understand the concerns Mark has, probably because I’m focussed too much on the implementation in CPython. If removing type.__getdescriptor__ and leaving this special method as an optional hook for subclasses of type fixes the conceptual concerns then that’s fine by me. I used type.__getdescriptor__ as the default implementation both because it appears to be cleaner to me and because this gives subclasses an easy way to access the default implementation.
The implementation of the PEP in issue 18181 <http://bugs.python.org/issue18181> does special-case type.__getdescriptor__ but only as an optimisation, the code would work just as well without that special casing because the normal attribute lookup machinery is not used when accessing special methods written in C. That is, the implementation of object.__getattribute__ directly accesses fields of the type struct at the C level. Some magic behavior appears to be necessary even without the addition of __getdescriptor__ (type is a subclass of itself, object.__getattribute__ has direct access to dict.__getitem__, …).
I’m currently working on getting the patch in 18181 up-to-date w.r.t. the current trunk, the patch in the issue no longer applies cleanly. After that I’ll try to think up some tests that seriously try to break the new behaviour, and I want to update a patch I have for PyObjC to make use of the new functionality to make sure that the PEP actually fixes the issues I had w.r.t. builtin.super’s behavior.
What is the best way forward after that? As before this is a change in behavior that, unsurprisingly, few core devs appear to be comfortable with evaluating, combined with new functionality that will likely see little use beyond PyObjC (although my opinions of that shouldn’t carry much weight, I thought that decorators would have limited appeal when those where introduced and couldn’t have been more wrong about that).
P.S. The PEP itself: <https://www.python.org/dev/peps/pep-0447>
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Python-Dev