Python -builtin fix wrapping constructors with varargs
Fix compilation error when using -builtin and wrapping varargs in constructors Closes #1942
This commit is contained in:
parent
71709af99a
commit
90cdbee6a6
6 changed files with 64 additions and 10 deletions
|
|
@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.1.0 (in progress)
|
Version 4.1.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2021-03-23: wsfulton
|
||||||
|
#1942 [Python] Fix compilation error in wrappers when using -builtin
|
||||||
|
and wrapping varargs in constructors.
|
||||||
|
|
||||||
2021-03-22: goto40
|
2021-03-22: goto40
|
||||||
#1977 Fix handling of template template parameters.
|
#1977 Fix handling of template template parameters.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,3 +126,21 @@ struct Extending2 {};
|
||||||
struct ExtendingOptArgs1 {};
|
struct ExtendingOptArgs1 {};
|
||||||
struct ExtendingOptArgs2 {};
|
struct ExtendingOptArgs2 {};
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// Varargs
|
||||||
|
%warnfilter(SWIGWARN_LANG_VARARGS_KEYWORD) VarargConstructor::VarargConstructor; // Can't wrap varargs with keyword arguments enabled
|
||||||
|
%warnfilter(SWIGWARN_LANG_VARARGS_KEYWORD) VarargConstructor::vararg_method; // Can't wrap varargs with keyword arguments enabled
|
||||||
|
%inline %{
|
||||||
|
struct VarargConstructor {
|
||||||
|
char *str;
|
||||||
|
VarargConstructor(const char *fmt, ...) {
|
||||||
|
str = new char[strlen(fmt) + 1];
|
||||||
|
strcpy(str, fmt);
|
||||||
|
}
|
||||||
|
void vararg_method(const char *fmt, ...) {
|
||||||
|
delete [] str;
|
||||||
|
str = new char[strlen(fmt) + 1];
|
||||||
|
strcpy(str, fmt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
|
||||||
|
|
@ -122,3 +122,18 @@ try:
|
||||||
raise RuntimeError("missed exception")
|
raise RuntimeError("missed exception")
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Varargs
|
||||||
|
f = VarargConstructor(fmt="Ciao")
|
||||||
|
f.vararg_method(fmt="Bonjour")
|
||||||
|
try:
|
||||||
|
f = VarargConstructor(nonexistent="Ciao")
|
||||||
|
raise RuntimeError("missed exception")
|
||||||
|
except TypeError as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
f.vararg_method(nonexistent="Bonjour")
|
||||||
|
raise RuntimeError("missed exception")
|
||||||
|
except TypeError as e:
|
||||||
|
pass
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ import varargs
|
||||||
if varargs.test("Hello") != "Hello":
|
if varargs.test("Hello") != "Hello":
|
||||||
raise RuntimeError("Failed")
|
raise RuntimeError("Failed")
|
||||||
|
|
||||||
|
vc = varargs.VarargConstructor("Hey there")
|
||||||
|
if vc.str != "Hey there":
|
||||||
|
raise RuntimeError("Failed")
|
||||||
|
|
||||||
f = varargs.Foo("Greetings")
|
f = varargs.Foo("Greetings")
|
||||||
if f.str != "Greetings":
|
if f.str != "Greetings":
|
||||||
raise RuntimeError("Failed")
|
raise RuntimeError("Failed")
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,31 @@
|
||||||
// Tests SWIG's *default* handling of varargs (function varargs, not preprocessor varargs).
|
// Tests SWIG's handling of varargs (function varargs, not preprocessor varargs).
|
||||||
// The default behavior is to simply ignore the varargs.
|
// The default behavior is to simply ignore the varargs.
|
||||||
%module varargs
|
%module varargs
|
||||||
|
|
||||||
|
// Default handling of varargs
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
char *test(const char *fmt, ...) {
|
||||||
|
return (char *) fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VarargConstructor {
|
||||||
|
char *str;
|
||||||
|
VarargConstructor(const char *fmt, ...) {
|
||||||
|
str = new char[strlen(fmt) + 1];
|
||||||
|
strcpy(str, fmt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// %varargs support
|
||||||
|
|
||||||
%varargs(int mode = 0) test_def;
|
%varargs(int mode = 0) test_def;
|
||||||
%varargs(int mode = 0) Foo::Foo;
|
%varargs(int mode = 0) Foo::Foo;
|
||||||
%varargs(int mode = 0) Foo::statictest(const char*fmt, ...);
|
%varargs(int mode = 0) Foo::statictest(const char*fmt, ...);
|
||||||
%varargs(2, int mode = 0) test_plenty(const char*fmt, ...);
|
%varargs(2, int mode = 0) test_plenty(const char*fmt, ...);
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
char *test(const char *fmt, ...) {
|
|
||||||
return (char *) fmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *test_def(const char *fmt, ...) {
|
const char *test_def(const char *fmt, ...) {
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
|
@ -40,5 +54,4 @@ public:
|
||||||
const char *test_plenty(const char *fmt, ...) {
|
const char *test_plenty(const char *fmt, ...) {
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
|
|
@ -2753,7 +2753,7 @@ public:
|
||||||
if (!varargs) {
|
if (!varargs) {
|
||||||
Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
|
Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
|
||||||
} else {
|
} else {
|
||||||
Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs) {", NIL);
|
Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs", builtin_kwargs, ") {", NIL);
|
||||||
}
|
}
|
||||||
if (allow_kwargs) {
|
if (allow_kwargs) {
|
||||||
Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions (%s).\n", Swig_name_decl(n));
|
Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions (%s).\n", Swig_name_decl(n));
|
||||||
|
|
@ -3253,10 +3253,10 @@ public:
|
||||||
Printf(f->code, " Py_XINCREF(swig_obj[i + %d]);\n", num_fixed_arguments);
|
Printf(f->code, " Py_XINCREF(swig_obj[i + %d]);\n", num_fixed_arguments);
|
||||||
Printf(f->code, "}\n");
|
Printf(f->code, "}\n");
|
||||||
} else {
|
} else {
|
||||||
Printf(f->code, "newargs = PyTuple_GetSlice(args,0,%d);\n", num_fixed_arguments);
|
Printf(f->code, "newargs = PyTuple_GetSlice(args, 0, %d);\n", num_fixed_arguments);
|
||||||
Printf(f->code, "varargs = PyTuple_GetSlice(args,%d,PyTuple_Size(args));\n", num_fixed_arguments);
|
Printf(f->code, "varargs = PyTuple_GetSlice(args, %d, PyTuple_Size(args));\n", num_fixed_arguments);
|
||||||
}
|
}
|
||||||
Printf(f->code, "resultobj = %s__varargs__(%s,newargs,varargs);\n", wname, builtin ? "self" : "NULL");
|
Printf(f->code, "resultobj = %s__varargs__(%s, newargs, varargs%s);\n", wname, builtin ? "self" : "NULL", strlen(builtin_kwargs) == 0 ? "" : ", kwargs");
|
||||||
Append(f->code, "Py_XDECREF(newargs);\n");
|
Append(f->code, "Py_XDECREF(newargs);\n");
|
||||||
Append(f->code, "Py_XDECREF(varargs);\n");
|
Append(f->code, "Py_XDECREF(varargs);\n");
|
||||||
Append(f->code, "return resultobj;\n");
|
Append(f->code, "return resultobj;\n");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue