subclassing extension type and assignment to __class__

Lenard Lindstrom len-1 at telus.net
Sat Nov 27 15:22:35 EST 2004


gregory lielens <gregory.lielens at fft.be> writes:

> Hello,
> 
> I am currently writing python bindings to an existing C++ library, and
> I just encountered a problem that I hope has been solved by more
> experienced python programmers:
> 
> A C++ class (let's call it CClass) is binded using classical Python
> extension API to _PClass, which is accesible through python without
> any problem. The problem is that I want this class to be
> extended/extensible in python, and expose the python-extended version
> (PClass) to library users (_PClass should never be used directly nor
> be retruned by any function).
> The aim is to leave only performance critical methods in C++ so that
> the binding work is minimal, and develop the other methods in python
> so that they are easier to maintain/extend.
> 
> We thus have something like this
> 
> class PClass(_PClass):
>    def overide_method(self,...):
>      ...
>    def new_method(self,...):
>      ...
> 
> and I can define
> a=PClass()
> and use my new or overiden method
> a.overide_method() a.new_method() as intended...
> 
> So far, so good, trouble begin when I have a method from another class
> PClass2 derived from _PClass2 which bind the C++ class CClass2, that
> should return objects of type PClass:
> 
> Let call this method troublesome_method:
> 
> b=_PClass2()
> c=b.troublesome_method()
> type(c) gives _PClass.
> 
> now I want to define a python class PClass2 for extending methods of
> _PClass2 like I have done for _PClass, in particular I want that
> PClass2 troublesome_method return objects of type PClass instead of
> _PClass...
> 
> To this end I try something like this
> 
> class PClass2(_PClass2):
>      ...
>      def troubelsome_method(self):
>         base=_PClass2.troublesome_method(self)
>         base.__class__=PClass
> 
> and I have python complaining about TypeError: __class__ assignment:
> only for heap types...
> 
> It seems thus that my approach is not possible, but problem is that I
> can not see another approach that would not involve far more efforts
> that this one (I have the impression I have to forget about making my
> PClass derived from _PClass, but instead embed a _PClass instance in
> PClass, far from ideal cause I would have to reimplement all method,
> not only those that I want to change :( )
> This is particularly frustrating cause I also have the impression that
> want I want to do was at one time possible in python, let say in
> 2002-2003, when __class__ was already assignable but before assignment
> was forbidden for non-heap types
> 
> Any hint on this problem?
> 
I have just run into the same thing with the builtin list type. The trick
was not to declare my subclass directly from list, but rather a subclass
of list. So try this:

class PClassBase(_PClass):
    pass

class PClass(PClassBase):
    ...

class PClass2(PClassBase):
    ...

Why? I cannot say other than I have noted that Python new-style classes
and extension types are not quite the same thing. That is, a new-style
class is a particular kind of extension type.

Lenard Lindstrom
<len-l at telus.net>



More information about the Python-list mailing list