[Zope-dev] urg

Michel Pelletier michel@digicool.com
Tue, 07 Mar 2000 03:51:03 -0800


Tom Deprez wrote:

> "Quote Martijn"
> im_func is a part of Python introspection. It is the pure function
> definition of a class, not bound to that class, so I can pass in an
> alternate self.

Aiee!  Split personality objects!
 
> I am trying to call a superclass method here, and normally
> CatalogAware.index_object() would suffice. But because of Extension Classes,
> Python gets confused as to what is a class method, and what is a regular
> function. It will accuse me of calling an unbound method, which of course I
> am not. I circumvent this by calling the unbound function, and passing in
> self explicitly.

Then this sounds like a bug in ExtensionClass, shouldn't it be able to
grock that CatalogAware.method(instance) is a class method bound to
instance?

Dammit I've seen this somewhere before... ah, this might be it, quothe
the ExtensionClass documetation:

  Overriding methods inherited from Python base classes

    A problem occurs when trying to overide methods inherited from
    Python base classes.  Consider the following example::

      from ExtensionClass import Base

      class Spam:

        def __init__(self, name):
	  self.name=name

      class ECSpam(Base, Spam):

        def __init__(self, name, favorite_color):
	  Spam.__init__(self,name)
	  self.favorite_color=favorite_color

    This implementation will fail when an 'ECSpam' object is
    instantiated.  The problem is that 'ECSpam.__init__' calls
    'Spam.__init__', and 'Spam.__init__' can only be called with a
    Python instance (an object of type '"instance"') as the first
    argument.  The first argument passed to 'Spam.__init__' will be an
    'ECSpam' instance (an object of type 'ECSPam').

MP> ^^^^^^^^ This sounds like your problem right here ^^^^^^^^

    To overcome this problem, extension classes provide a class method
    'inheritedAttribute' that can be used to obtain an inherited
    attribute that is suitable for calling with an extension class
    instance.  Using the 'inheritedAttribute' method, the above
    example can be rewritten as::

      from ExtensionClass import Base

      class Spam:

        def __init__(self, name):
	  self.name=name

      class ECSpam(Base, Spam):

        def __init__(self, name, favorite_color):
	  ECSpam.inheritedAttribute('__init__')(self,name)
	  self.favorite_color=favorite_color

    This isn't as pretty but does provide the desired result.


I don't think, however, that this can be used called from an external
method.  There is no access to whatever class your method is a shared
attribute of ('self' in an external method could be bound to all sorts
of class instances depending on how it is called).  I could be
completely wrong.

-Michel