Dynamically Changing the Base Class

A

Adam C.

We have a situation where we want a Swig-generated Python class to
have a different base (not object). It doesn't appear that we can
coerce Swig into generating the class we want at present (but we are
still enquiring).

Is it possible to dynamically change the base class to something else?
Initial experiments appear to show it is not:
-------------------------------- snip --------------------------------
pass
pass

Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
Foozle.__bases__ = (Foo,)
TypeError: __bases__ assignment: 'Foo' deallocator differs from
'object'
-------------------------------- snip --------------------------------

Is there a solution I am missing?

Thanks in advance.
 
G

George Sakkis

We have a situation where we want a Swig-generated Python class to
have a different base (not object). It doesn't appear that we can
coerce Swig into generating the class we want at present (but we are
still enquiring).

Is it possible to dynamically change the base class to something else?
Initial experiments appear to show it is not:
-------------------------------- snip -------------------------------->>> class Foo(object):

        pass


        pass


Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    Foozle.__bases__ = (Foo,)
TypeError: __bases__ assignment: 'Foo' deallocator differs from
'object'
-------------------------------- snip --------------------------------

Is there a solution I am missing?

Thanks in advance.

Supposedly it should (usually) work, there's a 6 year old patch for
this (http://bugs.python.org/issue635933). Check if Swig can generate
old-style classes (i.e. not inheriting from object) since __bases__
assignment works for them.

HTH,
George
 
A

Adam C.

Supposedly it should (usually) work, there's a 6 year old patch for
this (http://bugs.python.org/issue635933). Check if Swig can generate
old-style classes (i.e. not inheriting from object) since __bases__
assignment works for them.

HTH,
George

Thanks. I think we would want new-style classes, and 6-year-old
patches strike me as maybe a little out of the desired path... so this
really just doesn't work in modern Python?
 
C

Carl Banks

We have a situation where we want a Swig-generated Python class to
have a different base (not object). It doesn't appear that we can
coerce Swig into generating the class we want at present (but we are
still enquiring).

Is it possible to dynamically change the base class to something else?
Initial experiments appear to show it is not:
-------------------------------- snip -------------------------------->>> class Foo(object):

pass


Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
Foozle.__bases__ = (Foo,)
TypeError: __bases__ assignment: 'Foo' deallocator differs from
'object'
-------------------------------- snip --------------------------------

Is there a solution I am missing?

Thanks in advance.

You get the same effect as subclassing by using multiple inheritance.
Suppose your SWIG class called Foo to have a base class of Base. You
could instead call the SWIG class _Foo, and define Foo as a Python
class like this:

class Foo(_Foo,Base): pass

If you do that, the resulting class will behave exactly as if _Foo
were a subclass of base (apart from some introspection methods and
edge cases). You can see that this is so if you look at the MRO:

Foo, _Foo, Base, object

Which is the same MRO that would occur if _Foo derived from Base
directly.

The drawback (which is also a drawback to the hypothetical base
reassignment) is that Foo's __init__ method won't call Base's. The
only way you can make SWIG __init__ call it's superclass's __init__ is
apparently a patch.


Carl Banks
 
M

Michele Simionato

Thanks. I think we would want new-style classes, and 6-year-old
patches strike me as maybe a little out of the desired path... so this
really just doesn't work in modern Python?

Can you use (multiple) inheritance instead of changing the bases?
Alternatively, try using an old-style class, changing the bases
and subclassing it inheriting from object too:

class NewStyle(OldStyle, object):
pass
 
A

Adam C.

You get the same effect as subclassing by using multiple inheritance.
Suppose your SWIG class called Foo to have a base class of Base.  You
could instead call the SWIG class _Foo, and define Foo as a Python
class like this:

class Foo(_Foo,Base): pass

If you do that, the resulting class will behave exactly as if _Foo
were a subclass of base (apart from some introspection methods and
edge cases).  You can see that this is so if you look at the MRO:

Foo, _Foo, Base, object

Which is the same MRO that would occur if _Foo derived from Base
directly.

The drawback (which is also a drawback to the hypothetical base
reassignment) is that Foo's __init__ method won't call Base's.  The
only way you can make SWIG __init__ call it's superclass's __init__ is
apparently a patch.

Carl Banks

Thanks. Looks like I will just write a patch step and hook it into the
makefile.
 
A

Adam C.

Can you use (multiple) inheritance instead of changing the bases?
Alternatively, try using an old-style class, changing the bases
and subclassing it inheriting from object too:

class NewStyle(OldStyle, object):
  pass

Definitely don't want old-style classes. We could probably use
multiple inheritance, but it feels like a horrible hack to me; I'd
just go with duck typing and alternate implementations over that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top