> From: Ronald Oussoren [mailto:ronaldousso...@mac.com] > Sent: Monday, July 8, 2013 0858 > > On 8 Jul, 2013, at 17:19, Steve Dower <steve.do...@microsoft.com> wrote: > > > The only real advantage is a simpler signature and more easily explained > use (assuming the person you're explaining it to is familiar with metaclasses, > so most of the hard explaining has been done). > > The signature is as complex as it is to be able to call descr.__get__ with the > correct arguments. I ended up with the current signature when I added > __getattribute_super__ to object and removed the tp_dict peeking code > from super's tp_getattro. > > A way to get a simpler interface again would be a method that returns an > attribute *without* performing calls to descr.__get__. That could then be > used for both __getattribute__ and super.__getattribute__, instead of > peeking in a class' dictionary. I must admit that I haven't thought about the > ramifactions of this (both functionally and performance wise). This might > end up being easier to explain: both normal attribute resolution and super's > resolution would end up using the same mechanism, with the differences > being that super doesn't begin resolution at the start of the mro and ignores > the instance __dict__. The disadvantage is introducing a new way to affect > attribute resolution (do I use "__getattribute__" or this new method?). > > The new interface would be something like: > > @classmethod > def __getlocalname__(cls, object, name): > pass > > Or as you mentioned later as a __getlocalname__ method on the metaclass. > The "object" argument wouldn't be necessary to reproduce current > functionality, and isn't necessary for my usecase as well, but a hook for > attribute resolution on an instance that doesn't have access to that instance > feels wrong.
Except that if it's on a metaclass, the 'instance' it has access to is cls. The descriptor side of things is more interesting, but I see no reason why super can't do that itself, since it knows the actual instance to call __get__ with. (Presumably it already does this with the __dict__ lookup, since that won't call __get__ either.) Explaining the new method is easiest if the default implementation is (literally): def __getlocalname__(self, name): try: return self.__dict__[name] except KeyError: raise AttributeError(name) which does not do any descriptor resolution (and is only a small step from simply replacing __dict__ with a custom object, which is basically where we started). The only change I've really suggested is making it an instance method that can be implemented on a metaclass if you want it for class members. > > > > I'm still not sure that this isn't simply a bug in super. If the > > superclass's > metaclass provides a __getattr__ then it should probably use it and abandon > it's own MRO traversal. > > I'd have to think about this, but on first glance this would mean a change in > the semantics that a metaclass' __getattr__ currently has. Exactly. Probably not a great idea to change that. > > > > I still haven't thought the edge cases through, and it seems like there'd be > some with that change, so that's where __getattribute_super__ comes in - > super can call it without abandoning its MRO traversal. > > > > AFAICT, the difference between that and __getlocalattribute__ is that the > latter would be implemented on a metaclass while the former takes extra > parameters. I think this functionality is advanced enough that requiring a > metaclass isn't unreasonable. > > I'm not necessarily oppossed to a solution that requires using a metaclass, I > already have metaclasses with custom metaclasses in PyObjC and this > wouldn't add that much complexity to that :-) I assumed you were - when I was working on similar sort of code they made life extremely easy. > Ronald Steve _______________________________________________ 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/archive%40mail-archive.com