diff --git a/SWIG/CHANGES.current b/SWIG/CHANGES.current index 621b4897b..7d189a885 100644 --- a/SWIG/CHANGES.current +++ b/SWIG/CHANGES.current @@ -1,6 +1,69 @@ Version 1.3.28 (unreleased) =========================== +11/07/2005: mmatus + + [Python] Adding proper support for multi-inheritance in + the python side, ie, if you have two C++ wrapped class, Foo + and Bar, now: + + class MyPythonClass(Foo,Bar): + .... + + will properly work, even with directors, and the + deallocation of Foo.this and Bar.this will follow + correctly. Before, since a class can only have one 'this' + instance (not as in C++), only the last base class was + properly deletted, or detected with directors. + + Now the self.this element can be a list, which will + contain the C++ instance pointers for all the base + classes. + + - Now the 'this' pointer is responsible for deallocating + the C++ instance, and the __del__ method is not emitted + unless the user preppend/append some code to it. + + - Swig now can detect memory leaks, ie, if you still + use the non-shadow module, and type something like + + import _example + f = _example.new_Foo() + + and forgot to call _example.delete_Foo(f), then swig + will tell you that there is a memory leak. + + Otherwise, if you always use the shadow module, probably + you will never ever see this warning unless there is + something wrong inside the swig wrapping code. + + + *** POTENTIAL INCOMPATIBILITY *** + + If you overloaded the __del__ method, and call the base + one without a try block, as in + + class MyClass(SwigClass): + + def __del__(self): + + SwigClass.__del__(self) + + python could complain that the method SwigClass.__del__ is + undefined. Try to use instead: + + def __del__(self): + + try: SwigClass.__del__(self) + except: pass + + or simply + + def __del__(self): + + + + 11/02/2005: mmatus [Python] Adding more fun to STL/STD containers, now you @@ -84,7 +147,7 @@ Version 1.3.28 (unreleased) In general the sequence method __iter__ will call 'iterator()', returning the native C++ iterator, but in maps it will call 'key_iterator()', maintaining - backcompatibilty. + backward compatibility. Hence, for std::maps, you can play then with the native C++ iterator, which value is a (key, value) pair, by @@ -153,12 +216,12 @@ Version 1.3.28 (unreleased) - With this change, and the other ones in the PySwigObject type, which now carries the thisown and - swig_type_info pointer, the generated code shoudl be as + swig_type_info pointer, the generated code should be as fast as boost::Python and/or the other python wrappers based in pure Python/C API calls. As a reference, the profiletest_runme.py example, which - does a simple call function many times: + does a simple call function many times, such as this code: import profiletest @@ -172,14 +235,20 @@ Version 1.3.28 (unreleased) produces the following times nomodern modern - swig-1.3.26 25.9s 7.6s - swig-CVS 3.4s 3.3s + swig-1.3.26 19.70s 5.98s + swig-CVS 0.99s 0.98s Clearly, there is a large improvement for the python 'nomodern' mode. Still, the 'modern' mode is around - twice faster than before. + 6 times faster than before. For the same test, but + using the non-shadow version of the module, we get + _profiletest (non-shadow) + swig-1.3.26 0.80s + swig-CVS 0.60s + + Hence, now the proxy overhead is almost insignificant. 10/31/2005: mmatus @@ -204,7 +273,7 @@ Version 1.3.28 (unreleased) print self.this.own() >>> True - - Support for iterartors in STL/STD containers, for example, if you have + - Support for iterators in STL/STD containers, for example, if you have %template std::set; @@ -375,7 +444,7 @@ Version 1.3.28 (unreleased) - uniform the names for the setter and getter methods in perl,tcl,ruby and python, so, the attribute.i library - can work accross them. + can work across them. - see the li_attribute.i test-case or the library file @@ -388,7 +457,7 @@ Version 1.3.28 (unreleased) 10/24/2005: mmatus - - Perl uses now the unified typemap libray. + - Perl uses now the unified typemap library. - Changes in ruby to use the $track option in typemaps. @@ -439,7 +508,7 @@ Version 1.3.28 (unreleased) perl5/perlstrings.swg - The rest fo the files, such as carray.i, are mostly one + The rest of the files, such as carray.i, are mostly one line files that include the proper typemap library version. diff --git a/SWIG/Examples/test-suite/director_basic.i b/SWIG/Examples/test-suite/director_basic.i index 8512a8afa..04316faa8 100644 --- a/SWIG/Examples/test-suite/director_basic.i +++ b/SWIG/Examples/test-suite/director_basic.i @@ -4,9 +4,12 @@ class Foo { public: - virtual ~Foo() {} - virtual std::string ping() { return "Foo::ping()"; } - virtual std::string pong() { return "Foo::pong();" + ping(); } + virtual ~Foo() {} + virtual std::string ping() { return "Foo::ping()"; } + virtual std::string pong() { return "Foo::pong();" + ping(); } + + static Foo* get_self(Foo *self) {return self;} + }; %} @@ -18,9 +21,12 @@ class Foo { public: - virtual ~Foo() {} - virtual std::string ping() { return "Foo::ping()"; } - virtual std::string pong() { return "Foo::pong();" + ping(); } + virtual ~Foo(); + virtual std::string ping(); + virtual std::string pong(); + + static Foo* get_self(Foo *self); + }; %{ diff --git a/SWIG/Examples/test-suite/python/director_basic_runme.py b/SWIG/Examples/test-suite/python/director_basic_runme.py index 3a6a4579b..efe13c513 100644 --- a/SWIG/Examples/test-suite/python/director_basic_runme.py +++ b/SWIG/Examples/test-suite/python/director_basic_runme.py @@ -38,8 +38,8 @@ b = director_basic.Bar(3) d = director_basic.MyClass() c = PyClass() -cc = PyClass.get_self(c) -dd = PyClass.get_self(d) +cc = director_basic.MyClass_get_self(c) +dd = director_basic.MyClass_get_self(d) bc = cc.cmethod(b) bd = dd.cmethod(b) @@ -51,3 +51,40 @@ if bc.x != 34: if bd.x != 16: raise RuntimeError + + +class PyMulti(director_basic.Foo, director_basic.MyClass): + def __init__(self): + director_basic.Foo.__init__(self) + director_basic.MyClass.__init__(self) + pass + + + def vmethod(self, b): + b.x += 31 + return b + + + def ping(self): + return "PyFoo::ping()" + +a = 0 +for i in range(0,100): + pymult = PyMulti() + pymult.pong() + del pymult + + + +pymult = PyMulti() + + + + +p1 = director_basic.Foo_get_self(pymult) +p2 = director_basic.MyClass_get_self(pymult) + +p1.ping() +p2.vmethod(bc) + + diff --git a/SWIG/Examples/test-suite/python/director_finalizer_runme.py b/SWIG/Examples/test-suite/python/director_finalizer_runme.py index 0be55793c..4cd1f573e 100644 --- a/SWIG/Examples/test-suite/python/director_finalizer_runme.py +++ b/SWIG/Examples/test-suite/python/director_finalizer_runme.py @@ -3,7 +3,8 @@ from director_finalizer import * class MyFoo(Foo): def __del__(self): self.orStatus(2) - Foo.__del__(self) + try: Foo.__del__(self) + except: pass resetStatus() diff --git a/SWIG/Examples/test-suite/python/disown_runme.py b/SWIG/Examples/test-suite/python/disown_runme.py index bc9583408..c11acf2fa 100644 --- a/SWIG/Examples/test-suite/python/disown_runme.py +++ b/SWIG/Examples/test-suite/python/disown_runme.py @@ -4,3 +4,6 @@ a = A() b = B() b.acquire(a) + +if a.this.own(): + raise RuntimeError diff --git a/SWIG/Examples/test-suite/python/profiletest_runme.py b/SWIG/Examples/test-suite/python/profiletest_runme.py index 1fc1e088a..e62df9338 100644 --- a/SWIG/Examples/test-suite/python/profiletest_runme.py +++ b/SWIG/Examples/test-suite/python/profiletest_runme.py @@ -1,27 +1,29 @@ +import _profiletest import profiletest a = profiletest.A() b = profiletest.B() +fn = b.fn i = 50000 while i: - a = b.fn(a) #1 - a = b.fn(a) #2 - a = b.fn(a) #3 - a = b.fn(a) #4 - a = b.fn(a) #5 - a = b.fn(a) #6 - a = b.fn(a) #7 - a = b.fn(a) #8 - a = b.fn(a) #9 - a = b.fn(a) #10 - a = b.fn(a) #1 - a = b.fn(a) #2 - a = b.fn(a) #3 - a = b.fn(a) #4 - a = b.fn(a) #5 - a = b.fn(a) #6 - a = b.fn(a) #7 - a = b.fn(a) #8 - a = b.fn(a) #9 - a = b.fn(a) #20 + a = fn(a) #1 + a = fn(a) #2 + a = fn(a) #3 + a = fn(a) #4 + a = fn(a) #5 + a = fn(a) #6 + a = fn(a) #7 + a = fn(a) #8 + a = fn(a) #9 + a = fn(a) #10 + a = fn(a) #1 + a = fn(a) #2 + a = fn(a) #3 + a = fn(a) #4 + a = fn(a) #5 + a = fn(a) #6 + a = fn(a) #7 + a = fn(a) #8 + a = fn(a) #9 + a = fn(a) #20 i -= 1 diff --git a/SWIG/Examples/test-suite/python/profiletestc_runme.py b/SWIG/Examples/test-suite/python/profiletestc_runme.py new file mode 100644 index 000000000..33461e484 --- /dev/null +++ b/SWIG/Examples/test-suite/python/profiletestc_runme.py @@ -0,0 +1,54 @@ +import _profiletest +#import profiletest + +pa = _profiletest.new_A() +pb = _profiletest.new_B() +fn = _profiletest.B_fn +destroy = _profiletest.delete_A +i = 50000 +a = pa +while i: + a = fn(pb,a) #1 + destroy(a) + a = fn(pb,a) #2 + destroy(a) + a = fn(pb,a) #3 + destroy(a) + a = fn(pb,a) #4 + destroy(a) + a = fn(pb,a) #5 + destroy(a) + a = fn(pb,a) #6 + destroy(a) + a = fn(pb,a) #7 + destroy(a) + a = fn(pb,a) #8 + destroy(a) + a = fn(pb,a) #9 + destroy(a) + a = fn(pb,a) #10 + destroy(a) + a = fn(pb,a) #1 + destroy(a) + a = fn(pb,a) #2 + destroy(a) + a = fn(pb,a) #3 + destroy(a) + a = fn(pb,a) #4 + destroy(a) + a = fn(pb,a) #5 + destroy(a) + a = fn(pb,a) #6 + destroy(a) + a = fn(pb,a) #7 + destroy(a) + a = fn(pb,a) #8 + destroy(a) + a = fn(pb,a) #9 + destroy(a) + a = fn(pb,a) #20 + destroy(a) + i -= 1 + +_profiletest.delete_A(pa) +_profiletest.delete_B(pb) diff --git a/SWIG/Lib/python/pyerrors.swg b/SWIG/Lib/python/pyerrors.swg index 13bdefc54..bfab4ea47 100644 --- a/SWIG/Lib/python/pyerrors.swg +++ b/SWIG/Lib/python/pyerrors.swg @@ -49,7 +49,9 @@ SWIG_Python_ErrorType(int code) { SWIGINTERNINLINE PyObject * SWIG_Python_ExceptionType(swig_type_info *desc) { - return (desc && desc->clientdata ? (PyObject *)(desc->clientdata) : PyExc_RuntimeError); + PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); } SWIGINTERN void diff --git a/SWIG/Lib/python/pyrun.swg b/SWIG/Lib/python/pyrun.swg index d0d6440dc..6610c9c54 100644 --- a/SWIG/Lib/python/pyrun.swg +++ b/SWIG/Lib/python/pyrun.swg @@ -59,15 +59,19 @@ extern "C" { /* PySwigObject */ +typedef struct { + PyObject *klass; + PyObject *newargs; + PyObject *destroy; +} PySwigClientData; typedef struct { PyObject_HEAD void *ptr; swig_type_info *ty; int own; + PyObject *next; } PySwigObject; - - SWIGRUNTIME PyObject * @@ -108,13 +112,14 @@ SWIGRUNTIME PyObject * PySwigObject_repr(PySwigObject *v) { const char *name = SWIG_TypePrettyName(v->ty); - PyObject *hex = PySwigObject_hex(v); - if (name) { - return PyString_FromFormat("", name, PyString_AsString(hex)); - } else { - return PyString_FromFormat("", PyString_AsString(hex)); - } + PyObject *hex = PySwigObject_hex(v); + PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); Py_DECREF(hex); + if (v->next) { + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); + PyString_ConcatAndDel(&repr,nrep); + } + return repr; } SWIGRUNTIME int @@ -130,7 +135,6 @@ PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSED flags) } } - SWIGRUNTIME PyObject * PySwigObject_str(PySwigObject *v) { @@ -158,47 +162,106 @@ PySwigObject_Check(PyObject *op) { SWIGRUNTIME void PySwigObject_dealloc(PyObject *v) { - if (PySwigObject_Check(v)) { - PySwigObject *self = (PySwigObject *) v; - if (self->own) { + PySwigObject *sobj = (PySwigObject *) v; + PyObject *next = sobj->next; + if (sobj->own) { + /* + Well, somebody forgot to call delete, or we have a + multi-inheritance case. Hence, we need to call + Class.__destroy__(this). + */ + swig_type_info *ty = sobj->ty; + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args,0,v); + PyObject_Call(destroy, args, NULL); + Py_DECREF(args); + } else { + const char *name = SWIG_TypePrettyName(ty); + PyObject *wrn = PyString_FromFormat("swig/python detected a memory leak of type '%s'.", name); + PyErr_Warn(PyExc_RuntimeWarning, PyString_AsString(wrn)); + Py_DECREF(wrn); } - } + } + Py_XDECREF(next); v->ob_type->tp_free(v); } - -SWIGINTERN PyObject* -PySwigObject_disown(PySwigObject *self) +SWIGRUNTIME PyObject* +PySwigObject_append(PyObject* v, PyObject* next) { - self->own = 0; + PySwigObject *sobj = (PySwigObject *) v; + if (!PySwigObject_Check(next)) + return NULL; + + sobj->next = next; + Py_INCREF(next); + Py_INCREF(Py_None); return Py_None; } -SWIGINTERN PyObject* -PySwigObject_acquire(PySwigObject *self) +SWIGRUNTIME PyObject* +PySwigObject_next(PyObject* v) { - self->own = 1; - Py_INCREF(Py_None); - return Py_None; -} + PySwigObject *sobj = (PySwigObject *) v; + PyObject *obj = sobj->next ? sobj->next : Py_None; -SWIGINTERN PyObject* -PySwigObject_own(PySwigObject *self) -{ - PyObject *obj = self->own ? Py_True : Py_False; Py_INCREF(obj); return obj; } +SWIGINTERN PyObject* +PySwigObject_disown(PyObject *v) +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = 0; + Py_INCREF(Py_None); + return Py_None; +} + +SWIGINTERN PyObject* +PySwigObject_acquire(PyObject *v) +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = 1; + Py_INCREF(Py_None); + return Py_None; +} + +SWIGINTERN PyObject* +PySwigObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; + if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) { + return NULL; + } else { + PySwigObject *sobj = (PySwigObject *)v; + PyObject *obj = sobj->own ? Py_True : Py_False; + if (val) { + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v); + } else { + PySwigObject_disown(v); + } + } + Py_INCREF(obj); + return obj; + } +} + SWIGRUNTIME PyTypeObject* PySwigObject_type(void) { static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; static PyMethodDef swigobject_methods[] = { - {"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, "release ownership of the pointer"}, - {"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, "aquire ownership of the pointer"}, - {"own", (PyCFunction)PySwigObject_own, METH_NOARGS, "return ownership status of the pointer"}, + {"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, "releases ownership of the pointer"}, + {"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, "aquires ownership of the pointer"}, + {"own", (PyCFunction)PySwigObject_own, METH_VARARGS, "returns/sets ownership of the pointer"}, + {"append", (PyCFunction)PySwigObject_append, METH_O, "appends another 'this' object"}, + {"next", (PyCFunction)PySwigObject_next, METH_NOARGS, "returns the next 'this' object"}, {0, 0, 0, 0} }; @@ -312,13 +375,14 @@ PySwigObject_type(void) { SWIGRUNTIME PyObject * PySwigObject_New(void *ptr, swig_type_info *ty, int own) { - PySwigObject *self = PyObject_NEW(PySwigObject, PySwigObject_type()); - if (self) { - self->ptr = ptr; - self->ty = ty; - self->own = own; + PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; } - return (PyObject *)self; + return (PyObject *)sobj; } /* ----------------------------------------------------------------------------- @@ -390,8 +454,8 @@ SWIGRUNTIME void PySwigPacked_dealloc(PyObject *v) { if (PySwigPacked_Check(v)) { - PySwigPacked *self = (PySwigPacked *) v; - free(self->pack); + PySwigPacked *sobj = (PySwigPacked *) v; + free(sobj->pack); } v->ob_type->tp_free(v); } @@ -476,17 +540,17 @@ PySwigPacked_type(void) { SWIGRUNTIME PyObject * PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) { - PySwigPacked *self = PyObject_NEW(PySwigPacked, PySwigPacked_type()); - if (self == NULL) { + PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); + if (sobj == NULL) { return NULL; } else { void *pack = malloc(size); if (pack) { memcpy(pack, ptr, size); - self->pack = pack; - self->ty = ty; - self->size = size; - return (PyObject *) self; + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + return (PyObject *) sobj; } return NULL; } @@ -496,10 +560,10 @@ SWIGRUNTIMEINLINE swig_type_info * PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) { if (PySwigPacked_Check(obj)) { - PySwigPacked *self = (PySwigPacked *)obj; - if (self->size != size) return 0; - memcpy(ptr, self->pack, size); - return self->ty; + PySwigPacked *sobj = (PySwigPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; } else { return 0; } @@ -519,24 +583,13 @@ SWIG_This() /* #define SWIG_PYTHON_SLOW_GETSET_THIS */ -/* Convert a pointer value */ -SWIGRUNTIME int -SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { - swig_type_info *to = 0; - const char *desc = 0; - int newref = 0; - PyObject *pyobj = 0; - void *vptr = 0; - PySwigObject *sobj = 0; - - if (!obj) return SWIG_ERROR; - if (obj == Py_None) { - *ptr = 0; - return SWIG_OK; - } - - if (!(PySwigObject_Check(obj))) { - pyobj = obj; +SWIGRUNTIMEINLINE PySwigObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + if (PySwigObject_Check(pyobj)) { + return (PySwigObject *) pyobj; + } else { + PyObject *obj = 0; #ifndef SWIG_PYTHON_SLOW_GETSET_THIS if (PyInstance_Check(pyobj)) { obj = _PyInstance_Lookup(pyobj, SWIG_This()); @@ -549,45 +602,60 @@ SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) obj = PyObject_GetAttr(pyobj,SWIG_This()); } } - Py_XINCREF(obj); #else obj = PyObject_GetAttr(pyobj,SWIG_This()); -#endif - if (!obj) goto type_error; - if (!PySwigObject_Check(obj)) { - Py_DECREF(obj); - goto type_error; +#endif + if (PyErr_Occurred()) { + obj = 0; + PyErr_Clear(); } - newref = 1; - } - sobj = (PySwigObject *) obj; - vptr = sobj->ptr; - to = sobj->ty; - desc = (const char *) to->name; - if (newref) { newref = 0; Py_DECREF(obj); } - - if (ty) { - if (to == ty) { - /* no type cast needed */ - *ptr = vptr; - } else { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) goto type_error; - *ptr = SWIG_TypeCast(tc,vptr); - } - } else { - *ptr = vptr; + return obj && PySwigObject_Check(obj) ? (PySwigObject *) obj : 0; } - if ((pyobj) && (flags & SWIG_POINTER_DISOWN)) { - sobj->own = 0; - } - return SWIG_OK; - - type_error: - PyErr_Clear(); - return SWIG_ERROR; } +/* Convert a pointer value */ +SWIGRUNTIME int +SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { + if (!obj) return SWIG_ERROR; + if (obj == Py_None) { + *ptr = 0; + return SWIG_OK; + } else { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (PySwigObject *)sobj->next; + } else { + *ptr = SWIG_TypeCast(tc,vptr); + break; + } + } + } else { + *ptr = vptr; + break; + } + } + if (sobj) { + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + return SWIG_OK; + } else { + return SWIG_ERROR; + } + } +} + + SWIGRUNTIME int SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { if (!PyCFunction_Check(obj)) { @@ -640,19 +708,34 @@ SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *t * Create a new pointer object * ----------------------------------------------------------------------------- */ -#define SWIG_NewClientData(obj) SWIG_Python_NewClientData(obj) +#define SWIG_NewClientData(obj) PySwigClientData_New(obj) SWIGRUNTIMEINLINE void * -SWIG_Python_NewClientData(PyObject* obj) +PySwigClientData_New(PyObject* obj) { + PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); + data->klass = 0; + data->newargs = 0; + data->destroy = 0; + if (PyClass_Check(obj)) { - Py_INCREF(obj); - return obj; + data->klass = obj; + data->newargs = obj; + Py_INCREF(data->newargs); } else { - PyObject *args = PyTuple_New(1); - PyTuple_SetItem(args, 0, obj); - return args; + data->klass = obj; + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); } + if (data->klass) { + static PyObject* SWIG_STATIC_POINTER(destroystr) = PyString_FromString("__destroy__"); + data->destroy = PyObject_GetAttr(data->klass, destroystr); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + } + return data; } /* @@ -660,15 +743,14 @@ SWIG_Python_NewClientData(PyObject* obj) and set the 'this' attribute. */ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(PyObject *obj, PyObject *swig_this) +SWIGRUNTIMEINLINE PyObject* +SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) { PyObject *inst = 0; - if (!PyClass_Check(obj)) { + if (!PyClass_Check(data->klass)) { static PyObject* SWIG_STATIC_POINTER(fnew) = PyObject_GetAttrString((PyObject*)&PyBaseObject_Type, "__new__"); - inst = PyObject_Call(fnew, obj, NULL); + inst = PyObject_Call(fnew, data->newargs, NULL); if (inst) { #ifndef SWIG_PYTHON_SLOW_GETSET_THIS PyObject **dictptr = _PyObject_GetDictPtr(inst); @@ -677,17 +759,17 @@ SWIG_Python_NewShadowInstance(PyObject *obj, PyObject *swig_this) if (dict == NULL) { dict = PyDict_New(); *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); } - PyDict_SetItem(dict, SWIG_This(), swig_this); - } + } #else PyObject_SetAttr(inst, SWIG_This(), swig_this); #endif } } else { PyObject *dict = PyDict_New(); - PyDict_SetItem(dict,SWIG_This(), swig_this); - inst = PyInstance_NewRaw(obj, dict); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); Py_DECREF(dict); } return inst; @@ -696,30 +778,26 @@ SWIG_Python_NewShadowInstance(PyObject *obj, PyObject *swig_this) SWIGRUNTIME PyObject * SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { - PyObject *robj = 0; - int own = (flags & SWIG_POINTER_OWN); - int shadow = !(flags & SWIG_POINTER_NOSHADOW); - if (!type) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "Swig: null type passed to NewPointerObj"); - } - return robj; - } if (!ptr) { Py_INCREF(Py_None); return Py_None; - } - - robj = PySwigObject_New((void *) ptr, type, own); - if (!robj || (robj == Py_None)) return robj; - if (shadow && type->clientdata) { - PyObject *inst = SWIG_Python_NewShadowInstance((PyObject *)type->clientdata, robj); - if (inst) { - Py_DECREF(robj); - robj = inst; + } else if (!type) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "Swig: null type passed to NewPointerObj"); } + return NULL; + } else { + PyObject *robj = PySwigObject_New((void *) ptr, type, (flags & SWIG_POINTER_OWN)); + PySwigClientData *clientdata = (PySwigClientData *)type->clientdata; + if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + if (inst) { + Py_DECREF(robj); + robj = inst; + } + } + return robj; } - return robj; } /* Create a new array object */