[Python-3000] Fixing super anyone?

Steven Bethard steven.bethard at gmail.com
Tue Apr 24 19:35:51 CEST 2007


On 4/24/07, Calvin Spealman <ironfroggy at gmail.com> wrote:
> I must have miscopied then because it worked perfectly here. Yes, I
> meant to have the _superdesc defined inside the metaclass __init__,
> but thought I could pull it out to make it cleaner. I forgot it
> actually had to be there! Here is the metaclass that works.
>
> class autosuper(type):
>         def __init__(cls, name, bases, clsdict):
>                 class _superdesc(object):
>                         def __get__(self, obj, objcls):
>                                 return super(cls, obj)
>                 cls.__super__ = _superdesc()

I still get the same error. Take a look at what the 'self' and
'__super__' objects are at each level::

>>> class A:
...     __metaclass__ = autosuper
...     def f(self):
...         print 'A', self
...
>>> class B(A):
...     def f(self):
...         print 'B', self, self.__super__
...         self.__super__.f()
...
>>> class C(A):
...     def f(self):
...         print 'C', self, self.__super__
...         self.__super__.f()
...
>>> class D(B, C):
...     def f(self):
...         print 'D', self, self.__super__
...         self.__super__.f()
...
>>> D().f()
D <__main__.D object at 0x00E88530> <super: <class 'D'>, <D object>>
B <__main__.D object at 0x00E88530> <super: <class 'D'>, <D object>>
B <__main__.D object at 0x00E88530> <super: <class 'D'>, <D object>>
...
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<interactive input>", line 4, in f
  File "<interactive input>", line 4, in f
  ...
RuntimeError: maximum recursion depth exceeded
>>>

Notice that the 'self' object is always the 'D()' object, and
therefore the '__super__' object is always the 'B' wrapper.  If the
'self' object were first 'D()', then 'D().__super__', then
'D().__super__.__super__', etc. your code might work::

>>> D().__super__
<super: <class 'D'>, <D object>>
>>> D().__super__.__super__
<super: <class 'B'>, <D object>>
>>> D().__super__.__super__.__super__
<super: <class 'C'>, <D object>>
>>> D().__super__.__super__.__super__.__super__
<super: <class 'A'>, <D object>>


STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


More information about the Python-3000 mailing list