About 'superobject' and descriptors
Hi, I have a question about a choice of implementation concerning 'superobject' with the descriptors. When a 'superobject' looks for a given attribute, it runs through the mro of the object. If it finds a descriptor, the 'superobject' calls the __get__ method with 'starttype = su->obj_type' as third argument (in typeobject.c: super_getattro). So, the 'type' argument of __get__ does not give more information about the 'real calling type' in this case. It seems that this is just a redundant information of inst.__class__. For example: # A.descr is a descriptor # B inherit from A # C inherit from B c = C() c.descr super(C, c).descr super(B, c).descr In these 3 cases the __get__ method is called with the same arguments that are : __get__(descr, c, C). If this behavior is really expected: Could you explain why ? because it means that I am missing something obvious. Because, at first sight, the 'type' argument seems to be the perfect place to get the type of the 'real calling class'. Thank you, -- hakril
On 24 Oct 2013 03:37, "hakril lse" <hakril@lse.epita.fr> wrote:
Hi,
I have a question about a choice of implementation concerning 'superobject' with the descriptors.
When a 'superobject' looks for a given attribute, it runs through the mro of the object. If it finds a descriptor, the 'superobject' calls the __get__ method with 'starttype = su->obj_type' as third argument (in typeobject.c: super_getattro).
So, the 'type' argument of __get__ does not give more information about the 'real calling type' in this case. It seems that this is just a redundant information of inst.__class__.
For example:
# A.descr is a descriptor # B inherit from A # C inherit from B
c = C() c.descr super(C, c).descr super(B, c).descr
In these 3 cases the __get__ method is called with the same arguments that are : __get__(descr, c, C).
If this behavior is really expected: Could you explain why ? because it means that I am missing something obvious. Because, at first sight, the 'type' argument seems to be the perfect place to get the type of the 'real calling class'.
The third argument is just there to handle the case where the instance is None (i.e. lookup directly on the class rather than an instance). Cheers, Nick.
Thank you,
-- hakril _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe:
https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com
Hi Hakril, I think this question is probably off-topic for this list. This list is for development of the Python compiler, not for development with Python, and questions like this should probably go to python-list@python.org (also mirrored as comp.lang.python if you have Usenet access). But I have a brief observation below: On Wed, Oct 23, 2013 at 07:29:03PM +0200, hakril lse wrote:
For example:
# A.descr is a descriptor # B inherit from A # C inherit from B
c = C() c.descr super(C, c).descr super(B, c).descr
In these 3 cases the __get__ method is called with the same arguments that are : __get__(descr, c, C).
If this behavior is really expected: Could you explain why ? because it means that I am missing something obvious. Because, at first sight, the 'type' argument seems to be the perfect place to get the type of the 'real calling class'.
I'm afraid I don't understand what you mean by "real calling class", if it is not the class of the instance doing the calling. I have a feeling that perhaps you think that calls to super are equivalent to "the parent of the class", and so you expect: c.desc => desc.__get__(c, C) super(C, c).desc => desc.__get__(c, B) super(B, c).desc => desc.__get__(c, A) but that would not be correct. super is equivalent to "the next class in the MRO of the instance doing the calling", and in all cases, the "real-calling instance" is c, and the "real calling class" is the class of c, namely C. Extended discussion of this should go to python-list, but I think I have the basics right. -- Steven
participants (3)
-
hakril lse -
Nick Coghlan -
Steven D'Aprano