<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi,<div class=""><br class=""></div><div class="">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…</div><div class=""><br class=""></div><div class="">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 <<a href="https://mail.python.org/pipermail/python-dev/2015-July/140938.html" class="">https://mail.python.org/pipermail/python-dev/2015-July/140938.html</a>> (follow the link for more context):</div><div class=""> </div><div class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">> "__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.)</pre><div class="">My reaction that year is in <<a href="https://mail.python.org/pipermail/python-dev/2015-August/141114.html" class="">https://mail.python.org/pipermail/python-dev/2015-August/141114.html</a>>. 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.</div></div><div class=""><br class=""></div><div class="">The implementation of the PEP in issue 18181 <<a href="http://bugs.python.org/issue18181" class="">http://bugs.python.org/issue18181</a>> 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__, …).</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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).</div><div class=""><br class=""></div><div class="">Ronald</div><div class=""><br class=""></div><div class="">P.S. The PEP itself: <<a href="https://www.python.org/dev/peps/pep-0447" class="">https://www.python.org/dev/peps/pep-0447</a>></div></body></html>