aboutsummaryrefslogtreecommitdiff
path: root/Source/Modules/python.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/python.cxx')
-rw-r--r--Source/Modules/python.cxx1905
1 files changed, 892 insertions, 1013 deletions
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index a6801fc4e..ea31af029 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
+ * This file is part of SWIG, which is licensed as a whole under version 3
* (or any later version) of the GNU General Public License. Some additional
* terms also apply to certain portions of SWIG. The full details of the SWIG
* license and copyrights can be found in the LICENSE and COPYRIGHT files
@@ -16,11 +16,16 @@
#include "cparse.h"
#include <ctype.h>
#include <errno.h>
-#include <stdlib.h>
+#include "pydoc.h"
+
+#include <stdint.h>
#define PYSHADOW_MEMBER 0x2
#define WARN_PYTHON_MULTIPLE_INH 405
+#define PYTHON_INT_MAX (2147483647)
+#define PYTHON_INT_MIN (-2147483647-1)
+
static String *const_code = 0;
static String *module = 0;
static String *package = 0;
@@ -56,12 +61,10 @@ static String *builtin_default_unref = 0;
static String *builtin_closures_code = 0;
static String *methods;
+static String *methods_proxydocs;
static String *class_name;
static String *shadow_indent = 0;
static int in_class = 0;
-static int classic = 0;
-static int modern = 0;
-static int new_repr = 1;
static int no_header_file = 0;
static int max_bases = 0;
static int builtin_bases_needed = 0;
@@ -77,24 +80,15 @@ static String *real_classname;
/* Thread Support */
static int threads = 0;
static int nothreads = 0;
-static int classptr = 0;
+
/* Other options */
-static int shadowimport = 1;
-static int buildnone = 0;
-static int nobuildnone = 0;
-static int safecstrings = 0;
static int dirvtable = 0;
-static int proxydel = 1;
-static int fastunpack = 0;
+static int doxygen = 0;
+static int fastunpack = 1;
static int fastproxy = 0;
-static int fastquery = 0;
-static int fastinit = 0;
static int olddefs = 0;
-static int modernargs = 0;
-static int aliasobj0 = 0;
static int castmode = 0;
static int extranative = 0;
-static int outputtuple = 0;
static int nortti = 0;
static int relativeimport = 0;
@@ -105,68 +99,38 @@ enum autodoc_t {
AUTODOC_DTOR,
AUTODOC_STATICFUNC,
AUTODOC_FUNC,
- AUTODOC_METHOD
+ AUTODOC_METHOD,
+ AUTODOC_CONST,
+ AUTODOC_VAR
};
static const char *usage1 = "\
Python Options (available with -python)\n\
- -aliasobj0 - Alias obj0 when using fastunpack, needed for some old typemaps \n\
- -buildnone - Use Py_BuildValue(" ") to obtain Py_None (default in Windows)\n\
- -builtin - Create new python built-in types, rather than proxy classes, for better performance\n\
- -castmode - Enable the casting mode, which allows implicit cast between types in python\n\
- -classic - Use classic classes only\n\
- -classptr - Generate shadow 'ClassPtr' as in older swig versions\n\
- -cppcast - Enable C++ casting operators (default) \n\
- -dirvtable - Generate a pseudo virtual table for directors for faster dispatch \n\
- -extranative - Return extra native C++ wraps for std containers when possible \n\
- -fastinit - Use fast init mechanism for classes (default)\n\
- -fastunpack - Use fast unpack mechanism to parse the argument functions \n\
- -fastproxy - Use fast proxy mechanism for member methods \n\
- -fastquery - Use fast query mechanism for types \n\
- -globals <name> - Set <name> used to access C global variable [default: 'cvar']\n\
- -interface <lib>- Set the lib name to <lib>\n\
- -keyword - Use keyword arguments\n\
- -modern - Use modern python features only, without compatibility code\n\
- -modernargs - Use \"modern\" args mechanism to pack/unpack the function arguments\n";
+ -builtin - Create Python built-in types rather than proxy classes, for better performance\n\
+ -castmode - Enable the casting mode, which allows implicit cast between types in Python\n\
+ -debug-doxygen-parser - Display doxygen parser module debugging information\n\
+ -debug-doxygen-translator - Display doxygen translator module debugging information\n\
+ -dirvtable - Generate a pseudo virtual table for directors for faster dispatch\n\
+ -doxygen - Convert C++ doxygen comments to pydoc comments in proxy classes\n\
+ -extranative - Return extra native wrappers for C++ std containers wherever possible\n\
+ -fastproxy - Use fast proxy mechanism for member methods\n\
+ -globals <name> - Set <name> used to access C global variable (default: 'cvar')\n\
+ -interface <mod>- Set low-level C/C++ module name to <mod> (default: module name prefixed by '_')\n\
+ -keyword - Use keyword arguments\n";
static const char *usage2 = "\
- -newrepr - Use more informative version of __repr__ in proxy classes (default) \n\
- -newvwm - New value wrapper mode, use only when everything else fails \n\
- -noaliasobj0 - Don't generate an obj0 alias when using fastunpack (default) \n\
- -nobuildnone - Access Py_None directly (default in non-Windows systems)\n\
- -nocastmode - Disable the casting mode (default)\n\
- -nocppcast - Disable C++ casting operators, useful for generating bugs\n\
- -nodirvtable - Don't use the virtual table feature, resolve the python method each time (default)\n\
- -noexcept - No automatic exception handling\n\
- -noextranative - Don't use extra native C++ wraps for std containers when possible (default) \n\
- -nofastinit - Use traditional init mechanism for classes \n\
- -nofastunpack - Use traditional UnpackTuple method to parse the argument functions (default) \n\
- -nofastproxy - Use traditional proxy mechanism for member methods (default) \n\
- -nofastquery - Use traditional query mechanism for types (default) \n\
- -noh - Don't generate the output header file\n\
- -nomodern - Don't use modern python features which are not backwards compatible \n\
- -nomodernargs - Use classic ParseTuple/CallFunction methods to pack/unpack the function arguments (default) \n";
+ -nofastunpack - Use traditional UnpackTuple method to parse the argument functions\n\
+ -noh - Don't generate the output header file\n";
static const char *usage3 = "\
- -noolddefs - Don't emit the old method definitions even when using fastproxy (default) \n\
- -nooutputtuple - Use a PyList for appending output values (default) \n\
- -noproxy - Don't generate proxy classes \n\
- -noproxydel - Don't generate the redundant __del__ method \n\
- -noproxyimport - Don't insert proxy import statements derived from the %import directive \n\
+ -noproxy - Don't generate proxy classes\n\
-nortti - Disable the use of the native C++ RTTI with directors\n\
- -nosafecstrings - Avoid extra strings copies when possible (default)\n\
-nothreads - Disable thread support for the entire interface\n\
- -olddefs - Keep the old method definitions even when using fastproxy\n\
- -oldrepr - Use shorter and old version of __repr__ in proxy classes\n\
- -outputtuple - Use a PyTuple for outputs instead of a PyList (use carefully with legacy interfaces) \n\
- -proxydel - Generate a __del__ method even though it is now redundant (default) \n\
- -relativeimport - Use relative python imports \n\
- -safecstrings - Use safer (but slower) C string mapping, generating copies from Python -> C/C++\n\
+ -olddefs - Keep the old method definitions when using -fastproxy\n\
+ -py3 - Generate code with Python 3 specific features and syntax\n\
+ -relativeimport - Use relative Python imports\n\
-threads - Add thread support for all the interface\n\
- -O - Enable the following optimization options: \n\
- -modern -fastdispatch -nosafecstrings -fvirtual -noproxydel \n\
- -fastproxy -fastinit -fastunpack -fastquery -modernargs -nobuildnone \n\
- -py3 - Generate code with Python 3 specific features:\n\
- Function annotation \n\
+ -O - Enable the following optimization options:\n\
+ -fastdispatch -fastproxy -fvirtual\n\
\n";
static String *getSlot(Node *n = NULL, const char *key = NULL, String *default_slot = NULL) {
@@ -177,7 +141,7 @@ static String *getSlot(Node *n = NULL, const char *key = NULL, String *default_s
static void printSlot(File *f, String *slotval, const char *slotname, const char *functype = NULL) {
String *slotval_override = 0;
- if (functype)
+ if (functype && Strcmp(slotval, "0") == 0)
slotval = slotval_override = NewStringf("(%s) %s", functype, slotval);
int len = Len(slotval);
int fieldwidth = len > 41 ? (len > 61 ? 0 : 61 - len) : 41 - len;
@@ -199,6 +163,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) {
"ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
"ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
"ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
+ "objobjproc", "SWIGPY_OBJOBJPROC_CLOSURE",
"objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
"reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
"hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
@@ -218,6 +183,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) {
"ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
"ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
"ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
+ "objobjproc", "SWIGPY_FUNPACK_OBJOBJPROC_CLOSURE",
"objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
"reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
"hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
@@ -255,6 +221,11 @@ public:
director_multiple_inheritance = 1;
director_language = 1;
}
+
+ ~PYTHON() {
+ delete doxygenTranslator;
+ }
+
/* ------------------------------------------------------------
* Thread Implementation
* ------------------------------------------------------------ */
@@ -326,10 +297,11 @@ public:
* ------------------------------------------------------------ */
virtual void main(int argc, char *argv[]) {
- int cppcast = 1;
SWIG_library_directory("python");
+ int doxygen_translator_flags = 0;
+
for (int i = 1; i < argc; i++) {
if (argv[i]) {
if (strcmp(argv[i], "-interface") == 0) {
@@ -354,42 +326,13 @@ public:
} else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
shadow = 1;
Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-new_repr") == 0) || (strcmp(argv[i], "-newrepr") == 0)) {
- new_repr = 1;
- Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-old_repr") == 0) || (strcmp(argv[i], "-oldrepr") == 0)) {
- new_repr = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-classptr") == 0) {
- classptr = 1;
- Swig_mark_arg(i);
} else if ((strcmp(argv[i], "-noproxy") == 0)) {
shadow = 0;
Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-noproxyimport") == 0)) {
- shadowimport = 0;
- Swig_mark_arg(i);
} else if (strcmp(argv[i], "-keyword") == 0) {
use_kw = 1;
SWIG_cparse_set_compact_default_args(1);
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-classic") == 0) {
- classic = 1;
- modernargs = 0;
- modern = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-cppcast") == 0) {
- cppcast = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nocppcast") == 0) {
- cppcast = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-outputtuple") == 0) {
- outputtuple = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nooutputtuple") == 0) {
- outputtuple = 0;
- Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nortti") == 0) {
nortti = 1;
Swig_mark_arg(i);
@@ -397,31 +340,21 @@ public:
threads = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nothreads") == 0) {
- /* Turn off thread suppor mode */
+ /* Turn off thread support mode */
nothreads = 1;
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-safecstrings") == 0) {
- safecstrings = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nosafecstrings") == 0) {
- safecstrings = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-buildnone") == 0) {
- buildnone = 1;
- nobuildnone = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nobuildnone") == 0) {
- buildnone = 0;
- nobuildnone = 1;
- Swig_mark_arg(i);
} else if (strcmp(argv[i], "-dirvtable") == 0) {
dirvtable = 1;
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nodirvtable") == 0) {
- dirvtable = 0;
+ } else if (strcmp(argv[i], "-doxygen") == 0) {
+ doxygen = 1;
+ scan_doxygen_comments = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-debug-doxygen-translator") == 0) {
+ doxygen_translator_flags |= DoxygenTranslator::debug_translator;
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-fastunpack") == 0) {
- fastunpack = 1;
+ } else if (strcmp(argv[i], "-debug-doxygen-parser") == 0) {
+ doxygen_translator_flags |= DoxygenTranslator::debug_parser;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-nofastunpack") == 0) {
fastunpack = 0;
@@ -429,87 +362,26 @@ public:
} else if (strcmp(argv[i], "-fastproxy") == 0) {
fastproxy = 1;
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nofastproxy") == 0) {
- fastproxy = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-fastquery") == 0) {
- fastquery = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nofastquery") == 0) {
- fastquery = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-fastinit") == 0) {
- fastinit = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nofastinit") == 0) {
- fastinit = 0;
- Swig_mark_arg(i);
} else if (strcmp(argv[i], "-olddefs") == 0) {
olddefs = 1;
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-noolddefs") == 0) {
- olddefs = 0;
- Swig_mark_arg(i);
} else if (strcmp(argv[i], "-castmode") == 0) {
castmode = 1;
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-nocastmode") == 0) {
- castmode = 0;
- Swig_mark_arg(i);
} else if (strcmp(argv[i], "-extranative") == 0) {
extranative = 1;
Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-noextranative") == 0) {
- extranative = 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);
- } else if (strcmp(argv[i], "-noaliasobj0") == 0) {
- aliasobj0 = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-proxydel") == 0) {
- proxydel = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-noproxydel") == 0) {
- proxydel = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-modern") == 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;
Swig_mark_arg(i);
- } else if ((strcmp(argv[i], "-new_vwm") == 0) || (strcmp(argv[i], "-newvwm") == 0)) {
- /* Turn on new value wrapper mpde */
+ } else if (strcmp(argv[i], "-newvwm") == 0) {
+ /* Turn on new value wrapper mode */
+ /* Undocumented option, did have -help text: New value wrapper mode, use only when everything else fails */
Swig_value_wrapper_mode(1);
no_header_file = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-O") == 0) {
- classic = 0;
- modern = 1;
- safecstrings = 0;
- buildnone = 0;
- nobuildnone = 1;
- classptr = 0;
- proxydel = 0;
- fastunpack = 1;
fastproxy = 1;
- fastinit = 1;
- fastquery = 1;
- modernargs = 1;
Wrapper_fast_dispatch_mode_set(1);
Wrapper_virtual_elimination_mode_set(1);
Swig_mark_arg(i);
@@ -528,19 +400,52 @@ public:
} else if (strcmp(argv[i], "-relativeimport") == 0) {
relativeimport = 1;
Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-cppcast") == 0 ||
+ strcmp(argv[i], "-fastinit") == 0 ||
+ strcmp(argv[i], "-fastquery") == 0 ||
+ strcmp(argv[i], "-fastunpack") == 0 ||
+ strcmp(argv[i], "-modern") == 0 ||
+ strcmp(argv[i], "-modernargs") == 0 ||
+ strcmp(argv[i], "-noproxydel") == 0 ||
+ strcmp(argv[i], "-safecstrings") == 0) {
+ Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-aliasobj0") == 0 ||
+ strcmp(argv[i], "-buildnone") == 0 ||
+ strcmp(argv[i], "-classic") == 0 ||
+ strcmp(argv[i], "-classptr") == 0 ||
+ strcmp(argv[i], "-new_repr") == 0 ||
+ strcmp(argv[i], "-new_vwm") == 0 ||
+ strcmp(argv[i], "-newrepr") == 0 ||
+ strcmp(argv[i], "-noaliasobj0") == 0 ||
+ strcmp(argv[i], "-nobuildnone") == 0 ||
+ strcmp(argv[i], "-nocastmode") == 0 ||
+ strcmp(argv[i], "-nocppcast") == 0 ||
+ strcmp(argv[i], "-nodirvtable") == 0 ||
+ strcmp(argv[i], "-noextranative") == 0 ||
+ strcmp(argv[i], "-nofastinit") == 0 ||
+ strcmp(argv[i], "-nofastproxy") == 0 ||
+ strcmp(argv[i], "-nofastquery") == 0 ||
+ strcmp(argv[i], "-nomodern") == 0 ||
+ strcmp(argv[i], "-nomodernargs") == 0 ||
+ strcmp(argv[i], "-noolddefs") == 0 ||
+ strcmp(argv[i], "-nooutputtuple") == 0 ||
+ strcmp(argv[i], "-noproxyimport") == 0 ||
+ strcmp(argv[i], "-nosafecstrings") == 0 ||
+ strcmp(argv[i], "-old_repr") == 0 ||
+ strcmp(argv[i], "-oldrepr") == 0 ||
+ strcmp(argv[i], "-outputtuple") == 0 ||
+ strcmp(argv[i], "-proxydel") == 0) {
+ Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
+ Swig_mark_arg(i);
+ SWIG_exit(EXIT_FAILURE);
}
}
}
- if (py3) {
- /* force disable features that not compatible with Python 3.x */
- classic = 0;
- }
-
- if (cppcast) {
- Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
- }
+ if (doxygen)
+ doxygenTranslator = new PyDocConverter(doxygen_translator_flags);
if (!global_name)
global_name = NewString("cvar");
@@ -556,12 +461,12 @@ public:
* ------------------------------------------------------------ */
virtual int top(Node *n) {
- /* check if directors are enabled for this module. note: this
+ /* check if directors are enabled for this module. note: this
* is a "master" switch, without which no director code will be
* emitted. %feature("director") statements are also required
* to enable directors for individual classes or methods.
*
- * use %module(directors="1") modulename at the start of the
+ * use %module(directors="1") modulename at the start of the
* interface file to enable director generation.
*/
String *mod_docstring = NULL;
@@ -590,19 +495,23 @@ public:
castmode = 1;
}
if (Getattr(options, "nocastmode")) {
- castmode = 0;
+ Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nocastmode");
+ SWIG_exit(EXIT_FAILURE);
}
if (Getattr(options, "extranative")) {
extranative = 1;
}
if (Getattr(options, "noextranative")) {
- extranative = 0;
+ Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "noextranative");
+ SWIG_exit(EXIT_FAILURE);
}
if (Getattr(options, "outputtuple")) {
- outputtuple = 1;
+ Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "outputtuple");
+ SWIG_exit(EXIT_FAILURE);
}
if (Getattr(options, "nooutputtuple")) {
- outputtuple = 0;
+ Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nooutputtuple");
+ SWIG_exit(EXIT_FAILURE);
}
mod_docstring = Getattr(options, "docstring");
package = Getattr(options, "package");
@@ -663,6 +572,7 @@ public:
const_code = NewString("");
methods = NewString("");
+ methods_proxydocs = NewString("");
Swig_banner(f_begin);
@@ -678,26 +588,10 @@ public:
Printf(f_runtime, "#define SWIG_PYTHON_THREADS\n");
}
- if (safecstrings) {
- Printf(f_runtime, "#define SWIG_PYTHON_SAFE_CSTRINGS\n");
- }
-
- if (buildnone) {
- Printf(f_runtime, "#define SWIG_PYTHON_BUILD_NONE\n");
- }
-
- if (nobuildnone) {
- Printf(f_runtime, "#define SWIG_PYTHON_NO_BUILD_NONE\n");
- }
-
if (!dirvtable) {
Printf(f_runtime, "#define SWIG_PYTHON_DIRECTOR_NO_VTABLE\n");
}
- if (outputtuple) {
- Printf(f_runtime, "#define SWIG_PYTHON_OUTPUT_TUPLE\n");
- }
-
if (nortti) {
Printf(f_runtime, "#ifndef SWIG_DIRECTOR_NORTTI\n");
Printf(f_runtime, "#define SWIG_DIRECTOR_NORTTI\n");
@@ -713,46 +607,16 @@ public:
Printf(f_runtime, "#define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS\n");
}
- if (classic) {
- Printf(f_runtime, "#define SWIG_PYTHON_CLASSIC\n");
- }
-
if (builtin) {
Printf(f_runtime, "#define SWIGPYTHON_BUILTIN\n");
}
Printf(f_runtime, "\n");
- Printf(f_header, "#if (PY_VERSION_HEX <= 0x02000000)\n");
- Printf(f_header, "# if !defined(SWIG_PYTHON_CLASSIC)\n");
- Printf(f_header, "# error \"This python version requires swig to be run with the '-classic' option\"\n");
- Printf(f_header, "# endif\n");
+ Printf(f_header, "#ifdef SWIG_TypeQuery\n");
+ Printf(f_header, "# undef SWIG_TypeQuery\n");
Printf(f_header, "#endif\n");
-
- if (modern) {
- Printf(f_header, "#if (PY_VERSION_HEX <= 0x02020000)\n");
- Printf(f_header, "# error \"This python version requires swig to be run with the '-nomodern' option\"\n");
- Printf(f_header, "#endif\n");
- }
-
- if (modernargs) {
- Printf(f_header, "#if (PY_VERSION_HEX <= 0x02020000)\n");
- Printf(f_header, "# error \"This python version requires swig to be run with the '-nomodernargs' option\"\n");
- Printf(f_header, "#endif\n");
- }
-
- if (fastunpack) {
- Printf(f_header, "#ifndef METH_O\n");
- Printf(f_header, "# error \"This python version requires swig to be run with the '-nofastunpack' option\"\n");
- Printf(f_header, "#endif\n");
- }
-
- if (fastquery) {
- Printf(f_header, "#ifdef SWIG_TypeQuery\n");
- Printf(f_header, "# undef SWIG_TypeQuery\n");
- Printf(f_header, "#endif\n");
- Printf(f_header, "#define SWIG_TypeQuery SWIG_Python_TypeQuery\n");
- }
+ Printf(f_header, "#define SWIG_TypeQuery SWIG_Python_TypeQuery\n");
/* Set module name */
@@ -805,184 +669,95 @@ public:
Swig_register_filebyname("shadow", f_shadow);
Swig_register_filebyname("python", f_shadow);
- if (mod_docstring) {
- if (Len(mod_docstring)) {
- const char *triple_double = "\"\"\"";
- // follow PEP257 rules: https://www.python.org/dev/peps/pep-0257/
- // reported by pep257: https://github.com/GreenSteam/pep257
- bool multi_line_ds = Strchr(mod_docstring, '\n') != 0;
- Printv(f_shadow_after_begin, "\n", triple_double, multi_line_ds ? "\n":"", mod_docstring, multi_line_ds ? "\n":"", triple_double, "\n", NIL);
- }
- Delete(mod_docstring);
- mod_docstring = NULL;
- }
-
- Printv(default_import_code, "\nfrom sys import version_info as _swig_python_version_info\n", NULL);
-
- if (!builtin && fastproxy) {
- Printv(default_import_code, "if _swig_python_version_info >= (3, 0, 0):\n", NULL);
- Printf(default_import_code, tab4 "new_instancemethod = lambda func, inst, cls: %s.SWIG_PyInstanceMethod_New(func)\n", module);
- Printv(default_import_code, "else:\n", NULL);
- Printv(default_import_code, tab4, "from new import instancemethod as new_instancemethod\n", NULL);
- }
-
- /* Import the C-extension module. This should be a relative import,
- * since the shadow module may also have been imported by a relative
- * import, and there is thus no guarantee that the C-extension is on
- * sys.path. Relative imports must be explicitly specified from 2.6.0
- * onwards (implicit relative imports will raise a DeprecationWarning
- * in 2.6, and fail in 2.7 onwards), but the relative import syntax
- * isn't available in python 2.4 or earlier, so we have to write some
- * code conditional on the python version.
- *
- * For python 2.7.0 and newer, first determine the shadow wrappers package
- * based on the __name__ it was given by the importer that loaded it.
- * Then construct a name for the module based on the package name and the
- * module name (we know the module name). Use importlib to try and load
- * it. If an attempt to load the module with importlib fails with an
- * ImportError then fallback and try and load just the module name from
- * the global namespace.
- */
- Printv(default_import_code, "if _swig_python_version_info >= (2, 7, 0):\n", NULL);
- Printv(default_import_code, tab4, "def swig_import_helper():\n", NULL);
- Printv(default_import_code, tab8, "import importlib\n", NULL);
- Printv(default_import_code, tab8, "pkg = __name__.rpartition('.')[0]\n", NULL);
- Printf(default_import_code, tab8 "mname = '.'.join((pkg, '%s')).lstrip('.')\n", module);
- Printv(default_import_code, tab8, "try:\n", NULL);
- Printv(default_import_code, tab8, tab4, "return importlib.import_module(mname)\n", NULL);
- Printv(default_import_code, tab8, "except ImportError:\n", NULL);
- Printf(default_import_code, tab8 tab4 "return importlib.import_module('%s')\n", module);
- Printf(default_import_code, tab4 "%s = swig_import_helper()\n", module);
- Printv(default_import_code, tab4, "del swig_import_helper\n", NULL);
- Printv(default_import_code, "elif _swig_python_version_info >= (2, 6, 0):\n", NULL);
- Printv(default_import_code, tab4, "def swig_import_helper():\n", NULL);
- Printv(default_import_code, tab8, "from os.path import dirname\n", NULL);
- Printv(default_import_code, tab8, "import imp\n", NULL);
- Printv(default_import_code, tab8, "fp = None\n", NULL);
- Printv(default_import_code, tab8, "try:\n", NULL);
- Printf(default_import_code, tab4 tab8 "fp, pathname, description = imp.find_module('%s', [dirname(__file__)])\n", module);
- Printf(default_import_code, tab8 "except ImportError:\n");
- /* At here, the module may already loaded, so simply import it. */
- Printf(default_import_code, tab4 tab8 "import %s\n", module);
- Printf(default_import_code, tab4 tab8 "return %s\n", module);
- Printv(default_import_code, tab8 "try:\n", NULL);
- /* imp.load_module() handles fp being None. */
- Printf(default_import_code, tab4 tab8 "_mod = imp.load_module('%s', fp, pathname, description)\n", module);
- Printv(default_import_code, tab8, "finally:\n", NULL);
- Printv(default_import_code, tab4 tab8 "if fp is not None:\n", NULL);
- Printv(default_import_code, tab8 tab8, "fp.close()\n", NULL);
- Printv(default_import_code, tab8, "return _mod\n", NULL);
- Printf(default_import_code, tab4 "%s = swig_import_helper()\n", module);
- Printv(default_import_code, tab4, "del swig_import_helper\n", NULL);
- Printv(default_import_code, "else:\n", NULL);
- Printf(default_import_code, tab4 "import %s\n", module);
-
- if (builtin) {
- /*
- * Pull in all the attributes from the C module.
- *
- * An alternative approach to doing this if/else chain was
- * proposed by Michael Thon. Someone braver than I may try it out.
- * I fear some current swig user may depend on some side effect
- * of from _foo import *
- *
- * for attr in _foo.__all__:
- * globals()[attr] = getattr(_foo, attr)
- *
- */
- Printf(default_import_code, "# pull in all the attributes from %s\n", module);
- Printv(default_import_code, "if __name__.rpartition('.')[0] != '':\n", NULL);
- Printv(default_import_code, tab4, "if _swig_python_version_info >= (2, 7, 0):\n", NULL);
- Printv(default_import_code, tab8, "try:\n", NULL);
- Printf(default_import_code, tab8 tab4 "from .%s import *\n", module);
- Printv(default_import_code, tab8 "except ImportError:\n", NULL);
- Printf(default_import_code, tab8 tab4 "from %s import *\n", module);
- Printv(default_import_code, tab4, "else:\n", NULL);
- Printf(default_import_code, tab8 "from %s import *\n", module);
+ if (!builtin) {
+ /* Import the low-level C/C++ module. This should be a relative import,
+ * since the shadow module may also have been imported by a relative
+ * import, and there is thus no guarantee that the low-level C/C++ module is on
+ * sys.path. Relative imports must be explicitly specified from 2.6.0
+ * onwards (implicit relative imports raised a DeprecationWarning in 2.6,
+ * and fail in 2.7 onwards).
+ *
+ * First check for __package__ which is available from 2.6 onwards, see PEP366.
+ * Next try determine the shadow wrapper's package based on the __name__ it
+ * was given by the importer that loaded it.
+ * If the module is in a package, load the low-level C/C++ module from the
+ * same package, otherwise load it as a global module.
+ */
+ Printv(default_import_code, "# Import the low-level C/C++ module\n", NULL);
+ Printv(default_import_code, "if __package__ or \".\" in __name__:\n", NULL);
+ Printv(default_import_code, tab4, "from . import ", module, "\n", NULL);
Printv(default_import_code, "else:\n", NULL);
- Printf(default_import_code, tab4 "from %s import *\n", module);
- }
-
- /* Delete the _swig_python_version_info symbol since we don't use it elsewhere in the
- * module. */
- Printv(default_import_code, "del _swig_python_version_info\n\n", NULL);
-
- if (modern || !classic) {
- Printv(f_shadow, "try:\n", tab4, "_swig_property = property\n", "except NameError:\n", tab4, "pass # Python < 2.2 doesn't have 'property'.\n\n", NULL);
+ Printv(default_import_code, tab4, "import ", module, "\n", NULL);
+ } else {
+ Printv(default_import_code, "# Pull in all the attributes from the low-level C/C++ module\n", NULL);
+ Printv(default_import_code, "if __package__ or \".\" in __name__:\n", NULL);
+ Printv(default_import_code, tab4, "from .", module, " import *\n", NULL);
+ Printv(default_import_code, "else:\n", NULL);
+ Printv(default_import_code, tab4, "from ", module, " import *\n", NULL);
}
/* Need builtins to qualify names like Exception that might also be
defined in this module (try both Python 3 and Python 2 names) */
Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
- /* if (!modern) */
- /* always needed, a class can be forced to be no-modern, such as an exception */
- {
- // Python-2.2 object hack
- Printv(f_shadow,
- "\n", "def _swig_setattr_nondynamic(self, class_type, name, value, static=1):\n",
- tab4, "if (name == \"thisown\"):\n", tab8, "return self.this.own(value)\n",
- tab4, "if (name == \"this\"):\n", tab8, "if type(value).__name__ == 'SwigPyObject':\n", tab4, tab8, "self.__dict__[name] = value\n",
-#ifdef USE_THISOWN
- tab4, tab8, "if hasattr(value,\"thisown\"):\n", tab8, tab8, "self.__dict__[\"thisown\"] = value.thisown\n", tab4, tab8, "del value.thisown\n",
-#endif
- tab4, tab8, "return\n", tab4, "method = class_type.__swig_setmethods__.get(name, None)\n", tab4, "if method:\n", tab4, tab4, "return method(self, value)\n",
-#ifdef USE_THISOWN
- tab4, "if (not static) or (name == \"thisown\"):\n",
-#else
- tab4, "if (not static):\n",
-#endif
- NIL);
- if (!classic) {
- if (!modern)
- Printv(f_shadow, tab4, tab4, "if _newclass:\n", tab4, NIL);
- Printv(f_shadow, tab4, tab4, "object.__setattr__(self, name, value)\n", NIL);
- if (!modern)
- Printv(f_shadow, tab4, tab4, "else:\n", tab4, NIL);
- }
- if (classic || !modern)
- Printv(f_shadow, tab4, tab4, "self.__dict__[name] = value\n", NIL);
- Printv(f_shadow,
- tab4, "else:\n",
- tab4, tab4, "raise AttributeError(\"You cannot add attributes to %s\" % self)\n\n",
- "\n", "def _swig_setattr(self, class_type, name, value):\n", tab4, "return _swig_setattr_nondynamic(self, class_type, name, value, 0)\n\n", NIL);
-
- Printv(f_shadow,
- "\n", "def _swig_getattr(self, class_type, name):\n",
- tab4, "if (name == \"thisown\"):\n", tab8, "return self.this.own()\n",
- tab4, "method = class_type.__swig_getmethods__.get(name, None)\n",
- tab4, "if method:\n", tab8, "return method(self)\n",
- tab4, "raise AttributeError(\"'%s' object has no attribute '%s'\" % (class_type.__name__, name))\n\n", NIL);
-
- Printv(f_shadow,
- "\n", "def _swig_repr(self):\n",
- tab4, "try:\n", tab8, "strthis = \"proxy of \" + self.this.__repr__()\n",
- tab4, "except __builtin__.Exception:\n", tab8, "strthis = \"\"\n", tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
-
- if (!classic && !modern) {
- Printv(f_shadow,
- "try:\n",
- tab4, "_object = object\n", tab4, "_newclass = 1\n",
- "except __builtin__.Exception:\n",
- tab4, "class _object:\n", tab8, "pass\n", tab4, "_newclass = 0\n\n", NIL);
- }
- }
- if (modern) {
- Printv(f_shadow, "\n", "def _swig_setattr_nondynamic_method(set):\n", tab4, "def set_attr(self, name, value):\n",
+ if (!builtin && fastproxy) {
+ Printf(f_shadow, "\n");
+ Printf(f_shadow, "_swig_new_instance_method = %s.SWIG_PyInstanceMethod_New\n", module);
+ Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module);
+ }
+
+ Printv(f_shadow, "\n",
+ "def _swig_repr(self):\n",
+ tab4, "try:\n",
+ tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
+ tab4, "except __builtin__.Exception:\n",
+ tab4, tab4, "strthis = \"\"\n",
+ tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
+
+ Printv(f_shadow, "\n",
+ "def _swig_setattr_nondynamic_instance_variable(set):\n",
+ tab4, "def set_instance_attr(self, name, value):\n",
#ifdef USE_THISOWN
- tab4, tab4, "if hasattr(self, name) or (name in (\"this\", \"thisown\")):\n",
+ tab4, tab4, "if name in (\"this\", \"thisown\"):\n",
+ tab4, tab4, tab4, "set(self, name, value)\n",
#else
- tab4, tab4, "if (name == \"thisown\"):\n", tab8, tab4, "return self.this.own(value)\n", tab4, tab4, "if hasattr(self, name) or (name == \"this\"):\n",
+ tab4, tab4, "if name == \"thisown\":\n",
+ tab4, tab4, tab4, "self.this.own(value)\n",
+ tab4, tab4, "elif name == \"this\":\n",
+ tab4, tab4, tab4, "set(self, name, value)\n",
#endif
- tab4, tab4, tab4, "set(self, name, value)\n",
- tab4, tab4, "else:\n",
- tab4, tab4, tab4, "raise AttributeError(\"You cannot add attributes to %s\" % self)\n", tab4, "return set_attr\n\n\n", NIL);
- }
+ tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
+ tab4, tab4, tab4, "set(self, name, value)\n",
+ tab4, tab4, "else:\n",
+ tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
+ tab4, "return set_instance_attr\n\n", NIL);
+
+ Printv(f_shadow, "\n",
+ "def _swig_setattr_nondynamic_class_variable(set):\n",
+ tab4, "def set_class_attr(cls, name, value):\n",
+ tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
+ tab4, tab4, tab4, "set(cls, name, value)\n",
+ tab4, tab4, "else:\n",
+ tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
+ tab4, "return set_class_attr\n\n", NIL);
+
+ Printv(f_shadow, "\n",
+ "def _swig_add_metaclass(metaclass):\n",
+ tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
+ tab4, "def wrapper(cls):\n",
+ tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
+ tab4, "return wrapper\n\n", NIL);
+
+ Printv(f_shadow, "\n",
+ "class _SwigNonDynamicMeta(type):\n",
+ tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
+ tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
+ "\n", NIL);
+
+ Printv(f_shadow, "\n", NIL);
if (directorsEnabled()) {
- // Try loading weakref.proxy, which is only available in Python 2.1 and higher
- Printv(f_shadow,
- "try:\n", tab4, "import weakref\n", tab4, "weakref_proxy = weakref.proxy\n", "except __builtin__.Exception:\n", tab4, "weakref_proxy = lambda x: x\n", "\n\n", NIL);
+ Printv(f_shadow, "import weakref\n\n", NIL);
}
}
// Include some information in the code
@@ -1001,9 +776,11 @@ public:
Printf(f_wrappers, "#endif\n");
Append(const_code, "static swig_const_info swig_const_table[] = {\n");
Append(methods, "static PyMethodDef SwigMethods[] = {\n");
+ Append(methods_proxydocs, "static PyMethodDef SwigMethods_proxydocs[] = {\n");
/* the method exported for replacement of new.instancemethod in Python 3 */
add_pyinstancemethod_new();
+ add_pystaticmethod_new();
if (builtin) {
SwigType *s = NewString("SwigPyObject");
@@ -1025,6 +802,9 @@ public:
Append(methods, "\t { NULL, NULL, 0, NULL }\n");
Append(methods, "};\n");
Printf(f_wrappers, "%s\n", methods);
+ Append(methods_proxydocs, "\t { NULL, NULL, 0, NULL }\n");
+ Append(methods_proxydocs, "};\n");
+ Printf(f_wrappers, "%s\n", methods_proxydocs);
if (builtin) {
Dump(f_builtins, f_wrappers);
@@ -1049,20 +829,37 @@ public:
if (shadow) {
Swig_banner_target_lang(f_shadow_py, "#");
- if (!modern && !classic) {
- Printv(f_shadow, "# This file is compatible with both classic and new-style classes.\n", NIL);
+
+ if (mod_docstring) {
+ if (Len(mod_docstring)) {
+ const char *triple_double = "\"\"\"";
+ // follow PEP257 rules: https://www.python.org/dev/peps/pep-0257/
+ // reported by pep257: https://github.com/GreenSteam/pep257
+ bool multi_line_ds = Strchr(mod_docstring, '\n') != 0;
+ Printv(f_shadow_py, "\n", triple_double, multi_line_ds ? "\n":"", mod_docstring, multi_line_ds ? "\n":"", triple_double, "\n", NIL);
+ }
+ Delete(mod_docstring);
+ mod_docstring = NULL;
}
+
if (Len(f_shadow_begin) > 0)
Printv(f_shadow_py, "\n", f_shadow_begin, "\n", NIL);
+
+ Printv(f_shadow_py, "\nfrom sys import version_info as _swig_python_version_info\n", NULL);
+ Printv(f_shadow_py, "if _swig_python_version_info < (2, 7, 0):\n", NULL);
+ Printv(f_shadow_py, tab4, "raise RuntimeError(\"Python 2.7 or later required\")\n\n", NULL);
+
if (Len(f_shadow_after_begin) > 0)
- Printv(f_shadow_py, f_shadow_after_begin, "\n", NIL);
+ Printv(f_shadow_py, f_shadow_after_begin, "\n", NIL);
+
if (moduleimport) {
Replaceall(moduleimport, "$module", module);
- Printv(f_shadow_py, "\n", moduleimport, "\n", NIL);
+ Printv(f_shadow_py, moduleimport, "\n", NIL);
} else {
Printv(f_shadow_py, default_import_code, NIL);
}
- Printv(f_shadow_py, f_shadow, "\n", NIL);
+
+ Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
Delete(f_shadow_py);
}
@@ -1109,12 +906,36 @@ public:
* ------------------------------------------------------------ */
int add_pyinstancemethod_new() {
String *name = NewString("SWIG_PyInstanceMethod_New");
- Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_O, NULL},\n", name, name);
+ String *line = NewString("");
+ Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
+ Append(methods, line);
+ if (fastproxy) {
+ Append(methods_proxydocs, line);
+ }
+ Delete(line);
Delete(name);
return 0;
}
/* ------------------------------------------------------------
+ * Emit the wrapper for PyStaticMethod_New to MethodDef array.
+ * This wrapper is used to ensure the correct documentation is
+ * generated for static methods when using -fastproxy
+ * ------------------------------------------------------------ */
+ int add_pystaticmethod_new() {
+ if (fastproxy) {
+ String *name = NewString("SWIG_PyStaticMethod_New");
+ String *line = NewString("");
+ Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
+ Append(methods, line);
+ Append(methods_proxydocs, line);
+ Delete(line);
+ Delete(name);
+ }
+ return 0;
+ }
+
+ /* ------------------------------------------------------------
* subpkg_tail()
*
* Return the name of 'other' package relative to 'base'.
@@ -1269,14 +1090,9 @@ public:
Printf(out, "import %s%s%s%s\n", apkg, *Char(apkg) ? "." : "", pfx, mod);
Delete(apkg);
} else {
- Printf(out, "from sys import version_info as _swig_python_version_info\n");
- Printf(out, "if _swig_python_version_info >= (2, 7, 0):\n");
if (py3_rlen1)
- Printf(out, tab4 "from . import %.*s\n", py3_rlen1, rpkg);
- Printf(out, tab4 "from .%s import %s%s\n", rpkg, pfx, mod);
- Printf(out, "else:\n");
- Printf(out, tab4 "import %s%s%s%s\n", rpkg, *Char(rpkg) ? "." : "", pfx, mod);
- Printf(out, "del _swig_python_version_info\n");
+ Printf(out, "from . import %.*s\n", py3_rlen1, rpkg);
+ Printf(out, "from .%s import %s%s\n", rpkg, pfx, mod);
Delete(rpkg);
}
return out;
@@ -1393,18 +1209,18 @@ public:
Node *options = Getattr(mod, "options");
String *pkg = options ? Getattr(options, "package") : 0;
- if (shadowimport) {
- if (!options || (!Getattr(options, "noshadow") && !Getattr(options, "noproxy"))) {
- String *_import = import_directive_string(package, pkg, modname, "_");
- if (!GetFlagAttr(f_shadow_imports, _import)) {
- String *import = import_directive_string(package, pkg, modname);
- Printf(builtin ? f_shadow_after_begin : f_shadow, "%s", import);
- Delete(import);
- SetFlag(f_shadow_imports, _import);
- }
- Delete(_import);
+
+ if (!options || (!Getattr(options, "noshadow") && !Getattr(options, "noproxy"))) {
+ String *_import = import_directive_string(package, pkg, modname, "_");
+ if (!GetFlagAttr(f_shadow_imports, _import)) {
+ String *import = import_directive_string(package, pkg, modname);
+ Printf(builtin ? f_shadow_after_begin : f_shadow, "%s", import);
+ Delete(import);
+ SetFlag(f_shadow_imports, _import);
}
+ Delete(_import);
}
+
}
}
return Language::importDirective(n);
@@ -1648,37 +1464,76 @@ public:
bool have_docstring(Node *n) {
String *str = Getattr(n, "feature:docstring");
- return (str && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
+ return ((str && Len(str) > 0)
+ || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"))
+ || (doxygen && doxygenTranslator->hasDocumentation(n))
+ );
}
/* ------------------------------------------------------------
- * docstring()
+ * build_combined_docstring()
*
- * Get the docstring text, stripping off {} if necessary,
- * and enclose in triple double quotes. If autodoc is also
- * set then it will build a combined docstring.
+ * Build the full docstring which may be a combination of the
+ * explicit docstring and autodoc string or, if none of them
+ * is specified, obtained by translating Doxygen comment to
+ * Python.
+ *
+ * Return new string to be deleted by caller (never NIL but
+ * may be empty if there is no docstring).
* ------------------------------------------------------------ */
- String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool use_triple = true) {
- String *str = Getattr(n, "feature:docstring");
- bool have_ds = (str && Len(str) > 0);
- bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
- const char *triple_double = use_triple ? "\"\"\"" : "";
- String *autodoc = NULL;
- String *doc = NULL;
-
- if (have_ds) {
- char *t = Char(str);
+ String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) {
+ String *docstr = Getattr(n, "feature:docstring");
+ if (docstr && Len(docstr)) {
+ docstr = Copy(docstr);
+ char *t = Char(docstr);
if (*t == '{') {
- Delitem(str, 0);
- Delitem(str, DOH_END);
+ Delitem(docstr, 0);
+ Delitem(docstr, DOH_END);
+ }
+ }
+
+ if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
+ String *autodoc = make_autodoc(n, ad_type, low_level);
+ if (autodoc && Len(autodoc) > 0) {
+ if (docstr && Len(docstr)) {
+ Append(autodoc, "\n");
+ Append(autodoc, docstr);
+ }
+
+ String *tmp = autodoc;
+ autodoc = docstr;
+ docstr = tmp;
}
+
+ Delete(autodoc);
}
- if (have_auto) {
- autodoc = make_autodoc(n, ad_type);
- have_auto = (autodoc && Len(autodoc) > 0);
+ if (!docstr || !Len(docstr)) {
+ if (doxygen) {
+ docstr = Getattr(n, "python:docstring");
+ if (!docstr && doxygenTranslator->hasDocumentation(n)) {
+ docstr = doxygenTranslator->getDocumentation(n, 0);
+
+ // Avoid rebuilding it again the next time: notice that we can't do
+ // this for the combined doc string as autodoc part of it depends on
+ // the sym:name of the node and it is changed while handling it, so
+ // the cached results become incorrect. But Doxygen docstring only
+ // depends on the comment which is not going to change, so we can
+ // safely cache it.
+ Setattr(n, "python:docstring", Copy(docstr));
+ } else {
+ // Must copy here since if the docstring is multi-line, the String*
+ // here will get Deleted below, which is bad if it is a pointer to
+ // the cached object!
+ docstr = Copy(docstr);
+ }
+ }
}
+
+ if (!docstr)
+ docstr = NewString("");
+
// If there is more than one line then make docstrings like this:
//
// """
@@ -1687,82 +1542,79 @@ public:
// """
//
// otherwise, put it all on a single line
+ if (Strchr(docstr, '\n')) {
+ String *tmp = NewString("");
+ Append(tmp, "\n");
+ Append(tmp, indent_docstring(docstr, indent));
+ Append(tmp, indent);
+ Delete(docstr);
+ docstr = tmp;
+ }
+
+ return docstr;
+ }
+
+ /* ------------------------------------------------------------
+ * docstring()
+ *
+ * Get the docstring text, stripping off {} if necessary,
+ * and enclose in triple double quotes. If autodoc is also
+ * set then it will build a combined docstring.
+ * ------------------------------------------------------------ */
+
+ String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool low_level = false) {
+ String *docstr = build_combined_docstring(n, ad_type, indent, low_level);
+ if (!Len(docstr))
+ return docstr;
+
+ // Notice that all comments are created as raw strings (prefix "r"),
+ // because '\' is used often in comments, but may break Python module from
+ // loading. For example, in doxy comment one may write path in quotes:
//
- if (have_auto && have_ds) { // Both autodoc and docstring are present
- doc = NewString("");
- Printv(doc, triple_double, "\n",
- indent_docstring(autodoc, indent), "\n",
- indent_docstring(str, indent), indent, triple_double, NIL);
- } else if (!have_auto && have_ds) { // only docstring
- if (Strchr(str, '\n') == 0) {
- doc = NewStringf("%s%s%s", triple_double, str, triple_double);
- } else {
- doc = NewString("");
- Printv(doc, triple_double, "\n", indent_docstring(str, indent), indent, triple_double, NIL);
- }
- } else if (have_auto && !have_ds) { // only autodoc
- if (Strchr(autodoc, '\n') == 0) {
- doc = NewStringf("%s%s%s", triple_double, autodoc, triple_double);
- } else {
- doc = NewString("");
- Printv(doc, triple_double, "\n", indent_docstring(autodoc, indent), indent, triple_double, NIL);
- }
- } else
- doc = NewString("");
+ // This is path to file "C:\x\file.txt"
+ //
+ // Python will not load the module with such comment because of illegal
+ // escape '\x'. '\' may additionally appear in verbatim or htmlonly sections
+ // of doxygen doc, Latex expressions, ...
+ String *doc = NewString("");
+ Append(doc, "r\"\"\"");
+ Append(doc, docstr);
+ Append(doc, "\"\"\"");
+ Delete(docstr);
- // Save the generated strings in the parse tree in case they are used later
- // by post processing tools
- Setattr(n, "python:docstring", doc);
- Setattr(n, "python:autodoc", autodoc);
return doc;
- }
+ }
/* ------------------------------------------------------------
* cdocstring()
*
* Get the docstring text as it would appear in C-language
- * source code.
+ * source code (but without quotes around it).
* ------------------------------------------------------------ */
- String *cdocstring(Node *n, autodoc_t ad_type)
- {
- String *ds = docstring(n, ad_type, "", false);
+ String *cdocstring(Node *n, autodoc_t ad_type, bool low_level = false) {
+ String *ds = build_combined_docstring(n, ad_type, "", low_level);
Replaceall(ds, "\\", "\\\\");
Replaceall(ds, "\"", "\\\"");
Replaceall(ds, "\n", "\\n\"\n\t\t\"");
return ds;
}
- virtual String *makeParameterName(Node *n, Parm *p, int arg_num, bool = false) const {
- // For the keyword arguments, we want to preserve the names as much as possible,
- // so we only minimally rename them in Swig_name_make(), e.g. replacing "keyword"
- // with "_keyword" if they have any name at all.
- if (check_kwargs(n)) {
- String *name = Getattr(p, "name");
- if (name)
- return Swig_name_make(p, 0, name, 0, 0);
- }
-
- // For the other cases use the general function which replaces arguments whose
- // names clash with keywords with (less useful) "argN".
- return Language::makeParameterName(n, p, arg_num);
- }
-
/* -----------------------------------------------------------------------------
* addMissingParameterNames()
*
* For functions that have not had nameless parameters set in the Language class.
*
- * Inputs:
+ * Inputs:
* plist - entire parameter list
- * arg_offset - argument number for first parameter
+ * arg_num - the number to start from when naming arguments
* Side effects:
* The "lname" attribute in each parameter in plist will be contain a parameter name
* ----------------------------------------------------------------------------- */
- void addMissingParameterNames(Node *n, ParmList *plist, int arg_offset) {
+ void addMissingParameterNames(Node *n, ParmList *plist, int arg_num) {
Parm *p = plist;
- int i = arg_offset;
+ int i = arg_num;
while (p) {
if (!Getattr(p, "lname")) {
String *name = makeParameterName(n, p, i);
@@ -1779,10 +1631,11 @@ public:
*
* Generate the documentation for the function parameters
* Parameters:
+ * arg_num: The number to start assigning unnamed arguments from
* func_annotation: Function annotation support
* ------------------------------------------------------------ */
- String *make_autodocParmList(Node *n, bool showTypes, bool calling = false, bool func_annotation = false) {
+ String *make_autodocParmList(Node *n, bool showTypes, int arg_num = 1, bool calling = false, bool func_annotation = false) {
String *doc = NewString("");
String *pdocs = 0;
@@ -1790,15 +1643,6 @@ public:
Parm *p;
Parm *pnext;
-
- // Normally we start counting auto-generated argument names from 1, but we should do it from 2
- // if the first argument is "self", i.e. if we're handling a non-static member function.
- int arg_num = 1;
- if (is_wrapping_class()) {
- if (Cmp(Getattr(n, "storage"), "static") != 0)
- arg_num++;
- }
-
if (calling)
func_annotation = false;
@@ -1811,8 +1655,7 @@ public:
return doc;
}
- for (p = plist; p; p = pnext, arg_num++) {
-
+ for (p = plist; p; p = pnext) {
String *tm = Getattr(p, "tmap:in");
if (tm) {
pnext = Getattr(p, "tmap:in:next");
@@ -1833,12 +1676,21 @@ public:
value = Getattr(p, "tmap:doc:value");
}
+ // Skip the "self" argument - it is added to the parameter list automatically
+ // and shouldn't be included in the Parameters block
+ if (Getattr(p, "self")) {
+ continue;
+ }
+
// Note: the generated name should be consistent with that in kwnames[]
String *made_name = 0;
if (!name) {
name = made_name = makeParameterName(n, p, arg_num);
}
+ // Increment the argument number once we are sure this is a real argument to count
+ arg_num++;
+
type = type ? type : Getattr(p, "type");
value = value ? value : Getattr(p, "value");
@@ -1867,13 +1719,24 @@ public:
}
// Write the function annotation
if (func_annotation)
- Printf(doc, ": '%s'", type_str);
+ Printf(doc, ": \"%s\"", type_str);
// Write default value
if (value && !calling) {
String *new_value = convertValue(value, Getattr(p, "type"));
+ if (new_value) {
+ value = new_value;
+ } else {
+ // Even if the value is not representable in the target language, still use it in the documentation, for compatibility with the previous SWIG versions
+ // and because it can still be useful to see the C++ expression there.
+ Node *lookup = Swig_symbol_clookup(value, 0);
+ if (lookup)
+ value = Getattr(lookup, "sym:name");
+ }
+ Printf(doc, "=%s", value);
+
if (new_value)
- Printf(doc, "=%s", new_value);
+ Delete(new_value);
}
Delete(type_str);
Delete(made_name);
@@ -1895,8 +1758,9 @@ public:
* and use it directly.
* ------------------------------------------------------------ */
- String *make_autodoc(Node *n, autodoc_t ad_type) {
+ String *make_autodoc(Node *n, autodoc_t ad_type, bool low_level = false) {
int extended = 0;
+ bool first_func = true;
// If the function is overloaded then this function is called
// for the last one. Rewind to the first so the docstrings are
// in order.
@@ -1933,10 +1797,24 @@ public:
}
if (!skipAuto) {
- String *symname = Getattr(n, "sym:name");
+ /* Check if a documentation name was given for either the low-level C API or high-level Python shadow API */
+ String *symname = Getattr(n, low_level ? "doc:low:name" : "doc:high:name");
+ if (!symname) {
+ symname = Getattr(n, "sym:name");
+ }
+
SwigType *type = Getattr(n, "type");
String *type_str = NULL;
+ // If the function has default arguments, then that documentation covers this version too
+ if (Getattr(n, "defaultargs") != NULL) {
+ n = Getattr(n, "sym:nextSibling");
+ continue;
+ }
+
+ if (!first_func)
+ Append(doc, "\n");
+
if (type) {
if (Strcmp(type, "void") == 0) {
type_str = NULL;
@@ -1946,6 +1824,21 @@ public:
}
}
+ /* Treat the low-level C API functions for getting/setting variables as methods for documentation purposes */
+ String *kind = Getattr(n, "kind");
+ if (kind && Strcmp(kind, "variable") == 0) {
+ if (ad_type == AUTODOC_FUNC) {
+ ad_type = AUTODOC_METHOD;
+ }
+ }
+ /* Treat destructors as methods for documentation purposes */
+ String *nodeType = Getattr(n, "nodeType");
+ if (nodeType && Strcmp(nodeType, "destructor") == 0) {
+ if (ad_type == AUTODOC_FUNC) {
+ ad_type = AUTODOC_METHOD;
+ }
+ }
+
switch (ad_type) {
case AUTODOC_CLASS:
{
@@ -1959,9 +1852,9 @@ public:
Delete(rname);
} else {
if (CPlusPlus) {
- Printf(doc, "Proxy of C++ %s class.", real_classname);
+ Printf(doc, "Proxy of C++ %s class.", SwigType_namestr(real_classname));
} else {
- Printf(doc, "Proxy of C %s struct.", real_classname);
+ Printf(doc, "Proxy of C %s struct.", SwigType_namestr(real_classname));
}
}
}
@@ -1969,10 +1862,10 @@ public:
break;
case AUTODOC_CTOR:
if (Strcmp(class_name, symname) == 0) {
- String *paramList = make_autodocParmList(n, showTypes);
+ String *paramList = make_autodocParmList(n, showTypes, 2);
Printf(doc, "__init__(");
if (showTypes)
- Printf(doc, "%s ", getClassName());
+ Printf(doc, "%s ", class_name);
if (Len(paramList))
Printf(doc, "self, %s) -> %s", paramList, class_name);
else
@@ -1983,7 +1876,7 @@ public:
case AUTODOC_DTOR:
if (showTypes)
- Printf(doc, "__del__(%s self)", getClassName());
+ Printf(doc, "__del__(%s self)", class_name);
else
Printf(doc, "__del__(self)");
break;
@@ -2001,36 +1894,134 @@ public:
break;
case AUTODOC_METHOD:
- String *paramList = make_autodocParmList(n, showTypes);
- Printf(doc, "%s(", symname);
- if (showTypes)
- Printf(doc, "%s ", class_name);
- if (Len(paramList))
- Printf(doc, "self, %s)", paramList);
- else
- Printf(doc, "self)");
- if (type_str)
- Printf(doc, " -> %s", type_str);
+ {
+ String *paramList = make_autodocParmList(n, showTypes, 2);
+ Printf(doc, "%s(", symname);
+ if (showTypes)
+ Printf(doc, "%s ", class_name);
+ if (Len(paramList))
+ Printf(doc, "self, %s)", paramList);
+ else
+ Printf(doc, "self)");
+ if (type_str)
+ Printf(doc, " -> %s", type_str);
+ }
+ break;
+
+ case AUTODOC_CONST:
+ // There is no autodoc support for constants currently, this enum
+ // element only exists to allow calling docstring() with it.
+ return NULL;
+ case AUTODOC_VAR:
+ // Variables can also be documented (e.g. through the property() function in python)
+ Printf(doc, "%s", symname);
+ if (showTypes) {
+ String *type = Getattr(n, "tmap:doc:type");
+ if (!type)
+ type = Getattr(n, "membervariableHandler:type");
+ if (!type)
+ type = Getattr(n, "type");
+ Printf(doc, " : %s", type);
+ }
break;
}
Delete(type_str);
- }
- if (extended) {
- String *pdocs = Getattr(n, "feature:pdocs");
- if (pdocs) {
- Printv(doc, "\n", pdocs, NULL);
+
+ // Special case: wrapper functions to get a variable should have no parameters.
+ // Because the node is re-used for the setter and getter, the feature:pdocs field will
+ // exist for the getter function, so explicitly avoid printing parameters in this case.
+ bool variable_getter = kind && Strcmp(kind, "variable") == 0 && Getattr(n, "memberget");
+ if (extended && ad_type != AUTODOC_VAR && !variable_getter) {
+ String *pdocs = Getattr(n, "feature:pdocs");
+ if (pdocs) {
+ Printv(doc, "\n", pdocs, NULL);
+ }
}
}
// if it's overloaded then get the next decl and loop around again
n = Getattr(n, "sym:nextSibling");
if (n)
- Append(doc, "\n");
+ first_func = false;
}
return doc;
}
/* ------------------------------------------------------------
+ * convertIntegerValue()
+ *
+ * Check if string v is an integer and can be represented in
+ * Python. If so, return an appropriate Python representation,
+ * otherwise (or if we are unsure), return NIL.
+ * ------------------------------------------------------------ */
+ String *convertIntegerValue(String *v, SwigType *resolved_type) {
+ const char *const s = Char(v);
+ char *end;
+ String *result = NIL;
+
+ // Check if this is an integer number in any base.
+ errno = 0;
+ long value = strtol(s, &end, 0);
+ if (errno == ERANGE || end == s)
+ return NIL;
+
+ if (*end != '\0') {
+ // If there is a suffix after the number, we can safely ignore "l"
+ // and (provided the number is unsigned) "u", and also combinations of
+ // these, but not anything else.
+ for (char *p = end; *p != '\0'; ++p) {
+ switch (*p) {
+ case 'l':
+ case 'L':
+ break;
+ case 'u':
+ case 'U':
+ if (value < 0)
+ return NIL;
+ break;
+ default:
+ return NIL;
+ }
+ }
+ }
+ // So now we are certain that we are indeed dealing with an integer
+ // that has a representation as long given by value.
+
+ // Restrict to guaranteed supported range in Python, see maxint docs: https://docs.python.org/2/library/sys.html#sys.maxint
+ // Don't do this pointless check when long is 32 bits or smaller as strtol will have already failed with ERANGE
+#if LONG_MAX > PYTHON_INT_MAX || LONG_MIN < PYTHON_INT_MIN
+ if (value > PYTHON_INT_MAX || value < PYTHON_INT_MIN) {
+ return NIL;
+ }
+#endif
+
+ if (Cmp(resolved_type, "bool") == 0)
+ // Allow integers as the default value for a bool parameter.
+ return NewString(value ? "True" : "False");
+
+ if (value == 0)
+ return NewString(SwigType_ispointer(resolved_type) ? "None" : "0");
+
+ // v may still be octal or hexadecimal:
+ const char *p = s;
+ if (*p == '+' || *p == '-')
+ ++p;
+ if (*p == '0' && *(p+1) != 'x' && *(p+1) != 'X') {
+ // This must have been an octal number. This is the only case we
+ // cannot use in Python directly, since Python 2 and 3 use non-
+ // compatible representations.
+ result = NewString(*s == '-' ? "int(\"-" : "int(\"");
+ String *octal_string = NewStringWithSize(p, (int) (end - p));
+ Append(result, octal_string);
+ Append(result, "\", 8)");
+ Delete(octal_string);
+ return result;
+ }
+ result = *end == '\0' ? Copy(v) : NewStringWithSize(s, (int) (end - s));
+ return result;
+ }
+
+ /* ------------------------------------------------------------
* convertDoubleValue()
*
* Check if the given string looks like a decimal floating point constant
@@ -2040,6 +2031,7 @@ public:
const char *const s = Char(v);
char *end;
+ errno = 0;
double value = strtod(s, &end);
(void) value;
if (errno != ERANGE && end != s) {
@@ -2068,7 +2060,7 @@ public:
// Avoid unnecessary string allocation in the common case when we don't
// need to remove any suffix.
- return *end == '\0' ? v : NewStringWithSize(s, (int)(end - s));
+ return *end == '\0' ? Copy(v) : NewStringWithSize(s, (int)(end - s));
}
return NIL;
@@ -2078,109 +2070,24 @@ public:
* convertValue()
*
* Check if string v can be a Python value literal or a
- * constant. Return NIL if it isn't.
+ * constant. Return an equivalent Python representation,
+ * or NIL if it isn't, or we are unsure.
* ------------------------------------------------------------ */
String *convertValue(String *v, SwigType *type) {
const char *const s = Char(v);
- char *end;
String *result = NIL;
- bool fail = false;
- SwigType *resolved_type = 0;
-
- // Check if this is a number in any base.
- long value = strtol(s, &end, 0);
- (void) value;
- if (end != s) {
- if (errno == ERANGE) {
- // There was an overflow, we could try representing the value as Python
- // long integer literal, but for now don't bother with it.
- fail = true;
- } else {
- if (*end != '\0') {
- // If there is a suffix after the number, we can safely ignore any
- // combination of "l" and "u", but not anything else (again, stuff like
- // "LL" could be handled, but we don't bother to do it currently).
- bool seen_long = false;
- for (char * p = end; *p != '\0'; ++p) {
- switch (*p) {
- case 'l':
- case 'L':
- // Bail out on "LL".
- if (seen_long) {
- fail = true;
- break;
- }
- seen_long = true;
- break;
-
- case 'u':
- case 'U':
- break;
-
- default:
- // Except that our suffix could actually be the fractional part of
- // a floating point number, so we still have to check for this.
- result = convertDoubleValue(v);
- }
- }
- }
-
- if (!fail) {
- // Allow integers as the default value for a bool parameter.
- resolved_type = SwigType_typedef_resolve_all(type);
- if (Cmp(resolved_type, "bool") == 0) {
- result = NewString(value ? "True" : "False");
- } else {
- // Deal with the values starting with 0 first as they can be octal or
- // hexadecimal numbers or even pointers.
- if (s[0] == '0') {
- if (Len(v) == 1) {
- // This is just a lone 0, but it needs to be represented differently
- // in Python depending on whether it's a zero or a null pointer.
- if (SwigType_ispointer(resolved_type))
- result = NewString("None");
- else
- result = v;
- } else if (s[1] == 'x' || s[1] == 'X') {
- // This must have been a hex number, we can use it directly in Python,
- // so nothing to do here.
- } else {
- // This must have been an octal number, we have to change its prefix
- // to be "0o" in Python 3 only (and as long as we still support Python
- // 2.5, this can't be done unconditionally).
- if (py3) {
- if (end - s > 1) {
- result = NewString("0o");
- Append(result, NewStringWithSize(s + 1, (int)(end - s - 1)));
- }
- }
- }
- }
-
- // Avoid unnecessary string allocation in the common case when we don't
- // need to remove any suffix.
- if (!result)
- result = *end == '\0' ? v : NewStringWithSize(s, (int)(end - s));
- }
- }
- }
- }
+ SwigType *resolved_type = SwigType_typedef_resolve_all(type);
- // Check if this is a floating point number (notice that it wasn't
- // necessarily parsed as a long above, consider e.g. ".123").
- if (!fail && !result) {
+ result = convertIntegerValue(v, resolved_type);
+ if (!result) {
result = convertDoubleValue(v);
if (!result) {
- if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
+ if (Strcmp(v, "true") == 0)
result = NewString("True");
- else if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
+ else if (Strcmp(v, "false") == 0)
result = NewString("False");
- else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) {
- if (!resolved_type)
- resolved_type = SwigType_typedef_resolve_all(type);
+ else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
result = SwigType_ispointer(resolved_type) ? NewString("None") : NewString("0");
- }
-
// This could also be an enum type, default value of which could be
// representable in Python if it doesn't include any scope (which could,
// but currently is not, translated).
@@ -2188,7 +2095,7 @@ public:
Node *lookup = Swig_symbol_clookup(v, 0);
if (lookup) {
if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0)
- result = Getattr(lookup, "sym:name");
+ result = Copy(Getattr(lookup, "sym:name"));
}
}
}
@@ -2235,10 +2142,12 @@ public:
if (Getattr(p, "tmap:default"))
return false;
- if (String *value = Getattr(p, "value")) {
- String *type = Getattr(p, "type");
- if (!convertValue(value, type))
+ String *value = Getattr(p, "value");
+ if (value) {
+ String *convertedValue = convertValue(value, Getattr(p, "type"));
+ if (!convertedValue)
return false;
+ Delete(convertedValue);
}
}
@@ -2250,7 +2159,7 @@ public:
* is_real_overloaded()
*
* Check if the function is overloaded, but not just have some
- * siblings generated due to the original function have
+ * siblings generated due to the original function having
* default arguments.
* ------------------------------------------------------------ */
bool is_real_overloaded(Node *n) {
@@ -2263,7 +2172,7 @@ public:
while (i) {
Node *nn = Getattr(i, "defaultargs");
if (nn != h) {
- /* Check if overloaded function has defaultargs and
+ /* Check if overloaded function has defaultargs and
* pointed to the first overloaded. */
return true;
}
@@ -2279,13 +2188,16 @@ public:
* Generate parameter list for Python functions or methods,
* reuse make_autodocParmList() to do so.
* ------------------------------------------------------------ */
- String *make_pyParmList(Node *n, bool in_class, bool is_calling, int kw) {
- /* Get the original function for a defaultargs copy,
+ String *make_pyParmList(Node *n, bool in_class, bool is_calling, int kw, bool has_self_for_count = false) {
+ /* Get the original function for a defaultargs copy,
* see default_arguments() in parser.y. */
Node *nn = Getattr(n, "defaultargs");
if (nn)
n = nn;
+ Parm *parms = Getattr(n, "parms");
+ int varargs = parms ? emit_isvarargs(parms) : 0;
+
/* We prefer to explicitly list all parameters of the C function in the
generated Python code as this makes the function more convenient to use,
however in some cases we must replace the real parameters list with just
@@ -2295,8 +2207,9 @@ public:
2. We were explicitly asked to use the "compact" arguments form.
3. We were explicitly asked to use default args from C via the "python:cdefaultargs" feature.
4. One of the default argument values can't be represented in Python.
+ 5. Varargs that haven't been forced to use a fixed number of arguments with %varargs.
*/
- if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || GetFlag(n, "feature:python:cdefaultargs") || !is_representable_as_pyargs(n)) {
+ if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || GetFlag(n, "feature:python:cdefaultargs") || !is_representable_as_pyargs(n) || varargs) {
String *parms = NewString("");
if (in_class)
Printf(parms, "self, ");
@@ -2308,7 +2221,7 @@ public:
bool funcanno = py3 ? true : false;
String *params = NewString("");
- String *_params = make_autodocParmList(n, false, is_calling, funcanno);
+ String *_params = make_autodocParmList(n, false, ((in_class || has_self_for_count)? 2 : 1), is_calling, funcanno);
if (in_class) {
Printf(params, "self");
@@ -2387,7 +2300,7 @@ public:
* ------------------------------------------------------------ */
bool have_addtofunc(Node *n) {
- return have_pythonappend(n) || have_pythonprepend(n) || have_docstring(n);
+ return have_pythonappend(n) || have_pythonprepend(n);
}
@@ -2437,21 +2350,28 @@ public:
void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) {
String *parms = make_pyParmList(n, false, false, kw);
String *callParms = make_pyParmList(n, false, true, kw);
- /* Make a wrapper function to insert the code into */
- Printv(f_dest, "\ndef ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
- if (have_docstring(n))
- Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4), "\n", NIL);
- if (have_pythonprepend(n))
- Printv(f_dest, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
- if (have_pythonappend(n)) {
- Printv(f_dest, tab4 "val = ", funcCall(name, callParms), "\n", NIL);
- Printv(f_dest, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
- Printv(f_dest, tab4 "return val\n", NIL);
- } else {
- Printv(f_dest, tab4 "return ", funcCall(name, callParms), "\n", NIL);
+
+ // Callbacks need the C function in order to extract the pointer from the swig_ptr: string
+ bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
+
+ if (!fast || olddefs) {
+ /* Make a wrapper function to insert the code into */
+ Printv(f_dest, "\n", "def ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
+ if (have_docstring(n))
+ Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4, true), "\n", NIL);
+ if (have_pythonprepend(n))
+ Printv(f_dest, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
+ if (have_pythonappend(n)) {
+ Printv(f_dest, tab4 "val = ", funcCall(name, callParms), "\n", NIL);
+ Printv(f_dest, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
+ Printv(f_dest, tab4 "return val\n", NIL);
+ } else {
+ Printv(f_dest, tab4 "return ", funcCall(name, callParms), "\n", NIL);
+ }
}
- if (!have_addtofunc(n)) {
+ // Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first.
+ if (fast) {
/* If there is no addtofunc directive then just assign from the extension module (for speed up) */
Printv(f_dest, name, " = ", module, ".", name, "\n", NIL);
}
@@ -2475,36 +2395,64 @@ public:
* add_method()
* ------------------------------------------------------------ */
- void add_method(String *name, String *function, int kw, Node *n = 0, int funpack= 0, int num_required= -1, int num_arguments = -1) {
+ void add_method(String *name, String *function, int kw, Node *n = 0, int funpack = 0, int num_required = -1, int num_arguments = -1) {
+ String * meth_str = NewString("");
if (!kw) {
- if (n && funpack) {
+ if (funpack) {
if (num_required == 0 && num_arguments == 0) {
- Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_NOARGS, ", name, function);
+ Printf(meth_str, "\t { \"%s\", %s, METH_NOARGS, ", name, function);
} else if (num_required == 1 && num_arguments == 1) {
- Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_O, ", name, function);
+ Printf(meth_str, "\t { \"%s\", %s, METH_O, ", name, function);
} else {
- Printf(methods, "\t { (char *)\"%s\", %s, METH_VARARGS, ", name, function);
+ Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
}
} else {
- Printf(methods, "\t { (char *)\"%s\", %s, METH_VARARGS, ", name, function);
+ Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
}
} else {
- Printf(methods, "\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS, ", name, function);
+ // Cast via void(*)(void) to suppress GCC -Wcast-function-type warning.
+ // Python should always call the function correctly, but the Python C API
+ // requires us to store it in function pointer of a different type.
+ Printf(meth_str, "\t { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, ", name, function);
+ }
+ Append(methods, meth_str);
+ if (fastproxy) {
+ Append(methods_proxydocs, meth_str);
}
+ Delete(meth_str);
if (!n) {
Append(methods, "NULL");
+ if (fastproxy) {
+ Append(methods_proxydocs, "NULL");
+ }
} else if (have_docstring(n)) {
- String *ds = cdocstring(n, AUTODOC_FUNC);
- Printf(methods, "(char *)\"%s\"", ds);
+ /* Use the low-level docstring here since this is the docstring that will be used for the C API */
+ String *ds = cdocstring(n, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC, true);
+ Printf(methods, "\"%s\"", ds);
+ if (fastproxy) {
+ /* In the fastproxy case, we must also record the high-level docstring for use in the Python shadow API */
+ Delete(ds);
+ ds = cdocstring(n, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC);
+ Printf(methods_proxydocs, "\"%s\"", ds);
+ }
Delete(ds);
} else if (Getattr(n, "feature:callback")) {
- Printf(methods, "(char *)\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
+ Printf(methods, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
+ if (fastproxy) {
+ Printf(methods_proxydocs, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
+ }
} else {
Append(methods, "NULL");
+ if (fastproxy) {
+ Append(methods_proxydocs, "NULL");
+ }
}
Append(methods, "},\n");
+ if (fastproxy) {
+ Append(methods_proxydocs, "},\n");
+ }
}
/* ------------------------------------------------------------
@@ -2519,12 +2467,24 @@ public:
String *tmp = NewString("");
String *dispatch;
- const char *dispatch_code = funpack ? "return %s(self, argc, argv);" : "return %s(self, args);";
+
+ const char *dispatch_call = funpack ? "%s(self, argc, argv);" : (builtin_ctor ? "%s(self, args, NULL);" : "%s(self, args);");
+ String *dispatch_code = NewStringf("return %s", dispatch_call);
if (castmode) {
dispatch = Swig_overload_dispatch_cast(n, dispatch_code, &maxargs);
} else {
- dispatch = Swig_overload_dispatch(n, dispatch_code, &maxargs);
+ String *fastdispatch_code;
+ if (builtin_ctor)
+ fastdispatch_code = NewStringf("int retval = %s\nif (retval == 0 || !SWIG_Python_TypeErrorOccurred(NULL)) return retval;\nSWIG_fail;", dispatch_call);
+ else
+ fastdispatch_code = NewStringf("PyObject *retobj = %s\nif (!SWIG_Python_TypeErrorOccurred(retobj)) return retobj;\nSWIG_fail;", dispatch_call);
+ if (!CPlusPlus) {
+ Insert(fastdispatch_code, 0, "{\n");
+ Append(fastdispatch_code, "\n}");
+ }
+ dispatch = Swig_overload_dispatch(n, dispatch_code, &maxargs, fastdispatch_code);
+ Delete(fastdispatch_code);
}
/* Generate a dispatch wrapper for all overloaded functions */
@@ -2533,7 +2493,8 @@ public:
String *symname = Getattr(n, "sym:name");
String *wname = Swig_name_wrapper(symname);
- Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args) {", NIL);
+ const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : "";
+ Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
Wrapper_add_local(f, "argc", "Py_ssize_t argc");
Printf(tmp, "PyObject *argv[%d] = {0}", maxargs + 1);
@@ -2541,9 +2502,14 @@ public:
if (!fastunpack) {
Wrapper_add_local(f, "ii", "Py_ssize_t ii");
- if (maxargs - (add_self ? 1 : 0) > 0)
- Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n");
- Append(f->code, "argc = args ? PyObject_Length(args) : 0;\n");
+
+ if (maxargs - (add_self ? 1 : 0) > 0) {
+ Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n");
+ Append(f->code, "argc = PyObject_Length(args);\n");
+ } else {
+ Append(f->code, "argc = args ? PyObject_Length(args) : 0;\n");
+ }
+
if (add_self)
Append(f->code, "argv[0] = self;\n");
Printf(f->code, "for (ii = 0; (ii < %d) && (ii < argc); ii++) {\n", add_self ? maxargs - 1 : maxargs);
@@ -2553,7 +2519,7 @@ public:
Append(f->code, "argc++;\n");
} else {
String *iname = Getattr(n, "sym:name");
- Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args,\"%s\",0,%d,argv%s))) SWIG_fail;\n", iname, maxargs, add_self ? "+1" : "");
+ Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args, \"%s\", 0, %d, argv%s))) SWIG_fail;\n", iname, maxargs, add_self ? "+1" : "");
if (add_self)
Append(f->code, "argv[0] = self;\n");
else
@@ -2566,8 +2532,8 @@ public:
if (GetFlag(n, "feature:python:maybecall")) {
Append(f->code, "fail:\n");
- Append(f->code, "Py_INCREF(Py_NotImplemented);\n");
- Append(f->code, "return Py_NotImplemented;\n");
+ Append(f->code, " Py_INCREF(Py_NotImplemented);\n");
+ Append(f->code, " return Py_NotImplemented;\n");
} else {
Node *sibl = n;
while (Getattr(sibl, "sym:previousSibling"))
@@ -2579,7 +2545,7 @@ public:
Delete(fulldecl);
} while ((sibl = Getattr(sibl, "sym:nextSibling")));
Append(f->code, "fail:\n");
- Printf(f->code, "SWIG_SetErrorMsg(PyExc_NotImplementedError,"
+ Printf(f->code, " SWIG_Python_RaiseOrModifyTypeError("
"\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes);
Printf(f->code, "return %s;\n", builtin_ctor ? "-1" : "0");
Delete(protoTypes);
@@ -2596,6 +2562,7 @@ public:
}
DelWrapper(f);
Delete(dispatch);
+ Delete(dispatch_code);
Delete(tmp);
Delete(wname);
}
@@ -2688,12 +2655,12 @@ public:
builtin_self = false;
else
builtin_ctor = true;
+ Delete(mrename);
}
bool director_class = (getCurrentClass() && Swig_directorclass(getCurrentClass()));
bool add_self = builtin_self && (!builtin_ctor || director_class);
bool builtin_getter = (builtin && GetFlag(n, "memberget"));
bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter);
- bool over_varargs = false;
char const *self_param = builtin ? "self" : "SWIGUNUSEDPARM(self)";
char const *wrap_return = builtin_ctor ? "int " : "PyObject *";
String *linkage = NewString("SWIGINTERN ");
@@ -2742,9 +2709,10 @@ public:
Append(wname, overname);
}
+ const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : "";
if (!allow_kwargs || overname) {
if (!varargs) {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
} else {
Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs) {", NIL);
}
@@ -2761,53 +2729,33 @@ public:
}
if (!builtin || !in_class || tuple_arguments > 0) {
if (!allow_kwargs) {
- Append(parse_args, " if (!PyArg_ParseTuple(args,(char *)\"");
+ Append(parse_args, " if (!PyArg_ParseTuple(args, \"");
} else {
- Append(parse_args, " if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)\"");
- Append(arglist, ",kwnames");
+ Append(parse_args, " if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"");
+ Append(arglist, ", kwnames");
}
}
- if (overname) {
- String *over_varargs_attr = Getattr(n, "python:overvarargs");
- if (!over_varargs_attr) {
- for (Node *sibling = n; sibling; sibling = Getattr(sibling, "sym:nextSibling")) {
- if (emit_isvarargs(Getattr(sibling, "parms"))) {
- over_varargs = true;
- break;
- }
- }
- over_varargs_attr = NewString(over_varargs ? "1" : "0");
- for (Node *sibling = n; sibling; sibling = Getattr(sibling, "sym:nextSibling"))
- Setattr(sibling, "python:overvarargs", over_varargs_attr);
- }
- if (Strcmp(over_varargs_attr, "0") != 0)
- over_varargs = true;
- }
+ bool over_varargs = emit_isvarargs_function(n);
- int funpack = modernargs && fastunpack && !varargs && !over_varargs && !allow_kwargs;
+ int funpack = fastunpack && !varargs && !over_varargs && !allow_kwargs;
int noargs = funpack && (tuple_required == 0 && tuple_arguments == 0);
int onearg = funpack && (tuple_required == 1 && tuple_arguments == 1);
- if (builtin && funpack && !overname && !builtin_ctor &&
- !(GetFlag(n, "feature:compactdefaultargs") && (tuple_arguments > tuple_required || varargs))) {
- String *argattr = NewStringf("%d", tuple_arguments);
- Setattr(n, "python:argcount", argattr);
- Delete(argattr);
+ if (builtin && funpack && !overname && !builtin_ctor) {
+ int compactdefargs = ParmList_is_compactdefargs(l);
+ if (!(compactdefargs && (tuple_arguments > tuple_required || varargs))) {
+ String *argattr = NewStringf("%d", tuple_arguments);
+ Setattr(n, "python:argcount", argattr);
+ Delete(argattr);
+ }
}
/* Generate code for argument marshalling */
if (funpack) {
- if (overname) {
- if (aliasobj0) {
- Append(f->code, "#define obj0 (swig_obj[0])\n");
- }
- } else if (num_arguments) {
+ if (num_arguments > 0 && !overname) {
sprintf(source, "PyObject *swig_obj[%d]", num_arguments);
Wrapper_add_localv(f, "swig_obj", source, NIL);
- if (aliasobj0) {
- Append(f->code, "#define obj0 (swig_obj[0])\n");
- }
}
}
@@ -2852,7 +2800,7 @@ public:
sprintf(source, "obj%d", builtin_ctor ? i + 1 : i);
if (parse_from_tuple) {
- Putc(',', arglist);
+ Printf(arglist, ", ");
if (i == num_required)
Putc('|', parse_args); /* Optional argument separator */
}
@@ -2860,7 +2808,7 @@ public:
/* Keyword argument handling */
if (allow_kwargs && parse_from_tuple) {
String *name = makeParameterName(n, p, i + 1);
- Printf(kwargs, "(char *) \"%s\",", name);
+ Printf(kwargs, " (char *)\"%s\", ", name);
Delete(name);
}
@@ -2925,12 +2873,12 @@ public:
/* finish argument marshalling */
Append(kwargs, " NULL }");
if (allow_kwargs) {
- Printv(f->locals, " char * kwnames[] = ", kwargs, ";\n", NIL);
+ Printv(f->locals, " char * kwnames[] = ", kwargs, ";\n", NIL);
}
if (builtin && !funpack && in_class && tuple_arguments == 0) {
Printf(parse_args, " if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, \"%s takes no arguments\");\n", iname);
- } else if (use_parse || allow_kwargs || !modernargs) {
+ } else if (use_parse || allow_kwargs) {
Printf(parse_args, ":%s\"", iname);
Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
funpack = 0;
@@ -2940,28 +2888,25 @@ public:
Clear(f->def);
if (overname) {
if (noargs) {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
} else {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **swig_obj) {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
}
Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments);
} else {
- if (noargs) {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
- } else {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
- }
- if (onearg && !builtin_ctor) {
+ int is_tp_call = Equal(Getattr(n, "feature:python:slot"), "tp_call");
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
+ if (onearg && !builtin_ctor && !is_tp_call) {
Printf(parse_args, "if (!args) SWIG_fail;\n");
Append(parse_args, "swig_obj[0] = args;\n");
} else if (!noargs) {
- Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,swig_obj)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
+ Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args, \"%s\", %d, %d, swig_obj)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
} else if (noargs) {
- Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args,\"%s\",%d,%d,0)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
+ Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args, \"%s\", %d, %d, 0)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments);
}
}
} else {
- Printf(parse_args, "if(!PyArg_UnpackTuple(args,(char *)\"%s\",%d,%d", iname, num_fixed_arguments, tuple_arguments);
+ Printf(parse_args, "if (!PyArg_UnpackTuple(args, \"%s\", %d, %d", iname, num_fixed_arguments, tuple_arguments);
Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
}
}
@@ -3026,9 +2971,9 @@ public:
}
/* if the object is a director, and the method call originated from its
- * underlying python object, resolve the call by going up the c++
- * inheritance chain. otherwise try to resolve the method in python.
- * without this check an infinite loop is set up between the director and
+ * underlying python object, resolve the call by going up the c++
+ * inheritance chain. otherwise try to resolve the method in python.
+ * without this check an infinite loop is set up between the director and
* shadow class method calls.
*/
@@ -3122,7 +3067,7 @@ public:
// base class pointers!
/* New addition to unwrap director return values so that the original
- * python object is returned instead.
+ * python object is returned instead.
*/
#if 1
int unwrap = 0;
@@ -3204,21 +3149,18 @@ public:
if (need_cleanup) {
Printv(f->code, cleanup, NIL);
}
- if (builtin_ctor)
+ if (builtin_ctor) {
Printv(f->code, " return -1;\n", NIL);
- else
- Printv(f->code, " return NULL;\n", NIL);
-
-
- if (funpack) {
- if (aliasobj0) {
- Append(f->code, "#if defined(obj0)\n");
- Append(f->code, "#undef obj0\n");
- Append(f->code, "#endif\n");
+ } else {
+ if (GetFlag(n, "feature:python:maybecall")) {
+ Append(f->code, " PyErr_Clear();\n");
+ Append(f->code, " Py_INCREF(Py_NotImplemented);\n");
+ Append(f->code, " return Py_NotImplemented;\n");
+ } else {
+ Printv(f->code, " return NULL;\n", NIL);
}
}
-
Append(f->code, "}\n");
/* Substitute the cleanup code */
@@ -3244,9 +3186,10 @@ public:
DelWrapper(f);
f = NewWrapper();
if (funpack) {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **swig_obj) {", NIL);
+ // Note: funpack is currently always false for varargs
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
} else {
- Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL);
+ Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
}
Wrapper_add_local(f, "resultobj", builtin_ctor ? "int resultobj" : "PyObject *resultobj");
Wrapper_add_local(f, "varargs", "PyObject *varargs");
@@ -3309,6 +3252,10 @@ public:
Delete(h);
}
Setattr(h, "getter", "SwigPyObject_get___dict__");
+ if (!Getattr(h, "doc")) {
+ Setattr(n, "doc:high:name", Getattr(n, "name"));
+ Setattr(h, "doc", cdocstring(n, AUTODOC_VAR));
+ }
}
if (builtin_getter) {
@@ -3323,6 +3270,12 @@ public:
}
Setattr(h, "getter", wrapper_name);
Delattr(n, "memberget");
+ if (!Getattr(h, "doc")) {
+ Setattr(n, "doc:high:name", Getattr(n, "name"));
+ String *ds = cdocstring(n, AUTODOC_VAR);
+ Setattr(h, "doc", ds);
+ Delete(ds);
+ }
}
if (builtin_setter) {
String *memname = Getattr(n, "membervariableHandler:sym:name");
@@ -3336,6 +3289,12 @@ public:
}
Setattr(h, "setter", wrapper_name);
Delattr(n, "memberset");
+ if (!Getattr(h, "doc")) {
+ Setattr(n, "doc:high:name", Getattr(n, "name"));
+ String *ds = cdocstring(n, AUTODOC_VAR);
+ Setattr(h, "doc", ds);
+ Delete(ds);
+ }
}
if (in_class && builtin) {
@@ -3356,7 +3315,7 @@ public:
closure_name = Copy(wrapper_name);
}
if (func_type) {
- String *s = NewStringf("(%s) %s", func_type, closure_name);
+ String *s = NewStringf("%s", closure_name);
Delete(closure_name);
closure_name = s;
}
@@ -3413,7 +3372,17 @@ public:
Python dictionary. */
if (!have_globals) {
- Printf(f_init, "\t PyDict_SetItemString(md,(char *)\"%s\", SWIG_globals());\n", global_name);
+ Printf(f_init, "\t globals = SWIG_globals();\n");
+ Printf(f_init, "\t if (!globals) {\n");
+ Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Failure to create SWIG globals.\");\n");
+ Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
+ Printf(f_init, "\t return NULL;\n");
+ Printf(f_init, "#else\n");
+ Printf(f_init, "\t return;\n");
+ Printf(f_init, "#endif\n");
+ Printf(f_init, "\t }\n");
+ Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", globals);\n", global_name);
+ Printf(f_init, "\t Py_DECREF(globals);\n");
if (builtin)
Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name);
have_globals = 1;
@@ -3501,9 +3470,9 @@ public:
Wrapper_print(getf, f_wrappers);
/* Now add this to the variable linking mechanism */
- Printf(f_init, "\t SWIG_addvarlink(SWIG_globals(),(char *)\"%s\",%s, %s);\n", iname, vargetname, varsetname);
+ Printf(f_init, "\t SWIG_addvarlink(globals, \"%s\", %s, %s);\n", iname, vargetname, varsetname);
if (builtin && shadow && !assignable && !in_class) {
- Printf(f_init, "\t PyDict_SetItemString(md, (char *)\"%s\", PyObject_GetAttrString(SWIG_globals(), \"%s\"));\n", iname, iname);
+ Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", PyObject_GetAttrString(globals, \"%s\"));\n", iname, iname);
Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", iname);
}
Delete(vargetname);
@@ -3529,7 +3498,7 @@ public:
/* Note, that we need special handling for function pointers, as
* SwigType_base(fptr) does not return the underlying pointer-to-function
* type but the return-type of function. */
- if(!SwigType_isfunction(uqtype) && !SwigType_isfunctionpointer(uqtype)) {
+ if (!SwigType_isfunction(uqtype) && !SwigType_isfunctionpointer(uqtype)) {
SwigType *basetype = SwigType_base(uqtype);
result = SwigType_isclass(basetype) != 0;
Delete(basetype);
@@ -3595,15 +3564,7 @@ public:
Printf(f_wrappers, "SWIGINTERN PyObject *%s_swigconstant(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", iname);
Printf(f_wrappers, tab2 "PyObject *module;\n", tm);
Printf(f_wrappers, tab2 "PyObject *d;\n");
- if (modernargs) {
- if (fastunpack) {
- Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args,(char *)\"swigconstant\", 1, 1,&module)) return NULL;\n");
- } else {
- Printf(f_wrappers, tab2 "if (!PyArg_UnpackTuple(args,(char *)\"swigconstant\", 1, 1,&module)) return NULL;\n");
- }
- } else {
- Printf(f_wrappers, tab2 "if (!PyArg_ParseTuple(args,(char *)\"O:swigconstant\", &module)) return NULL;\n");
- }
+ Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args, \"swigconstant\", 1, 1, &module)) return NULL;\n");
Printf(f_wrappers, tab2 "d = PyModule_GetDict(module);\n");
Printf(f_wrappers, tab2 "if (!d) return NULL;\n");
Printf(f_wrappers, tab2 "%s\n", tm);
@@ -3612,7 +3573,7 @@ public:
// Register the method in SwigMethods array
String *cname = NewStringf("%s_swigconstant", iname);
- add_method(cname, cname, 0);
+ add_method(cname, cname, 0, 0, 1, 1, 1);
Delete(cname);
} else {
Printf(f_init, "%s\n", tm);
@@ -3630,27 +3591,28 @@ public:
}
if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+ String *f_s;
if (!in_class) {
- if(needs_swigconstant(n)) {
- Printv(f_shadow, "\n",NIL);
- Printv(f_shadow, module, ".", iname, "_swigconstant(",module,")\n", NIL);
- }
- Printv(f_shadow, iname, " = ", module, ".", iname, "\n", NIL);
+ f_s = f_shadow;
} else {
- if (!(Getattr(n, "feature:python:callback"))) {
- if(needs_swigconstant(n)) {
- Printv(f_shadow_stubs, "\n",NIL);
- Printv(f_shadow_stubs, module, ".", iname, "_swigconstant(", module, ")\n", NIL);
- }
- Printv(f_shadow_stubs, iname, " = ", module, ".", iname, "\n", NIL);
+ f_s = Getattr(n, "feature:python:callback") ? NIL : f_shadow_stubs;
+ }
+
+ if (f_s) {
+ if (needs_swigconstant(n)) {
+ Printv(f_s, "\n",NIL);
+ Printv(f_s, module, ".", iname, "_swigconstant(",module,")\n", NIL);
}
+ Printv(f_s, iname, " = ", module, ".", iname, "\n", NIL);
+ if (have_docstring(n))
+ Printv(f_s, docstring(n, AUTODOC_CONST, tab4), "\n", NIL);
}
}
return SWIG_OK;
}
- /* ------------------------------------------------------------
+ /* ------------------------------------------------------------
* nativeWrapper()
* ------------------------------------------------------------ */
@@ -3685,7 +3647,7 @@ public:
/* ---------------------------------------------------------------
* classDirectorMethod()
*
- * Emit a virtual director method to pass a method call on to the
+ * Emit a virtual director method to pass a method call on to the
* underlying Python object.
* ** Moved down due to gcc-2.96 internal error **
* --------------------------------------------------------------- */
@@ -3722,7 +3684,7 @@ public:
Wrapper *w = NewWrapper();
String *call;
String *basetype = Getattr(parent, "classtype");
- String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
+ String *target = Swig_method_decl(0, decl, classname, parms, 0);
call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
@@ -3735,7 +3697,7 @@ public:
/* constructor header */
{
- String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
+ String *target = Swig_method_decl(0, decl, classname, parms, 1);
Printf(f_directors_h, " %s;\n", target);
Delete(target);
}
@@ -3857,7 +3819,7 @@ public:
if (shadow) {
if (builtin) {
String *rname = SwigType_namestr(real_classname);
- Printf(builtin_methods, " { \"__disown__\", (PyCFunction) Swig::Director::swig_pyobj_disown< %s >, METH_NOARGS, \"\" },\n", rname);
+ Printf(builtin_methods, " { \"__disown__\", Swig::Director::swig_pyobj_disown< %s >, METH_NOARGS, \"\" },\n", rname);
Delete(rname);
} else {
String *symname = Getattr(n, "sym:name");
@@ -3869,7 +3831,7 @@ public:
Printv(f_shadow, tab8, "self.this.disown()\n", NIL);
#endif
Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL);
- Printv(f_shadow, tab8, "return weakref_proxy(self)\n", NIL);
+ Printv(f_shadow, tab8, "return weakref.proxy(self)\n", NIL);
Delete(mrename);
}
}
@@ -3937,7 +3899,7 @@ public:
String *mname = SwigType_manglestr(rname);
String *pmname = SwigType_manglestr(pname);
String *templ = NewStringf("SwigPyBuiltin_%s", mname);
- int funpack = modernargs && fastunpack;
+ int funpack = fastunpack;
static String *tp_new = NewString("PyType_GenericNew");
Printv(f_init, " SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);\n", NIL);
@@ -4003,9 +3965,10 @@ public:
const char *setter_closure = setter ? funpack ? "SwigPyBuiltin_FunpackSetterClosure" : "SwigPyBuiltin_SetterClosure" : "0";
String *gspair = NewStringf("%s_%s_getset", symname, memname);
Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0");
- String *entry =
- NewStringf("{ (char *) \"%s\", (getter) %s, (setter) %s, (char *)\"%s.%s\", (void *) &%s }\n", memname, getter_closure,
- setter_closure, name, memname, gspair);
+ String *doc = Getattr(mgetset, "doc");
+ if (!doc)
+ doc = NewStringf("%s.%s", name, memname);
+ String *entry = NewStringf("{ (char *)\"%s\", %s, %s, (char *)\"%s\", &%s }", memname, getter_closure, setter_closure, doc, gspair);
if (GetFlag(mgetset, "static")) {
Printf(f, "static PyGetSetDef %s_def = %s;\n", gspair, entry);
Printf(f_init, "static_getset = SwigPyStaticVar_new_getset(metatype, &%s_def);\n", gspair);
@@ -4017,7 +3980,7 @@ public:
Delete(gspair);
Delete(entry);
}
- Printv(f, getset_def, " {NULL, NULL, NULL, NULL, NULL} /* Sentinel */\n", "};\n\n", NIL);
+ Printv(f, getset_def, " { NULL, NULL, NULL, NULL, NULL } /* Sentinel */\n", "};\n\n", NIL);
// Rich compare function
Hash *richcompare = Getattr(n, "python:richcompare");
@@ -4126,7 +4089,16 @@ public:
Printv(f, "#else\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags), "tp_flags");
Printv(f, "#endif\n", NIL);
- printSlot(f, quoted_tp_doc_str, "tp_doc");
+ if (have_docstring(n)) {
+ String *ds = cdocstring(n, AUTODOC_CLASS);
+ String *tp_doc = NewString("");
+ Printf(tp_doc, "\"%s\"", ds);
+ Delete(ds);
+ printSlot(f, tp_doc, "tp_doc");
+ Delete(tp_doc);
+ } else {
+ printSlot(f, quoted_tp_doc_str, "tp_doc");
+ }
printSlot(f, getSlot(n, "feature:python:tp_traverse"), "tp_traverse", "traverseproc");
printSlot(f, getSlot(n, "feature:python:tp_clear"), "tp_clear", "inquiry");
printSlot(f, getSlot(n, "feature:python:tp_richcompare", richcompare_func), "tp_richcompare", "richcmpfunc");
@@ -4152,9 +4124,7 @@ public:
printSlot(f, getSlot(n, "feature:python:tp_subclasses"), "tp_subclasses", "PyObject *");
printSlot(f, getSlot(n, "feature:python:tp_weaklist"), "tp_weaklist", "PyObject *");
printSlot(f, getSlot(n, "feature:python:tp_del"), "tp_del", "destructor");
- Printv(f, "#if PY_VERSION_HEX >= 0x02060000\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_version_tag"), "tp_version_tag", "int");
- Printv(f, "#endif\n", NIL);
Printv(f, "#if PY_VERSION_HEX >= 0x03040000\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_finalize"), "tp_finalize", "destructor");
Printv(f, "#endif\n", NIL);
@@ -4162,9 +4132,7 @@ public:
printSlot(f, getSlot(n, "feature:python:tp_allocs"), "tp_allocs", "Py_ssize_t");
printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t");
printSlot(f, getSlot(n, "feature:python:tp_maxalloc"), "tp_maxalloc", "Py_ssize_t");
- Printv(f, "#if PY_VERSION_HEX >= 0x02050000\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev");
- Printv(f, "#endif\n", NIL);
printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next");
Printv(f, "#endif\n", NIL);
Printf(f, " },\n");
@@ -4230,9 +4198,7 @@ public:
printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_true_divide", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_floor_divide"), "nb_inplace_floor_divide", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_true_divide", "binaryfunc");
- Printv(f, "#if PY_VERSION_HEX >= 0x02050000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_index"), "nb_index", "unaryfunc");
- Printv(f, "#endif\n", NIL);
Printv(f, "#if PY_VERSION_HEX >= 0x03050000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_matrix_multiply"), "nb_matrix_multiply", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_matrix_multiply"), "nb_inplace_matrix_multiply", "binaryfunc");
@@ -4276,10 +4242,8 @@ public:
printSlot(f, getSlot(n, "feature:python:bf_getsegcount"), "bf_getsegcount", "segcountproc");
printSlot(f, getSlot(n, "feature:python:bf_getcharbuffer"), "bf_getcharbuffer", "charbufferproc");
Printv(f, "#endif\n", NIL);
- Printv(f, "#if PY_VERSION_HEX >= 0x02060000\n", NIL);
printSlot(f, getSlot(n, "feature:python:bf_getbuffer"), "bf_getbuffer", "getbufferproc");
printSlot(f, getSlot(n, "feature:python:bf_releasebuffer"), "bf_releasebuffer", "releasebufferproc");
- Printv(f, "#endif\n", NIL);
Printf(f, " },\n");
// PyObject *ht_name, *ht_slots, *ht_qualname;
@@ -4349,8 +4313,6 @@ public:
}
virtual int classHandler(Node *n) {
- int oldclassic = classic;
- int oldmodern = modern;
File *f_shadow_file = f_shadow;
Node *base_node = NULL;
@@ -4360,19 +4322,6 @@ public:
have_constructor = 0;
have_repr = 0;
- if (GetFlag(n, "feature:classic")) {
- classic = 1;
- modern = 0;
- }
- if (GetFlag(n, "feature:modern")) {
- classic = 0;
- modern = 1;
- }
- if (GetFlag(n, "feature:exceptionclass")) {
- classic = 1;
- modern = 0;
- }
-
class_name = Getattr(n, "sym:name");
real_classname = Getattr(n, "name");
@@ -4438,9 +4387,9 @@ public:
if (builtin) {
if (have_docstring(n)) {
- String *str = cdocstring(n, AUTODOC_CLASS);
- Setattr(n, "feature:python:tp_doc", str);
- Delete(str);
+ String *ds = cdocstring(n, AUTODOC_CLASS);
+ Setattr(n, "feature:python:tp_doc", ds);
+ Delete(ds);
} else {
String *name = Getattr(n, "name");
String *rname = add_explicit_scope(SwigType_namestr(name));
@@ -4448,52 +4397,37 @@ public:
Delete(rname);
}
} else {
+ if (!py3) {
+ if (GetFlag(n, "feature:python:nondynamic"))
+ Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL);
+ }
Printv(f_shadow, "class ", class_name, NIL);
if (Len(base_class)) {
Printf(f_shadow, "(%s)", base_class);
} else {
- if (!classic) {
- Printf(f_shadow, modern ? "(object)" : "(_object)");
- }
if (GetFlag(n, "feature:exceptionclass")) {
Printf(f_shadow, "(Exception)");
+ } else {
+ Printf(f_shadow, "(object");
+ Printf(f_shadow, py3 && GetFlag(n, "feature:python:nondynamic") ? ", metaclass=_SwigNonDynamicMeta" : "", ")");
+ Printf(f_shadow, ")");
}
}
Printf(f_shadow, ":\n");
+
+ // write docstrings if requested
if (have_docstring(n)) {
String *str = docstring(n, AUTODOC_CLASS, tab4);
if (str && Len(str))
Printv(f_shadow, tab4, str, "\n\n", NIL);
}
- if (!modern) {
- Printv(f_shadow, tab4, "__swig_setmethods__ = {}\n", NIL);
- if (Len(base_class)) {
- Printv(f_shadow, tab4, "for _s in [", base_class, "]:\n", tab8, "__swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))\n", NIL);
- }
-
- if (!GetFlag(n, "feature:python:nondynamic")) {
- Printv(f_shadow, tab4, "__setattr__ = lambda self, name, value: _swig_setattr(self, ", class_name, ", name, value)\n", NIL);
- } else {
- Printv(f_shadow, tab4, "__setattr__ = lambda self, name, value: _swig_setattr_nondynamic(self, ", class_name, ", name, value)\n", NIL);
- }
-
- Printv(f_shadow, tab4, "__swig_getmethods__ = {}\n", NIL);
- if (Len(base_class)) {
- Printv(f_shadow, tab4, "for _s in [", base_class, "]:\n", tab8, "__swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))\n", NIL);
- }
-
- Printv(f_shadow, tab4, "__getattr__ = lambda self, name: _swig_getattr(self, ", class_name, ", name)\n", NIL);
- } else {
- Printv(f_shadow, tab4, "thisown = _swig_property(lambda x: x.this.own(), ", "lambda x, v: x.this.own(v), doc='The membership flag')\n", NIL);
- /* Add static attribute */
- if (GetFlag(n, "feature:python:nondynamic")) {
- Printv(f_shadow_file,
- tab4, "__setattr__ = _swig_setattr_nondynamic_method(object.__setattr__)\n",
- tab4, "class __metaclass__(type):\n", tab4, tab4, "__setattr__ = _swig_setattr_nondynamic_method(type.__setattr__)\n", NIL);
- }
+ Printv(f_shadow, tab4, "thisown = property(lambda x: x.this.own(), ", "lambda x, v: x.this.own(v), doc=\"The membership flag\")\n", NIL);
+ /* Add static attribute */
+ if (GetFlag(n, "feature:python:nondynamic")) {
+ Printv(f_shadow_file, tab4, "__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n", NIL);
}
}
}
@@ -4544,20 +4478,12 @@ public:
} else {
Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
Printv(f_wrappers, " PyObject *obj;\n", NIL);
- if (modernargs) {
- if (fastunpack) {
- Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args,(char *)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL);
- } else {
- Printv(f_wrappers, " if (!PyArg_UnpackTuple(args,(char *)\"swigregister\", 1, 1,&obj)) return NULL;\n", NIL);
- }
- } else {
- Printv(f_wrappers, " if (!PyArg_ParseTuple(args,(char *)\"O:swigregister\", &obj)) return NULL;\n", NIL);
- }
+ Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args, \"swigregister\", 1, 1, &obj)) return NULL;\n", NIL);
Printv(f_wrappers,
" SWIG_TypeNewClientData(SWIGTYPE", SwigType_manglestr(ct), ", SWIG_NewClientData(obj));\n", " return SWIG_Py_Void();\n", "}\n\n", NIL);
String *cname = NewStringf("%s_swigregister", class_name);
- add_method(cname, cname, 0);
+ add_method(cname, cname, 0, 0, 1, 1, 1);
Delete(cname);
}
Delete(smart);
@@ -4567,7 +4493,7 @@ public:
if (!builtin)
Printv(f_shadow_file, "\n", tab4, "def __init__(self, *args, **kwargs):\n", tab8, "raise AttributeError(\"", "No constructor defined",
(Getattr(n, "abstracts") ? " - class is abstract" : ""), "\")\n", NIL);
- } else if (fastinit && !builtin) {
+ } else if (!builtin) {
Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
Printv(f_wrappers, " return SWIG_Python_InitShadowInstance(args);\n", "}\n\n", NIL);
@@ -4578,11 +4504,7 @@ public:
if (!have_repr && !builtin) {
/* Supply a repr method for this class */
String *rname = SwigType_namestr(real_classname);
- if (new_repr) {
- Printv(f_shadow_file, tab4, "__repr__ = _swig_repr\n", NIL);
- } else {
- Printv(f_shadow_file, tab4, "def __repr__(self):\n", tab8, "return \"<C ", rname, " instance at %p>\" % (self.this,)\n", NIL);
- }
+ Printv(f_shadow_file, tab4, "__repr__ = _swig_repr\n", NIL);
Delete(rname);
}
@@ -4594,35 +4516,12 @@ public:
builtin_tp_init = 0;
}
- /* Now emit methods */
- if (!builtin)
- Printv(f_shadow_file, f_shadow, NIL);
-
- /* Now the Ptr class */
- if (classptr && !builtin) {
- Printv(f_shadow_file, "\nclass ", class_name, "Ptr(", class_name, "):\n", tab4, "def __init__(self, this):\n", NIL);
- if (!modern) {
- Printv(f_shadow_file,
- tab8, "try:\n", tab8, tab4, "self.this.append(this)\n",
- tab8, "except __builtin__.Exception:\n", tab8, tab4, "self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL);
- } else {
- Printv(f_shadow_file,
- tab8, "try:\n", tab8, tab4, "self.this.append(this)\n",
- tab8, "except __builtin__.Exception:\n", tab8, tab4, "self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL);
- }
- }
-
if (!builtin) {
- if (fastproxy) {
- List *shadow_list = Getattr(n, "shadow_methods");
- for (int i = 0; i < Len(shadow_list); ++i) {
- String *symname = Getitem(shadow_list, i);
- Printf(f_shadow_file, "%s.%s = new_instancemethod(%s.%s, None, %s)\n", class_name, symname, module, Swig_name_member(NSPACE_TODO, class_name, symname),
- class_name);
- }
- }
- Printf(f_shadow_file, "%s_swigregister = %s.%s_swigregister\n", class_name, module, class_name);
- Printf(f_shadow_file, "%s_swigregister(%s)\n", class_name, class_name);
+ /* Now emit methods */
+ Printv(f_shadow_file, f_shadow, NIL);
+ Printf(f_shadow_file, "\n");
+ Printf(f_shadow_file, "# Register %s in %s:\n", class_name, module);
+ Printf(f_shadow_file, "%s.%s_swigregister(%s)\n", module, class_name, class_name);
}
shadow_indent = 0;
@@ -4636,9 +4535,6 @@ public:
Clear(builtin_methods);
}
- classic = oldclassic;
- modern = oldmodern;
-
/* Restore shadow file back to original version */
Delete(f_shadow);
f_shadow = f_shadow_file;
@@ -4692,15 +4588,19 @@ public:
String *wname = Swig_name_wrapper(fullname);
Setattr(class_members, symname, n);
int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2;
- String *ds = have_docstring(n) ? cdocstring(n, AUTODOC_FUNC) : NewString("");
+ String *ds = have_docstring(n) ? cdocstring(n, AUTODOC_METHOD) : NewString("");
if (check_kwargs(n)) {
- Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS|METH_KEYWORDS, (char *) \"%s\" },\n", symname, wname, ds);
+ // Cast via void(*)(void) to suppress GCC -Wcast-function-type
+ // warning. Python should always call the function correctly, but
+ // the Python C API requires us to store it in function pointer of a
+ // different type.
+ Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, \"%s\" },\n", symname, wname, ds);
} else if (argcount == 0) {
- Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_NOARGS, (char *) \"%s\" },\n", symname, wname, ds);
+ Printf(builtin_methods, " { \"%s\", %s, METH_NOARGS, \"%s\" },\n", symname, wname, ds);
} else if (argcount == 1) {
- Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_O, (char *) \"%s\" },\n", symname, wname, ds);
+ Printf(builtin_methods, " { \"%s\", %s, METH_O, \"%s\" },\n", symname, wname, ds);
} else {
- Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, METH_VARARGS, (char *) \"%s\" },\n", symname, wname, ds);
+ Printf(builtin_methods, " { \"%s\", %s, METH_VARARGS, \"%s\" },\n", symname, wname, ds);
}
Delete(fullname);
Delete(wname);
@@ -4733,6 +4633,8 @@ public:
if (!have_addtofunc(n)) {
if (!fastproxy || olddefs) {
Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
+ if (have_docstring(n))
+ Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL);
Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n", NIL);
}
} else {
@@ -4754,13 +4656,8 @@ public:
}
}
if (fproxy) {
- List *shadow_list = Getattr(getCurrentClass(), "shadow_methods");
- if (!shadow_list) {
- shadow_list = NewList();
- Setattr(getCurrentClass(), "shadow_methods", shadow_list);
- Delete(shadow_list);
- }
- Append(shadow_list, symname);
+ Printf(f_shadow, tab4);
+ Printf(f_shadow, "%s = _swig_new_instance_method(%s.%s)\n", symname, module, Swig_name_member(NSPACE_TODO, class_name, symname));
}
Delete(fullname);
}
@@ -4790,7 +4687,7 @@ public:
String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname);
String *wname = Swig_name_wrapper(fullname);
Setattr(class_members, symname, n);
- int funpack = modernargs && fastunpack && !Getattr(n, "sym:overloaded");
+ int funpack = fastunpack && !Getattr(n, "sym:overloaded");
String *pyflags = NewString("METH_STATIC|");
int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2;
if (funpack && argcount == 0)
@@ -4799,12 +4696,15 @@ public:
Append(pyflags, "METH_O");
else
Append(pyflags, "METH_VARARGS");
+ // Cast via void(*)(void) to suppress GCC -Wcast-function-type warning.
+ // Python should always call the function correctly, but the Python C
+ // API requires us to store it in function pointer of a different type.
if (have_docstring(n)) {
String *ds = cdocstring(n, AUTODOC_STATICFUNC);
- Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, %s, (char *) \"%s\" },\n", symname, wname, pyflags, ds);
+ Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
Delete(ds);
} else {
- Printf(builtin_methods, " { \"%s\", (PyCFunction) %s, %s, \"\" },\n", symname, wname, pyflags);
+ Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"\" },\n", symname, wname, pyflags);
}
Delete(fullname);
Delete(wname);
@@ -4818,10 +4718,13 @@ public:
}
if (shadow) {
- if (!Getattr(n, "feature:python:callback") && have_addtofunc(n)) {
+ String *staticfunc_name = NewString(fastproxy ? "_swig_new_static_method" : "staticmethod");
+ bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
+ if (!fast || olddefs) {
int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
String *parms = make_pyParmList(n, false, false, kw);
String *callParms = make_pyParmList(n, false, true, kw);
+ Printv(f_shadow, "\n", tab4, "@staticmethod", NIL);
Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
if (have_docstring(n))
Printv(f_shadow, tab8, docstring(n, AUTODOC_STATICFUNC, tab8), "\n", NIL);
@@ -4830,24 +4733,18 @@ public:
if (have_pythonappend(n)) {
Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
- Printv(f_shadow, tab8, "return val\n\n", NIL);
+ Printv(f_shadow, tab8, "return val\n", NIL);
} else {
- Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n\n", NIL);
- }
- Printv(f_shadow, tab4, symname, " = staticmethod(", symname, ")\n", NIL);
- } else {
- if (!classic) {
- if (!modern)
- Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL);
- Printv(f_shadow, tab4, symname, " = staticmethod(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname),
- ")\n", NIL);
- }
- if (classic || !modern) {
- if (!classic)
- Printv(f_shadow, tab4, "else:\n", tab4, NIL);
- Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), "\n", NIL);
+ Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
}
}
+
+ // Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first.
+ if (fast) {
+ Printv(f_shadow, tab4, symname, " = ", staticfunc_name, "(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname),
+ ")\n", NIL);
+ }
+ Delete(staticfunc_name);
}
return SWIG_OK;
}
@@ -4861,7 +4758,7 @@ public:
int oldshadow = shadow;
int use_director = Swig_directorclass(n);
- /*
+ /*
* If we're wrapping the constructor of a C++ director class, prepend a new parameter
* to receive the scripting language object (e.g. 'self')
*
@@ -4905,11 +4802,12 @@ public:
Delete(cname);
}
+ String *subfunc = Swig_name_construct(NSPACE_TODO, symname);
if (!have_constructor && handled_as_init) {
if (!builtin) {
if (Getattr(n, "feature:shadow")) {
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
- String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(NSPACE_TODO, symname));
+ String *pyaction = NewStringf("%s.%s", module, subfunc);
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
Printv(f_shadow, pycode, "\n", NIL);
@@ -4923,7 +4821,7 @@ public:
String *parms = make_pyParmList(n, true, false, allow_kwargs);
/* Pass 'self' only if using director */
- String *callParms = make_pyParmList(n, false, true, allow_kwargs);
+ String *callParms = make_pyParmList(n, false, true, allow_kwargs, true);
if (use_director) {
Insert(callParms, 0, "_self, ");
@@ -4939,13 +4837,7 @@ public:
if (have_pythonprepend(n))
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
Printv(f_shadow, pass_self, NIL);
- if (fastinit) {
- Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self, ", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), ")\n", NIL);
- } else {
- Printv(f_shadow,
- tab8, "this = ", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), "\n",
- tab8, "try:\n", tab8, tab4, "self.this.append(this)\n", tab8, "except __builtin__.Exception:\n", tab8, tab4, "self.this = this\n", NIL);
- }
+ Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self, ", funcCall(subfunc, callParms), ")\n", NIL);
if (have_pythonappend(n))
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n\n", NIL);
Delete(pass_self);
@@ -4955,39 +4847,36 @@ public:
} else {
/* Hmmm. We seem to be creating a different constructor. We're just going to create a
function for it. */
- if (Getattr(n, "feature:shadow")) {
- String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n), "%feature(\"shadow\")");
- String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(NSPACE_TODO, symname));
- Replaceall(pycode, "$action", pyaction);
- Delete(pyaction);
- Printv(f_shadow_stubs, pycode, "\n", NIL);
- Delete(pycode);
- } else {
- String *parms = make_pyParmList(n, false, false, allow_kwargs);
- String *callParms = make_pyParmList(n, false, true, allow_kwargs);
+ if (!builtin) {
+ if (Getattr(n, "feature:shadow")) {
+ String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n), "%feature(\"shadow\")");
+ String *pyaction = NewStringf("%s.%s", module, subfunc);
+ Replaceall(pycode, "$action", pyaction);
+ Delete(pyaction);
+ Printv(f_shadow_stubs, pycode, "\n", NIL);
+ Delete(pycode);
+ } else {
+ String *parms = make_pyParmList(n, false, false, allow_kwargs);
+ String *callParms = make_pyParmList(n, false, true, allow_kwargs);
- Printv(f_shadow_stubs, "\ndef ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
- if (have_docstring(n))
- Printv(f_shadow_stubs, tab4, docstring(n, AUTODOC_CTOR, tab4), "\n", NIL);
- if (have_pythonprepend(n))
- Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
- String *subfunc = NULL;
- /*
- if (builtin)
- subfunc = Copy(Getattr(getCurrentClass(), "sym:name"));
- else
- */
- subfunc = Swig_name_construct(NSPACE_TODO, symname);
- Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
+ Printv(f_shadow_stubs, "\ndef ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
+ if (have_docstring(n))
+ Printv(f_shadow_stubs, tab4, docstring(n, AUTODOC_CTOR, tab4), "\n", NIL);
+ if (have_pythonprepend(n))
+ Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
+ Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
#ifdef USE_THISOWN
- Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
+ Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
#endif
- if (have_pythonappend(n))
- Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
- Printv(f_shadow_stubs, tab4, "return val\n", NIL);
- Delete(subfunc);
+ if (have_pythonappend(n))
+ Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
+ Printv(f_shadow_stubs, tab4, "return val\n", NIL);
+ }
+ } else {
+ Printf(f_shadow_stubs, "%s = %s\n", symname, subfunc);
}
}
+ Delete(subfunc);
}
}
return SWIG_OK;
@@ -5027,9 +4916,6 @@ public:
} else {
Printv(f_shadow, tab4, "__swig_destroy__ = ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "\n", NIL);
if (!have_pythonprepend(n) && !have_pythonappend(n)) {
- if (proxydel) {
- Printv(f_shadow, tab4, "__del__ = lambda self: None\n", NIL);
- }
return SWIG_OK;
}
Printv(f_shadow, tab4, "def __del__(self):\n", NIL);
@@ -5070,20 +4956,12 @@ public:
String *setname = Swig_name_set(NSPACE_TODO, mname);
String *getname = Swig_name_get(NSPACE_TODO, mname);
int assignable = is_assignable(n);
- if (!modern) {
- if (assignable) {
- Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", setname, "\n", NIL);
- }
- Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL);
- }
- if (!classic) {
- if (!modern)
- Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL);
- Printv(f_shadow, tab4, symname, " = _swig_property(", module, ".", getname, NIL);
- if (assignable)
- Printv(f_shadow, ", ", module, ".", setname, NIL);
- Printv(f_shadow, ")\n", NIL);
- }
+ Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
+ if (assignable)
+ Printv(f_shadow, ", ", module, ".", setname, NIL);
+ if (have_docstring(n))
+ Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
+ Printv(f_shadow, ")\n", NIL);
Delete(mname);
Delete(setname);
Delete(getname);
@@ -5129,13 +5007,13 @@ public:
DelWrapper(f);
int assignable = is_assignable(n);
if (assignable) {
- int funpack = modernargs && fastunpack;
+ int funpack = fastunpack;
Wrapper *f = NewWrapper();
Printv(f->def, "SWIGINTERN PyObject *", wrapsetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL);
Wrapper_add_local(f, "res", "int res");
if (!funpack) {
Wrapper_add_local(f, "value", "PyObject *value");
- Append(f->code, "if (!PyArg_ParseTuple(args,(char *)\"O:set\",&value)) return NULL;\n");
+ Append(f->code, "if (!PyArg_ParseTuple(args, \"O:set\", &value)) return NULL;\n");
}
Printf(f->code, "res = %s(%s);\n", varsetname, funpack ? "args" : "value");
Append(f->code, "return !res ? SWIG_Py_Void() : NULL;\n");
@@ -5144,18 +5022,12 @@ public:
add_method(setname, wrapsetname, 0, 0, funpack, 1, 1);
DelWrapper(f);
}
- if (!modern && !builtin) {
- if (assignable) {
- Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", setname, "\n", NIL);
- }
- Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL);
- }
- if (!classic && !builtin) {
- if (!modern)
- Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL);
- Printv(f_shadow, tab4, symname, " = _swig_property(", module, ".", getname, NIL);
+ if (!builtin) {
+ Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
if (assignable)
Printv(f_shadow, ", ", module, ".", setname, NIL);
+ if (have_docstring(n))
+ Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
Printv(f_shadow, ")\n", NIL);
}
String *getter = Getattr(n, "pybuiltin:getter");
@@ -5207,13 +5079,15 @@ public:
Swig_restore(n);
} else if (shadow) {
Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), "\n", NIL);
+ if (have_docstring(n))
+ Printv(f_shadow, tab4, docstring(n, AUTODOC_CONST, tab4), "\n", NIL);
}
return SWIG_OK;
}
/* ------------------------------------------------------------
* insertDirective()
- *
+ *
* Hook for %insert directive. We're going to look for special %shadow inserts
* as a special case so we can do indenting correctly
* ------------------------------------------------------------ */
@@ -5229,9 +5103,11 @@ public:
Delete(pycode);
}
} else if (!ImportMode && (Cmp(section, "pythonbegin") == 0)) {
- String *pycode = indent_pythoncode(code, "", Getfile(n), Getline(n), "%pythonbegin or %insert(\"pythonbegin\") block");
- Printv(f_shadow_begin, pycode, NIL);
- Delete(pycode);
+ if (shadow) {
+ String *pycode = indent_pythoncode(code, "", Getfile(n), Getline(n), "%pythonbegin or %insert(\"pythonbegin\") block");
+ Printv(f_shadow_begin, pycode, NIL);
+ Delete(pycode);
+ }
} else {
Language::insertDirective(n);
}
@@ -5294,7 +5170,7 @@ public:
/* ---------------------------------------------------------------
* classDirectorMethod()
*
- * Emit a virtual director method to pass a method call on to the
+ * Emit a virtual director method to pass a method call on to the
* underlying Python object.
*
* ** Moved it here due to internal error on gcc-2.96 **
@@ -5351,18 +5227,21 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
String *pclassname = NewStringf("SwigDirector_%s", classname);
String *qualified_name = NewStringf("%s::%s", pclassname, name);
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
- target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
+ target = Swig_method_decl(rtype, decl, qualified_name, l, 0);
Printf(w->def, "%s", target);
Delete(qualified_name);
Delete(target);
/* header declaration */
- target = Swig_method_decl(rtype, decl, name, l, 0, 1);
+ target = Swig_method_decl(rtype, decl, name, l, 1);
Printf(declaration, " virtual %s", target);
Delete(target);
// Get any exception classes in the throws typemap
+ if (Getattr(n, "noexcept")) {
+ Append(w->def, " noexcept");
+ Append(declaration, " noexcept");
+ }
ParmList *throw_parm_list = 0;
-
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
Parm *p;
int gencomma = 0;
@@ -5392,12 +5271,20 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
Append(w->def, " {");
Append(declaration, ";\n");
- /* declare method return value
+ /* declare method return value
* if the return value is a reference or const reference, a specialized typemap must
* handle it, including declaration of c_result ($result).
*/
- if (!is_void) {
- if (!(ignored_method && !pure_virtual)) {
+ if (!is_void && (!ignored_method || pure_virtual)) {
+ if (!SwigType_isclass(returntype)) {
+ if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) {
+ String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0));
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL);
+ Delete(construct_result);
+ } else {
+ Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL);
+ }
+ } else {
String *cres = SwigType_lstr(returntype, "c_result");
Printf(w->code, "%s;\n", cres);
Delete(cres);
@@ -5429,7 +5316,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
/* remove the wrapper 'w' since it was producing spurious temps */
Swig_typemap_attach_parms("in", l, 0);
- Swig_typemap_attach_parms("directorin", l, 0);
+ Swig_typemap_attach_parms("directorin", l, w);
Swig_typemap_attach_parms("directorargout", l, w);
Parm *p;
@@ -5544,7 +5431,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
} else {
Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
- //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
+ //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
// source, nonconst, base);
Printv(arglist, source, NIL);
}
@@ -5590,34 +5477,26 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
Append(w->code, "PyObject *method = swig_get_method(swig_method_index, swig_method_name);\n");
if (Len(parse_args) > 0) {
- if (use_parse || !modernargs) {
+ if (use_parse) {
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", Swig_cresult_name(), parse_args, arglist);
} else {
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunctionObjArgs(method %s, NULL);\n", Swig_cresult_name(), arglist);
}
} else {
- if (modernargs) {
- Append(w->code, "swig::SwigVar_PyObject args = PyTuple_New(0);\n");
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_Call(method, (PyObject *) args, NULL);\n", Swig_cresult_name());
- } else {
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, NULL, NULL);\n", Swig_cresult_name());
- }
+ Append(w->code, "swig::SwigVar_PyObject args = PyTuple_New(0);\n");
+ Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_Call(method, (PyObject *) args, NULL);\n", Swig_cresult_name());
}
Append(w->code, "#else\n");
if (Len(parse_args) > 0) {
- if (use_parse || !modernargs) {
+ if (use_parse) {
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n", Swig_cresult_name(), pyname, parse_args, arglist);
} else {
- Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar((char *)\"%s\");\n", pyname);
+ Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar(\"%s\");\n", pyname);
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n", Swig_cresult_name(), arglist);
}
} else {
- if (!modernargs) {
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethod(swig_get_self(), (char *) \"%s\", NULL);\n", Swig_cresult_name(), pyname);
- } else {
- Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar((char *)\"%s\");\n", pyname);
- Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n", Swig_cresult_name());
- }
+ Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar(\"%s\");\n", pyname);
+ Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n", Swig_cresult_name());
}
Append(w->code, "#endif\n");
@@ -5646,7 +5525,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
/*
* Python method may return a simple object, or a tuple.
- * for in/out aruments, we have to extract the appropriate PyObjects from the tuple,
+ * for in/out arguments, we have to extract the appropriate PyObjects from the tuple,
* then marshal everything back to C/C++ (return value and output arguments).
*
*/