[Python-Dev] PEP 447: Add __getdescriptor__ to metaclasses

Ronald Oussoren ronaldoussoren at mac.com
Sun Jul 24 07:06:45 EDT 2016


> On 24 Jul 2016, at 12:37, Nick Coghlan <ncoghlan at gmail.com> wrote:
> 
> On 23 July 2016 at 22:26, Ronald Oussoren <ronaldoussoren at mac.com> wrote:
>> 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.
> 
> You may also want to check compatibility with Martin's patch for PEP
> 487 (__init_subclass__ and __set_name__) at
> http://bugs.python.org/issue27366
> 
> I don't *think* it will conflict, but "try it and see what happens" is
> generally a better idea for the descriptor machinery than assuming
> changes are going to be non-conflicting :)

I also don’t think the two will conflict, but that’s based on a superficial read 
of that PEP the last time it was posted on python-dev. PEP 487 and 447 affect
different parts of the object model, in particular PEP 487 doesn’t affect 
attribute lookup.

> 
>> 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.
> 
> You may want to explicitly ping the
> https://github.com/ipython/traitlets developers to see if this change
> would let them do anything they currently find impractical or
> impossible.

I’ll ask them.

> 
> As far as Mark's concern about a non-terminating method definition
> goes, I do think you need to double check how the semantics of
> object.__getattribute__ are formally defined.
> 
>>>> class Meta(type):
>    ...     def __getattribute__(self, attr):
>    ...         print("Via metaclass!")
>    ...         return super().__getattribute__(attr)
>    ...
>>>> class Example(metaclass=Meta): pass
>    ...
>>>> Example.mro()
>    Via metaclass!
>    [<class '__main__.Example'>, <class 'object'>]
> 
> Where the current PEP risks falling into unbounded recursion is that
> it appears to propose that the default type.__getdescriptor__
> implementation be defined in terms of accessing cls.__dict__, but a
> normal Python level access to "cls.__dict__" would go through the
> descriptor machinery, triggering an infinite regress.
> 
> The PEP needs to be explicit that where "cls.__dict__" is written in
> the definitions of both the old and new lookup semantics, it is *not*
> referring to a normal class attribute lookup, but rather to the
> interpreter's privileged access to the class namespace (e.g. direct
> 'tp_dict' access in CPython).

On first glance the same is true for all access to dunder attributes in sample
code for the PEP, a similar example could be written for __get__ or __set__. 
I have to think a bit more about how to clearly describe this.

I’m currently coaxing PyObjC into using PEP 447 when that’s available
and that involves several layers of metaclasses in C and that’s annoyingly 
hard to debug when the code doesn’t do what I want like it does now.

But on the other hand, that’s why wanted to use PyObjC to validate
the PEP in the first place.

Back to wrangling C code,

   Ronald


> 
> Cheers,
> Nick.
> 
> -- 
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-Dev mailing list