When using %extend to "reimplement" a virtual class method in class C, this reimplemented method is not available in subclass D of C but instead behaves as the original method.
E.g. (see attached tarball for these files)
=== classes.h ===
class C
{
public:
virtual void return_float(float &f) { f = 123; }
};
class D : public C
{
public:
virtual void return_float(float &f) { f = 456; }
};
=== test.i ===
%module(directors="1") test;
%{
#include "classes.h"
%}
%include "classes.h";
%extend C
{
// Pythonic way of returning a float
PyObject* return_float()
{
float f;
$self->return_float(f);
return Py_BuildValue("f", f);
}
};
When run through swig -c++ -python and GCC 4.1.2 the following then happens:
Python 2.5.2 (r252:60911, Oct 16 2008, 21:18:49)
[GCC 4.1.2 (Gentoo 4.1.2 p1.1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> c = test.C()
>>> c.return_float()
123.0
>>> d = test.D()
>>> d.return_float()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 82, in return_float
def return_float(*args): return _test.D_return_float(*args)
TypeError: D_return_float() takes exactly 2 arguments (1 given)
>>>
This used to work (at least in 1.3.29)...
Test case
Forgot to mention that this is with 1.3.36
Reproducible with current git master.
Arguably a better way to achieve what you want here is to apply an
OUTPUTtypemap (which also eliminates the non-pythonic wrapping):However, I don't see why your example shouldn't work (there are some limitations with
%extendand virtual methods - e.g. see https://github.com/swig/swig/issues/503#issuecomment-171447199 but here the method added isn't even virtual).Reproduced with current git master (6eb2560e8d7192a8302e90ca3426df9aceb6d2e2).
I noticed that if we ignore the methods we don't want then it works - e.g. add this before the
%include "classes.h";:This is at least consistent with how method hiding would work if the
%extendmethod was actually added in C++, consider this:which fails to compile because
Ddoesn't inheritfloat return_float()from C:I don't think that's why this doesn't work in SWIG though.