From c805e48d3572c6c59eaaf2cd963b68c78458ab50 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Tue, 20 Dec 2005 00:35:03 +0000 Subject: [PATCH] add the -modernargs/-nomodernargs options and code to deal with old python 1.5 git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8013 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/python/pycontainer.swg | 3 - Lib/python/pyrun.swg | 115 +++++++++++++++++++++++++++++++------ Lib/python/pyruntime.swg | 20 +++++++ Source/Modules/python.cxx | 52 ++++++++++++----- 4 files changed, 155 insertions(+), 35 deletions(-) diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg index daaed85f3..50a9f35db 100644 --- a/Lib/python/pycontainer.swg +++ b/Lib/python/pycontainer.swg @@ -27,9 +27,6 @@ /**** The PySequence C++ Wrap ***/ %insert(header) %{ -#if PY_VERSION_HEX < 0x02000000 -#define PySequence_Size PySequence_Length -#endif #include %} diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg index 474db28e2..7e49ca1f3 100644 --- a/Lib/python/pyrun.swg +++ b/Lib/python/pyrun.swg @@ -185,11 +185,17 @@ PySwigClientData_New(PyObject* obj) data->newargs = obj; Py_INCREF(obj); } else { +#if (PY_VERSION_HEX < 0x02020000) + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); +#else data->newraw = PyObject_GetAttrString((PyObject*)&PyBaseObject_Type, "__new__"); Py_INCREF(data->newraw); data->newargs = PyTuple_New(1); PyTuple_SetItem(data->newargs, 0, obj); Py_INCREF(data->newargs); +#endif } /* the destroy method, aka as the C++ delete method */ data->destroy = PyObject_GetAttrString(data->klass, "__swig_destroy__"); @@ -200,7 +206,11 @@ PySwigClientData_New(PyObject* obj) if (data->destroy) { Py_INCREF(data->destroy); int flags = PyCFunction_GET_FLAGS(data->destroy); +#ifdef METH_O data->delargs = !(flags & (METH_O)); +#else + data->delargs = 0; +#endif } else { data->delargs = 0; } @@ -340,7 +350,11 @@ PySwigObject_dealloc(PyObject *v) if (data->delargs) { /* we need to create a temporal object to carry the destroy operation */ PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); +#if PY_VERSION_HEX >= 0x02020000 res = PyObject_CallFunctionObjArgs(destroy, tmp, NULL); +#else + res = PyObject_CallFunction(destroy, "O", tmp); +#endif Py_DECREF(tmp); } else { PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); @@ -350,19 +364,28 @@ PySwigObject_dealloc(PyObject *v) Py_XDECREF(res); } else { const char *name = SWIG_TypePrettyName(ty); +#if (PY_VERSION_HEX >= 0x02020000) PyObject *wrn = PyString_FromFormat("swig/python detected a memory leak of type '%s'.", name); PyErr_Warn(PyExc_RuntimeWarning, PyString_AsString(wrn)); Py_DECREF(wrn); +#else + printf("swig/python detected a memory leak of type '%s'.", name); +#endif } } Py_XDECREF(next); - v->ob_type->tp_free(v); + PyObject_DEL(v); } SWIGRUNTIME PyObject* PySwigObject_append(PyObject* v, PyObject* next) { PySwigObject *sobj = (PySwigObject *) v; +#ifndef METH_O + PyObject *tmp = 0; + if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; + next = tmp; +#endif if (!PySwigObject_Check(next)) { return NULL; } @@ -372,7 +395,11 @@ PySwigObject_append(PyObject* v, PyObject* next) } SWIGRUNTIME PyObject* +#ifdef METH_NOARGS PySwigObject_next(PyObject* v) +#else +PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif { PySwigObject *sobj = (PySwigObject *) v; if (sobj->next) { @@ -384,7 +411,11 @@ PySwigObject_next(PyObject* v) } SWIGINTERN PyObject* +#ifdef METH_NOARGS PySwigObject_disown(PyObject *v) +#else +PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif { PySwigObject *sobj = (PySwigObject *)v; sobj->own = 0; @@ -392,7 +423,11 @@ PySwigObject_disown(PyObject *v) } SWIGINTERN PyObject* +#ifdef METH_NOARGS PySwigObject_acquire(PyObject *v) +#else +PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif { PySwigObject *sobj = (PySwigObject *)v; sobj->own = SWIG_POINTER_OWN; @@ -403,27 +438,43 @@ 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); - } +#if (PY_VERSION_HEX < 0x02020000) + if (!PyArg_ParseTuple(args,(char *)"O:own",&val)) +#else + if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) +#endif + { + return NULL; } - Py_INCREF(obj); - return obj; - } + else + { + PySwigObject *sobj = (PySwigObject *)v; + PyObject *obj = sobj->own ? Py_True : Py_False; + if (val) { +#ifdef METH_NOARGS + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v); + } else { + PySwigObject_disown(v); + } +#else + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v,args); + } else { + PySwigObject_disown(v,args); + } +#endif + } + Py_INCREF(obj); + return obj; + } } SWIGRUNTIME PyTypeObject* _PySwigObject_type(void) { static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; static PyMethodDef +#ifdef METH_O swigobject_methods[] = { {"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, "releases ownership of the pointer"}, {"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, "aquires ownership of the pointer"}, @@ -432,6 +483,16 @@ _PySwigObject_type(void) { {"next", (PyCFunction)PySwigObject_next, METH_NOARGS, "returns the next 'this' object"}, {0, 0, 0, 0} }; +#else + swigobject_methods[] = { + {"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, "releases ownership of the pointer"}, + {"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, "aquires ownership of the pointer"}, + {"own", (PyCFunction)PySwigObject_own, METH_VARARGS, "returns/sets ownership of the pointer"}, + {"append", (PyCFunction)PySwigObject_append, METH_VARARGS, "appends another 'this' object"}, + {"next", (PyCFunction)PySwigObject_next, METH_VARARGS, "returns the next 'this' object"}, + {0, 0, 0, 0} + }; +#endif static PyNumberMethods PySwigObject_as_number = { (binaryfunc)0, /*nb_add*/ @@ -621,7 +682,7 @@ PySwigPacked_dealloc(PyObject *v) PySwigPacked *sobj = (PySwigPacked *) v; free(sobj->pack); } - v->ob_type->tp_free(v); + PyObject_DEL(v); } SWIGRUNTIME PyTypeObject* @@ -649,7 +710,7 @@ _PySwigPacked_type(void) { (hashfunc)0, /* tp_hash */ (ternaryfunc)0, /* tp_call */ (reprfunc)PySwigPacked_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ @@ -756,7 +817,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj) return (PySwigObject *) pyobj; } else { PyObject *obj = 0; -#ifndef SWIG_PYTHON_SLOW_GETSET_THIS +#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && !(PY_VERSION_HEX < 0x02020000)) if (PyInstance_Check(pyobj)) { obj = _PyInstance_Lookup(pyobj, SWIG_This()); } else { @@ -900,12 +961,13 @@ SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *t SWIGRUNTIMEINLINE PyObject* SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) { +#if (PY_VERSION_HEX >= 0x02020000) PyObject *inst = 0; PyObject *newraw = data->newraw; if (newraw) { inst = PyObject_Call(newraw, data->newargs, NULL); if (inst) { -#ifndef SWIG_PYTHON_SLOW_GETSET_THIS +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) PyObject **dictptr = _PyObject_GetDictPtr(inst); if (dictptr != NULL) { PyObject *dict = *dictptr; @@ -927,6 +989,21 @@ SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) Py_DECREF(dict); } return inst; +#else + PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); + if (inst == NULL) { + return NULL; + } + inst->in_class = (PyClassObject *)data->newargs; + Py_INCREF(inst->in_class); + inst->in_dict = PyDict_New(); + if (inst->in_dict == NULL) { + Py_DECREF(inst); + return NULL; + } + PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); + return (PyObject *) inst; +#endif } /* Create a new pointer object */ diff --git a/Lib/python/pyruntime.swg b/Lib/python/pyruntime.swg index 8a42565ec..cf18ceac1 100644 --- a/Lib/python/pyruntime.swg +++ b/Lib/python/pyruntime.swg @@ -30,6 +30,26 @@ PyString_FromFormat(const char *fmt, ...) { #if PY_VERSION_HEX < 0x01060000 #define PyObject_Del(op) PyMem_DEL((op)) #endif +#ifndef PyObject_DEL +#define PyObject_DEL PyObject_Del +#endif + +/* A crude PyExc_StopIteration exception for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +#define PyExc_StopIteration PyExc_RuntimeError +#define PyObject_GenericGetAttr 0 +#define Py_NotImplemented PyExc_RuntimeError +#endif + + +/* A crude PyString_AsStringAndSize implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02010000 +#define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} +#endif + +#if PY_VERSION_HEX < 0x02000000 +#define PySequence_Size PySequence_Length +#endif %} %insert(runtime) "swigrun.swg"; /* SWIG API */ diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index a60fcf5d3..ed5515588 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -67,6 +67,7 @@ static int safecstrings = 0; static int dirvtable = 0; static int proxydel = 1; static int fastunpack = 0; +static int modernargs = 0; static int aliasobj0 = 0; /* flags for the make_autodoc function */ @@ -107,12 +108,14 @@ Python Options (available with -python)\n\ -nodirvtable - Don't use the virtual table feature, resolve the python method each time (default)\n\ -proxydel - Generate a __del__ method even when now is redundant (default) \n\ -noproxydel - Don't generate the redundant __del__ method \n\ + -modernargs - Use \"modern\" args mechanism to pack/unpack the function arguments \n\ + -nomodernargs - Use classic ParseTuple/CallFunction methods to pack/unpack the function arguments (default) \n\ -fastunpack - Use fast unpack mechanism to parse the argument functions \n\ -nofastunpack - Use traditional UnpackTuple method to parse the argument functions (default) \n\ -aliasobj0 - Alias obj0 when using fastunpack, needed for some old typemaps \n\ -noaliasobj0 - Don't generate an obj0 alias when using fastunpack (default) \n\ - -O - Enable several old and new optimizations options: \n\ - -modern -fastdispatch -dirvtable -nosafecstrings -fvirtual -noproxydel -fastunpack\n\ + -O - Enable all the optimizations options: \n\ + -modern -fastdispatch -dirvtable -nosafecstrings -fvirtual -noproxydel -fastunpack -modernargs\n\ \n"; class PYTHON : public Language { @@ -252,6 +255,7 @@ public: Swig_mark_arg(i); } else if (strcmp(argv[i],"-classic") == 0) { classic = 1; + modernargs = 0; apply = 1; modern = 0; Swig_mark_arg(i); @@ -290,6 +294,12 @@ public: } else if (strcmp(argv[i],"-nofastunpack") == 0) { fastunpack = 0; Swig_mark_arg(i); + } else if (strcmp(argv[i],"-modernargs") == 0) { + modernargs = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-nomodernargs") == 0) { + modernargs = 0; + Swig_mark_arg(i); } else if (strcmp(argv[i],"-aliasobj0") == 0) { aliasobj0 = 1; Swig_mark_arg(i); @@ -306,9 +316,11 @@ public: apply = 0; classic = 0; modern = 1; + modernargs = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-nomodern") == 0) { modern = 0; + modernargs = 0; Swig_mark_arg(i); } else if (strcmp(argv[i],"-noh") == 0) { no_header_file = 1; @@ -327,6 +339,7 @@ public: classptr = 0; proxydel = 0; fastunpack = 1; + modernargs = 1; Wrapper_fast_dispatch_mode_set(1); Wrapper_virtual_elimination_mode_set(1); Swig_mark_arg(i); @@ -1318,7 +1331,7 @@ public: Printf(f->code,"}\n"); } else { String *iname = Getattr(n,"sym:name"); - Printf(f->code,"if (!(argc = SWIG_Python_UnpackTuple(args,\"%s\",0,%d,argv))) SWIG_fail;\n", iname, maxargs); + Printf(f->code,"if (!(argc = SWIG_Python_Modernargs(args,\"%s\",0,%d,argv))) SWIG_fail;\n", iname, maxargs); Printf(f->code,"--argc;\n"); } @@ -1430,7 +1443,7 @@ public: num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); varargs = emit_isvarargs(l); - int funpack = fastunpack && !varargs && !allow_kwargs ; + int funpack = modernargs && fastunpack && !varargs && !allow_kwargs ; int noargs = funpack && (num_required == 0 && num_arguments == 0); int onearg = funpack && (num_required == 1 && num_arguments == 1); @@ -1576,7 +1589,7 @@ public: Printv(f->locals,tab4, "char * kwnames[] = ", kwargs, ";\n", NIL); } - if (use_parse || allow_kwargs) { + if (use_parse || allow_kwargs || !modernargs) { Printf(parse_args,":%s\"", iname); Printv(parse_args,arglist, ")) goto fail;\n",NIL); funpack = 0; @@ -1603,12 +1616,12 @@ public: if (onearg) { Printf(parse_args,"if (!args) { goto fail; } else { swig_obj[0] = args; }\n"); } else if (!noargs) { - Printf(parse_args,"if(!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,swig_obj)) goto fail;\n", + Printf(parse_args,"if(!SWIG_Python_Modernargs(args,\"%s\",%d,%d,swig_obj)) goto fail;\n", iname, num_required, num_arguments); } } } else { - Printf(parse_args,"if(!PyArg_UnpackTuple(args,(char *)\"%s\",%d,%d", iname, num_required, num_arguments); + Printf(parse_args,"if(!PyArg_Modernargs(args,(char *)\"%s\",%d,%d", iname, num_required, num_arguments); Printv(parse_args,arglist, ")) goto fail;\n",NIL); } } @@ -2454,9 +2467,18 @@ public: SwigType_remember(ct); Printv(f_wrappers, "SWIGINTERN PyObject * ", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL); + Printv(f_wrappers, tab4, "PyObject *obj;\n", NIL); + if (modernargs) { + if (fastunpack) { + Printv(f_wrappers, tab4, "if (!SWIG_Python_Modernargs(args,(char*)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL); + } else { + Printv(f_wrappers, tab4, "if (!PyArg_Modernargs(args,(char*)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL); + } + } else { + Printv(f_wrappers, tab4, "if (!PyArg_ParseTuple(args,(char*)\"O|swigregister\", &obj)) return NULL;\n", NIL); + } + Printv(f_wrappers, - tab4, "PyObject *obj;\n", - tab4, "if (!PyArg_UnpackTuple(args,(char*)\"swigregister\", 1, 1,&obj)) return NULL;\n", tab4, "SWIG_TypeNewClientData(SWIGTYPE", SwigType_manglestr(ct),", SWIG_NewClientData(obj));\n", tab4, "return SWIG_Py_Void();\n", "}\n",NIL); @@ -3264,7 +3286,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { Printf(w->code, "PyObject* method = swig_get_method(swig_method_index, swig_method_name);\n"); if (Len(parse_args) > 0) { - if (use_parse) { + if (use_parse || !modernargs) { Printf(w->code, "swig::PyObject_var result = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", parse_args, arglist); } else { Printf(w->code, "swig::PyObject_var result = PyObject_CallFunctionObjArgs(method %s, NULL);\n", arglist); @@ -3275,7 +3297,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { } Printf(w->code,"#else\n"); if (Len(parse_args) > 0) { - if (use_parse) { + if (use_parse || !modernargs) { Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n", pyname, parse_args, arglist); } else { @@ -3284,8 +3306,12 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { arglist); } } else { - Printf(w->code, "swig::PyObject_var swig_method_name = PyString_FromString((char *)\"%s\");\n", pyname); - Printf(w->code, "swig::PyObject_var result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n"); + if (!modernargs) { + Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *) \"%s\", NULL);\n", pyname); + } else { + Printf(w->code, "swig::PyObject_var swig_method_name = PyString_FromString((char *)\"%s\");\n", pyname); + Printf(w->code, "swig::PyObject_var result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n"); + } } Printf(w->code,"#endif\n");