Re: Pb with descriptor and super ...
On Mar 9, 11:22 am, Erwan Adam <[EMAIL PROTECTED]> wrote: [snip] > > [EMAIL PROTECTED] /home/adam/Work/Python]> python super_from_guido.py > Using built-in super > Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c> > and typ is > Using python Super > Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c> > and typ is None > Using python MySuper > Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c> > and typ is It seems to me that it is the built-in super which has the correct behaviour. When you write obj.attr, python calls attr.__get__(obj, type(obj)) and not attr.__get__(obj) which sets the second arg to None. You can check this by creating a barebone descriptor that simply prints its arguments: class D(object): def __get__(self, obj, objtype): print obj, objtype class A(object): d=D() A().d <__main__.A object at 0x133c5f0> # objtype is not None! Therefore in your case when you do super(B, b).attr then A.__dict__['attr'].__get__(b, type(b)) is called. You can try this, it should give the same output as builtin super. > the Super gives None for typ ... which is quite surprising ! > In MySuper, I just change > > x = x.__get__(self.__obj__) > > by > > x = x.__get__(self.__obj__, cls) > at the -3 :) line of the class ... and it gives the result I expected > at the beginning : obj is b and typ is A Neither of these are right I think. If my explanation above is right the correct line should be: x = x.__get__(self.__obj__, type(self.__obj__)) HTH -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: Pb with descriptor and super ...
En Fri, 09 Mar 2007 08:22:46 -0300, Erwan Adam <[EMAIL PROTECTED]> escribió: > Thanks for your answer ... I followed the link > and tried to use the "fully functional implementation of > the super() built-in class in pure Python" given > on this page and the result is quite surprising : It appears that there is some disagreement on how the super object should behave. If you want to know what it actually *does* now (not what it *should* do) you can look at typeobject.c, but it's a bit hard to read, and I don't understand it in full... Maybe looking at the test suite is easier, in test_descr.py -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
Re: Pb with descriptor and super ...
Gabriel Genellina a écrit : > En Fri, 09 Mar 2007 06:25:08 -0300, Erwan Adam <[EMAIL PROTECTED]> > escribió: > >> I have a problem with the use of descriptors >> and super. The file is : > > Descriptors for "super" behave a bit different than for classes. See > http://www.python.org/2.2/descrintro.html#cooperation > > --Gabriel Genellina > Hi Gabriel, Thanks for your answer ... I followed the link and tried to use the "fully functional implementation of the super() built-in class in pure Python" given on this page and the result is quite surprising : # - class Super(object): def __init__(self, type, obj=None): self.__type__ = type self.__obj__ = obj def __get__(self, obj, type=None): if self.__obj__ is None and obj is not None: return Super(self.__type__, obj) else: return self def __getattr__(self, attr): if isinstance(self.__obj__, self.__type__): starttype = self.__obj__.__class__ else: starttype = self.__obj__ mro = iter(starttype.__mro__) for cls in mro: if cls is self.__type__: break # Note: mro is an iterator, so the second loop # picks up where the first one left off! for cls in mro: if attr in cls.__dict__: x = cls.__dict__[attr] if hasattr(x, "__get__"): x = x.__get__(self.__obj__) return x raise AttributeError, attr class Desc(object): def __init__(self, class_name): self.class_name = class_name return def __get__(self, obj, typ=None): print "Desc.__get__ : class_name is %s, obj is %s and typ is %s"%(self.class_name, obj, typ) return pass class A(object): attr = Desc("A") pass class B(A): attr = Desc("B") pass b = B() print "Using built-in super" attr = super(B, b).attr print "Using python Super" attr = Super(B, b).attr class MySuper(object): def __init__(self, type, obj=None): self.__type__ = type self.__obj__ = obj def __get__(self, obj, type=None): if self.__obj__ is None and obj is not None: return Super(self.__type__, obj) else: return self def __getattr__(self, attr): if isinstance(self.__obj__, self.__type__): starttype = self.__obj__.__class__ else: starttype = self.__obj__ mro = iter(starttype.__mro__) for cls in mro: if cls is self.__type__: break # Note: mro is an iterator, so the second loop # picks up where the first one left off! for cls in mro: if attr in cls.__dict__: x = cls.__dict__[attr] if hasattr(x, "__get__"): x = x.__get__(self.__obj__, cls) return x raise AttributeError, attr print "Using python MySuper" attr = MySuper(B, b).attr # -- it gives : [EMAIL PROTECTED] /home/adam/Work/Python]> python super_from_guido.py Using built-in super Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c> and typ is Using python Super Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c> and typ is None Using python MySuper Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7bc302c> and typ is the Super gives None for typ ... which is quite surprising ! In MySuper, I just change x = x.__get__(self.__obj__) by x = x.__get__(self.__obj__, cls) at the -3 :) line of the class ... and it gives the result I expected at the beginning : obj is b and typ is A Best regards, E.A. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pb with descriptor and super ...
Erwan Adam a écrit : > Hi all, > > I have a problem with the use of descriptors > and super. The file is : > > # --- > > class Desc(object): > def __init__(self, class_name): > self.class_name = class_name > return > def __get__(self, obj, typ): > print "Desc.__get__ : class_name is %s, obj is %s and typ is > %s"%(self.class_name, obj, typ) > return > pass > > class A(object): > attr = Desc("A") > pass > > class B(A): > attr = Desc("B") > pass > > b = B() > > print "---" > print "Getting b.attr ..." > print "I hope that : class_name is B, obj is b and typ is B" > b.attr > print "---" > print "Getting super(B, b).attr ..." > print "I hope that : class_name is A, obj is b and typ is A but it is > not the case !" > super(B, b).attr > print "---" > > # --- > > and the result is : > > --- > Getting b.attr ... > I hope that : class_name is B, obj is b and typ is B > Desc.__get__ : class_name is B, obj is <__main__.B object at 0xb7b1f8ec> > and typ is > --- > Getting super(B, b).attr ... > I hope that : class_name is A, obj is b and typ is A but it is not the > case ! > Desc.__get__ : class_name is A, obj is <__main__.B object at 0xb7b1f8ec> > and typ is > --- > > I expected that when getting super(B, b).attr, typ is A, but it is not > the case ... Moreover, on the page : http://users.rcn.com/python/download/Descriptor.htm the author writes : "The call super(B, obj).m() searches obj.__class__.__mro__ for the base class A immediately following B and then returns A.__dict__['m'].__get__(obj, A)." which it seems not the case ... Is it a bug or a mis-understood ? Regards, E.A. > > python used : > > [EMAIL PROTECTED] /home/adam/Work/Python]> python > Python 2.4.3 (#2, Sep 18 2006, 21:07:35) > [GCC 4.1.1 20060724 (prerelease) (4.1.1-3mdk)] on linux2 > Type "help", "copyright", "credits" or "license" for more information. > >>> > > > Best regards, > > > E.A. -- http://mail.python.org/mailman/listinfo/python-list
Re: Pb with descriptor and super ...
En Fri, 09 Mar 2007 06:25:08 -0300, Erwan Adam <[EMAIL PROTECTED]> escribió: > I have a problem with the use of descriptors > and super. The file is : Descriptors for "super" behave a bit different than for classes. See http://www.python.org/2.2/descrintro.html#cooperation -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list