Merged the Python 3.0 support branch. The merging progress is not so smooth, so hope this commit won't make anything broken.
This is the (incomplemete) log produced by svnmerge.py: Merged revisions 10405-10409,10420-10422,10426,10438,10445,10451,10454-10465,10467,10473-10475,10485,10488-10489,10493-10495,10497,10509-10510,10513-10514,10517,10520,10525,10528-10529,10533-10535,10554-10557,10570,10573,10593,10614,10666-10669,10673,10678,10687,10690,10704-10706,10731,10744,10750-10752,10755,10759,10770,10775-10776,10813,10819 via svnmerge from https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-bhy git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10834 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
761ef2b98f
commit
3d8ddfc442
75 changed files with 1603 additions and 246 deletions
|
|
@ -49,10 +49,11 @@ static String *shadow_indent = 0;
|
|||
static int in_class = 0;
|
||||
static int classic = 0;
|
||||
static int modern = 0;
|
||||
static int apply = 0;
|
||||
static int new_repr = 1;
|
||||
static int no_header_file = 0;
|
||||
|
||||
static int py3 = 0;
|
||||
|
||||
/* C++ Support + Shadow Classes */
|
||||
|
||||
static int have_constructor;
|
||||
|
|
@ -96,7 +97,6 @@ enum autodoc_t {
|
|||
static const char *usage1 = (char *) "\
|
||||
Python Options (available with -python)\n\
|
||||
-aliasobj0 - Alias obj0 when using fastunpack, needed for some old typemaps \n\
|
||||
-apply - Use apply() in proxy classes\n\
|
||||
-buildnone - Use Py_BuildValue(" ") to obtain Py_None (default in Windows)\n\
|
||||
-castmode - Enable the casting mode, which allows implicit cast between types in python\n\
|
||||
-classic - Use classic classes only\n\
|
||||
|
|
@ -148,6 +148,8 @@ static const char *usage3 = (char *) "\
|
|||
-O - Enable all the optimization options: \n\
|
||||
-modern -fastdispatch -dirvtable -nosafecstrings -fvirtual -noproxydel \n\
|
||||
-fastproxy -fastinit -fastunpack -fastquery -modernargs -nobuildnone \n\
|
||||
-py3 - Generate code with Python 3 specific features:\n\
|
||||
Function annotation \n\
|
||||
\n";
|
||||
|
||||
class PYTHON:public Language {
|
||||
|
|
@ -259,9 +261,6 @@ public:
|
|||
} else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
|
||||
shadow = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-apply") == 0) {
|
||||
apply = 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);
|
||||
|
|
@ -284,7 +283,6 @@ public:
|
|||
} else if (strcmp(argv[i], "-classic") == 0) {
|
||||
classic = 1;
|
||||
modernargs = 0;
|
||||
apply = 1;
|
||||
modern = 0;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-cppcast") == 0) {
|
||||
|
|
@ -390,7 +388,6 @@ public:
|
|||
proxydel = 0;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-modern") == 0) {
|
||||
apply = 0;
|
||||
classic = 0;
|
||||
modern = 1;
|
||||
modernargs = 1;
|
||||
|
|
@ -408,7 +405,6 @@ public:
|
|||
no_header_file = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-O") == 0) {
|
||||
apply = 0;
|
||||
classic = 0;
|
||||
modern = 1;
|
||||
dirvtable = 1;
|
||||
|
|
@ -429,8 +425,17 @@ public:
|
|||
fputs(usage1, stdout);
|
||||
fputs(usage2, stdout);
|
||||
fputs(usage3, stdout);
|
||||
}
|
||||
} else if (strcmp(argv[i], "-py3") == 0) {
|
||||
py3 = 1;
|
||||
Swig_mark_arg(i);
|
||||
}
|
||||
|
||||
}
|
||||
} /* for */
|
||||
|
||||
if (py3) {
|
||||
/* force disable features that not compatible with Python 3.x */
|
||||
classic = 0;
|
||||
}
|
||||
|
||||
if (cppcast) {
|
||||
|
|
@ -691,6 +696,13 @@ public:
|
|||
|
||||
Printv(f_shadow, "\nfrom sys import version_info\n", NULL);
|
||||
|
||||
if(fastproxy)
|
||||
{
|
||||
Printv(f_shadow, "if version_info >= (3,0,0):\n", NULL);
|
||||
Printf(f_shadow, tab4 "new_instancemethod = lambda func, inst, cls: %s.SWIG_PyInstanceMethod_New(func)\n", module);
|
||||
Printv(f_shadow, "else:\n", NULL);
|
||||
Printv(f_shadow, 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
|
||||
|
|
@ -719,11 +731,9 @@ public:
|
|||
* module. */
|
||||
Printv(f_shadow, "del version_info\n", NULL);
|
||||
|
||||
Printv(f_shadow, "import new\n", NULL);
|
||||
Printv(f_shadow, "new_instancemethod = new.instancemethod\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", NULL);
|
||||
}
|
||||
}
|
||||
/* if (!modern) */
|
||||
/* always needed, a class can be forced to be no-modern, such as an exception */
|
||||
{
|
||||
|
|
@ -750,7 +760,7 @@ public:
|
|||
"def _swig_getattr(self,class_type,name):\n",
|
||||
tab4, "if (name == \"thisown\"): return self.this.own()\n",
|
||||
tab4, "method = class_type.__swig_getmethods__.get(name,None)\n",
|
||||
tab4, "if method: return method(self)\n", tab4, "raise AttributeError,name\n\n", NIL);
|
||||
tab4, "if method: return method(self)\n", tab4, "raise AttributeError(name)\n\n", NIL);
|
||||
|
||||
Printv(f_shadow,
|
||||
"def _swig_repr(self):\n",
|
||||
|
|
@ -758,11 +768,17 @@ public:
|
|||
tab4, "except: strthis = \"\"\n", tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
|
||||
|
||||
if (!classic) {
|
||||
/* Usage of types.ObjectType is deprecated.
|
||||
* But don't sure wether this would broken old Python?
|
||||
*/
|
||||
Printv(f_shadow,
|
||||
"import types\n",
|
||||
// "import types\n",
|
||||
"try:\n",
|
||||
" _object = types.ObjectType\n",
|
||||
" _newclass = 1\n", "except AttributeError:\n", " class _object : pass\n", " _newclass = 0\n", "del types\n", "\n\n", NIL);
|
||||
// " _object = types.ObjectType\n",
|
||||
" _object = object\n",
|
||||
" _newclass = 1\n", "except AttributeError:\n", " class _object : pass\n", " _newclass = 0\n",
|
||||
// "del types\n",
|
||||
"\n\n", NIL);
|
||||
}
|
||||
}
|
||||
if (modern) {
|
||||
|
|
@ -788,7 +804,11 @@ public:
|
|||
|
||||
}
|
||||
|
||||
Printf(f_header, "#define SWIG_init init%s\n\n", module);
|
||||
Printf(f_header, "#if PY_VERSION_HEX >= 0x03000000\n");
|
||||
Printf(f_header, "# define SWIG_init PyInit_%s\n\n", module);
|
||||
Printf(f_header, "#else\n");
|
||||
Printf(f_header, "# define SWIG_init init%s\n\n", module);
|
||||
Printf(f_header, "#endif\n");
|
||||
Printf(f_header, "#define SWIG_name \"%s\"\n", module);
|
||||
|
||||
Printf(f_wrappers, "#ifdef __cplusplus\n");
|
||||
|
|
@ -797,6 +817,9 @@ public:
|
|||
Append(const_code, "static swig_const_info swig_const_table[] = {\n");
|
||||
Append(methods, "static PyMethodDef SwigMethods[] = {\n");
|
||||
|
||||
/* the method exported for replacement of new.instancemethod in Python 3 */
|
||||
add_pyinstancemethod_new();
|
||||
|
||||
/* emit code */
|
||||
Language::top(n);
|
||||
|
||||
|
|
@ -815,6 +838,12 @@ public:
|
|||
Append(const_code, "{0, 0, 0, 0.0, 0, 0}};\n");
|
||||
Printf(f_wrappers, "%s\n", const_code);
|
||||
initialize_threads(f_init);
|
||||
|
||||
Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
|
||||
Printf(f_init, " return m;\n");
|
||||
Printf(f_init, "#else\n");
|
||||
Printf(f_init, " return;\n");
|
||||
Printf(f_init, "#endif\n");
|
||||
Printf(f_init, "}\n");
|
||||
|
||||
Printf(f_wrappers, "#ifdef __cplusplus\n");
|
||||
|
|
@ -822,10 +851,6 @@ public:
|
|||
Printf(f_wrappers, "#endif\n");
|
||||
|
||||
if (shadow) {
|
||||
/*
|
||||
Printf(f_shadow_imports,"\nimport %s\n", module);
|
||||
Printv(f_shadow_py, f_shadow_imports, "\n",NIL);
|
||||
*/
|
||||
Printv(f_shadow_py, f_shadow, "\n", NIL);
|
||||
Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
|
||||
|
||||
|
|
@ -859,6 +884,19 @@ public:
|
|||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* Emit the wrapper for PyInstanceMethod_New to MethodDef array.
|
||||
* This wrapper is used to implement -fastproxy,
|
||||
* as a replacement of new.instancemethod in Python 3.
|
||||
* ------------------------------------------------------------ */
|
||||
int add_pyinstancemethod_new()
|
||||
{
|
||||
String* name = NewString("SWIG_PyInstanceMethod_New");
|
||||
Printf(methods, "\t { (char *)\"%s\", (PyCFunction)%s, METH_O, NULL},", name, name);
|
||||
Delete(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* importDirective()
|
||||
|
|
@ -902,25 +940,19 @@ public:
|
|||
return Language::importDirective(n);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* emitFuncCallHelper()
|
||||
* Write the shadow code to call a function in the extension
|
||||
* module. Takes into account the -apply flag and whether
|
||||
* to use keyword args or not.
|
||||
* funcCall()
|
||||
* Emit shadow code to call a function in the extension
|
||||
* module. Using proper argument and calling style for
|
||||
* given node n.
|
||||
* ------------------------------------------------------------ */
|
||||
String *funcCall(String *name, String *parms) {
|
||||
String *str = NewString("");
|
||||
|
||||
String *funcCallHelper(String *name, int kw) {
|
||||
String *str;
|
||||
|
||||
str = NewString("");
|
||||
if (apply) {
|
||||
Printv(str, "apply(", module, ".", name, ", args", (kw ? ", kwargs" : ""), ")", NIL);
|
||||
} else {
|
||||
Printv(str, module, ".", name, "(*args", (kw ? ", **kwargs" : ""), ")", NIL);
|
||||
}
|
||||
Printv(str, module, ".", name, "(", parms, ")", NIL);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* pythoncode() - Output python code into the shadow file
|
||||
|
|
@ -1088,29 +1120,84 @@ public:
|
|||
return doc;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* makeParameterName()
|
||||
* Note: the generated name should consist with that in kwnames[]
|
||||
*
|
||||
* Inputs:
|
||||
* n - Node
|
||||
* p - parameter node
|
||||
* arg_num - parameter argument number
|
||||
* Return:
|
||||
* arg - a unique parameter name
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *makeParameterName(ParmList *plist, Parm *p, int arg_num) {
|
||||
String *arg = 0;
|
||||
String *pn = Swig_name_make(p, 0, Getattr(p, "name"), 0, 0);
|
||||
// Use C parameter name unless it is a duplicate or an empty parameter name
|
||||
int count = 0;
|
||||
if ( SwigType_isvarargs(Getattr(p, "type")) ) {
|
||||
return NewString("*args");
|
||||
}
|
||||
while (plist) {
|
||||
if ((Cmp(pn, Getattr(plist, "name")) == 0))
|
||||
count++;
|
||||
plist = nextSibling(plist);
|
||||
}
|
||||
arg = (!pn || !Len(pn) || (count > 1)) ? NewStringf("arg%d", arg_num) : Copy(pn);
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* make_autodocParmList()
|
||||
* Generate the documentation for the function parameters
|
||||
* Parameters:
|
||||
* func_annotation: Function annotation support
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
String *make_autodocParmList(Node *n, bool showTypes) {
|
||||
String *make_autodocParmList(Node *n, bool showTypes, bool calling=false, bool func_annotation=false) {
|
||||
|
||||
|
||||
String *doc = NewString("");
|
||||
String *pdocs = Copy(Getattr(n, "feature:pdocs"));
|
||||
ParmList *plist = CopyParmList(Getattr(n, "parms"));
|
||||
Parm *p;
|
||||
Parm *pnext;
|
||||
Node *lookup;
|
||||
Node *lookup;
|
||||
|
||||
|
||||
int lines = 0;
|
||||
int arg_num = 0;
|
||||
const int maxwidth = 50;
|
||||
|
||||
if(calling)
|
||||
func_annotation = false;
|
||||
|
||||
if (pdocs)
|
||||
Append(pdocs, "\n");
|
||||
|
||||
|
||||
Swig_typemap_attach_parms("in", plist, 0);
|
||||
Swig_typemap_attach_parms("doc", plist, 0);
|
||||
|
||||
|
||||
if (Strcmp(ParmList_protostr(plist), "void")==0) {
|
||||
//No parameters actually
|
||||
return doc;
|
||||
}
|
||||
|
||||
for (p = plist; p; p = pnext) {
|
||||
|
||||
String *tm = Getattr(p, "tmap:in");
|
||||
if (tm) {
|
||||
pnext = Getattr(p, "tmap:in:next");
|
||||
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
pnext = nextSibling(p);
|
||||
}
|
||||
|
||||
String *name = 0;
|
||||
String *type = 0;
|
||||
String *value = 0;
|
||||
|
|
@ -1127,12 +1214,14 @@ public:
|
|||
type = type ? type : Getattr(p, "type");
|
||||
value = value ? value : Getattr(p, "value");
|
||||
|
||||
String *tm = Getattr(p, "tmap:in");
|
||||
if (tm) {
|
||||
pnext = Getattr(p, "tmap:in:next");
|
||||
} else {
|
||||
pnext = nextSibling(p);
|
||||
}
|
||||
name = makeParameterName(plist, p, arg_num);
|
||||
// Reset it for convinient in further use. (mainly for makeParameterName())
|
||||
// Since the plist is created by CopyParmList,
|
||||
// we can hope that the set would have no side effect
|
||||
Setattr(p, "name", name);
|
||||
|
||||
arg_num++;
|
||||
|
||||
|
||||
if (Len(doc)) {
|
||||
// add a comma to the previous one if any
|
||||
|
|
@ -1144,39 +1233,40 @@ public:
|
|||
lines += 1;
|
||||
}
|
||||
}
|
||||
|
||||
type = SwigType_base(type);
|
||||
lookup = Swig_symbol_clookup(type, 0);
|
||||
if (lookup)
|
||||
type = Getattr(lookup, "sym:name");
|
||||
|
||||
// Do the param type too?
|
||||
if (showTypes) {
|
||||
type = SwigType_base(type);
|
||||
lookup = Swig_symbol_clookup(type, 0);
|
||||
if (lookup)
|
||||
type = Getattr(lookup, "sym:name");
|
||||
Printf(doc, "%s ", type);
|
||||
if (showTypes)
|
||||
Printf(doc, "%s ", type);
|
||||
|
||||
|
||||
Append(doc, name);
|
||||
if (pdoc) {
|
||||
if (!pdocs)
|
||||
pdocs = NewString("Parameters:\n");
|
||||
Printf(pdocs, " %s\n", pdoc);
|
||||
}
|
||||
|
||||
if (name) {
|
||||
Append(doc, name);
|
||||
if (pdoc) {
|
||||
if (!pdocs)
|
||||
pdocs = NewString("Parameters:\n");
|
||||
Printf(pdocs, " %s\n", pdoc);
|
||||
}
|
||||
} else {
|
||||
Append(doc, "?");
|
||||
}
|
||||
// Write the function annoation
|
||||
if (func_annotation)
|
||||
Printf(doc, " : '%s'", type);
|
||||
|
||||
if (value) {
|
||||
if (Strcmp(value, "NULL") == 0)
|
||||
value = NewString("None");
|
||||
else if (Strcmp(value, "true") == 0 || Strcmp(value, "TRUE") == 0)
|
||||
value = NewString("True");
|
||||
else if (Strcmp(value, "false") == 0 || Strcmp(value, "FALSE") == 0)
|
||||
value = NewString("False");
|
||||
// Write default value
|
||||
if (value && !calling) {
|
||||
String* pv = pyvalue(value, Getattr(p, "type"));
|
||||
if (pv)
|
||||
value = pv;
|
||||
else {
|
||||
lookup = Swig_symbol_clookup(value, 0);
|
||||
if (lookup)
|
||||
if (lookup) {
|
||||
value = Getattr(lookup, "sym:name");
|
||||
}
|
||||
}
|
||||
Printf(doc, "=%s", value);
|
||||
Printf(doc, " = %s", value);
|
||||
}
|
||||
}
|
||||
if (pdocs)
|
||||
|
|
@ -1314,6 +1404,132 @@ public:
|
|||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* pyvalue()
|
||||
* Check if string v can be a Python value literal,
|
||||
* (eg. number or string), or translate it to a Python literal.
|
||||
* ------------------------------------------------------------ */
|
||||
String* pyvalue(String *v, SwigType *t)
|
||||
{
|
||||
if (v && Len(v)>0) {
|
||||
char fc = (Char(v))[0];
|
||||
if (('0'<=fc && fc<='9') || '\''==fc || '"'==fc) {
|
||||
/* number or string (or maybe NULL pointer)*/
|
||||
if (SwigType_ispointer(t) && Strcmp(v, "0")==0)
|
||||
return NewString("None");
|
||||
else
|
||||
return v;
|
||||
}
|
||||
if (Strcmp(v, "true")==0 || Strcmp(v, "FALSE")==0)
|
||||
return NewString("True");
|
||||
if (Strcmp(v, "false")==0 || Strcmp(v, "FALSE")==0)
|
||||
return NewString("False");
|
||||
if (Strcmp(v, "NULL")==0)
|
||||
return NewString("None");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------
|
||||
* is_primitive_defaultargs()
|
||||
* Check if all the default args have primitive type.
|
||||
* (So we can generate proper parameter list with default
|
||||
* values..)
|
||||
* ------------------------------------------------------------ */
|
||||
bool is_primitive_defaultargs(Node *n)
|
||||
{
|
||||
ParmList *plist = CopyParmList(Getattr(n, "parms"));
|
||||
Parm *p;
|
||||
Parm *pnext;
|
||||
|
||||
Swig_typemap_attach_parms("in", plist, 0);
|
||||
for (p = plist; p; p = pnext) {
|
||||
String *tm = Getattr(p, "tmap:in");
|
||||
if (tm) {
|
||||
pnext = Getattr(p, "tmap:in:next");
|
||||
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
pnext = nextSibling(p);
|
||||
}
|
||||
String *type = Getattr(p, "type");
|
||||
String *value = Getattr(p, "value");
|
||||
if (!pyvalue(value, type))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* is_real_overloaded()
|
||||
* Check if the function is overloaded, but not just have some
|
||||
* siblings generated due to the original function have
|
||||
* default arguments.
|
||||
* ------------------------------------------------------------ */
|
||||
bool is_real_overloaded(Node *n)
|
||||
{
|
||||
Node *h = Getattr(n, "sym:overloaded");
|
||||
Node *i;
|
||||
if (!h)
|
||||
return false;
|
||||
|
||||
i = Getattr(h, "sym:nextSibling");
|
||||
while (i) {
|
||||
Node *nn = Getattr(i, "defaultargs");
|
||||
if (nn != h) {
|
||||
/* Check if overloaded function has defaultargs and
|
||||
* pointed to the first overloaded. */
|
||||
return true;
|
||||
}
|
||||
i = Getattr(i, "sym:nextSibling");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* make_pyParmList()
|
||||
* 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,
|
||||
* see default_arguments() in parser.y. */
|
||||
Node *nn = Getattr(n, "defaultargs");
|
||||
if (nn) n = nn;
|
||||
|
||||
/* For overloaded function, just use *args */
|
||||
if (is_real_overloaded(n) ||
|
||||
GetFlag(n, "feature:compactdefaultargs") ||
|
||||
!is_primitive_defaultargs(n))
|
||||
{
|
||||
String *parms = NewString("");
|
||||
if(in_class)
|
||||
Printf(parms, "self, ");
|
||||
Printf(parms, "*args");
|
||||
if (kw)
|
||||
Printf(parms, ", **kwargs");
|
||||
return parms;
|
||||
}
|
||||
|
||||
bool funcanno = py3 ? true : false;
|
||||
String *params = NewString("");
|
||||
String *_params = make_autodocParmList(n, false, is_calling, funcanno);
|
||||
|
||||
if (in_class)
|
||||
{
|
||||
Printf(params, "self");
|
||||
if(Len(_params) > 0)
|
||||
Printf(params, ", ");
|
||||
}
|
||||
|
||||
Printv(params, _params, NULL);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* have_pythonprepend()
|
||||
|
|
@ -1379,6 +1595,40 @@ public:
|
|||
return have_pythonappend(n) || have_pythonprepend(n) || have_docstring(n);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* returnTypeAnnotation()
|
||||
* Helper function for constructing the function annotation
|
||||
* of the returning type, return a empty string for Python 2.x
|
||||
* ------------------------------------------------------------ */
|
||||
String* returnTypeAnnotation(Node *n)
|
||||
{
|
||||
String *ret=0;
|
||||
Parm *p = Getattr(n, "parms");
|
||||
String *tm;
|
||||
/* Try to guess the returning type by argout typemap,
|
||||
* however the result may not accurate. */
|
||||
while (p) {
|
||||
if ((tm=Getattr(p, "tmap:argout:match_type"))) {
|
||||
tm = SwigType_str(tm, 0);
|
||||
if (ret)
|
||||
Printv(ret, ", ", tm, NULL);
|
||||
else
|
||||
ret = tm;
|
||||
p = Getattr(p, "tmap:argout:next");
|
||||
} else {
|
||||
p = nextSibling(p);
|
||||
}
|
||||
}
|
||||
/* If no argout typemap, then get the returning type from
|
||||
* the function prototype. */
|
||||
if (!ret) {
|
||||
ret = Getattr(n, "type");
|
||||
if (ret) ret = SwigType_str(ret, 0);
|
||||
}
|
||||
return (ret && py3) ? NewStringf(" -> \"%s\" ", ret)
|
||||
: NewString("");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* emitFunctionShadowHelper()
|
||||
|
|
@ -1388,24 +1638,26 @@ public:
|
|||
* ------------------------------------------------------------ */
|
||||
|
||||
void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) {
|
||||
if (Getattr(n, "feature:python:callback") || !have_addtofunc(n)) {
|
||||
/* If there is no addtofunc directive then just assign from the extension module */
|
||||
Printv(f_dest, name, " = ", module, ".", name, "\n", NIL);
|
||||
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, ctab4, docstring(n, AUTODOC_FUNC, tab4), "\n", NIL);
|
||||
if (have_pythonprepend(n))
|
||||
Printv(f_dest, ctab4, pythonprepend(n), "\n", NIL);
|
||||
if (have_pythonappend(n)) {
|
||||
Printv(f_dest, ctab4, "val = ", funcCall(name, callParms), "\n", NIL);
|
||||
Printv(f_dest, ctab4, pythonappend(n), "\n", NIL);
|
||||
Printv(f_dest, ctab4, "return val\n", NIL);
|
||||
} else {
|
||||
/* Otherwise make a wrapper function to insert the code into */
|
||||
Printv(f_dest, "\ndef ", name, "(*args", (kw ? ", **kwargs" : ""), "):\n", NIL);
|
||||
if (have_docstring(n))
|
||||
Printv(f_dest, ctab4, docstring(n, AUTODOC_FUNC, tab4), "\n", NIL);
|
||||
if (have_pythonprepend(n))
|
||||
Printv(f_dest, ctab4, pythonprepend(n), "\n", NIL);
|
||||
if (have_pythonappend(n)) {
|
||||
Printv(f_dest, ctab4, "val = ", funcCallHelper(name, kw), "\n", NIL);
|
||||
Printv(f_dest, ctab4, pythonappend(n), "\n", NIL);
|
||||
Printv(f_dest, ctab4, "return val\n", NIL);
|
||||
} else {
|
||||
Printv(f_dest, ctab4, "return ", funcCallHelper(name, kw), "\n", NIL);
|
||||
}
|
||||
Printv(f_dest, ctab4, "return ", funcCall(name, callParms), "\n", NIL);
|
||||
}
|
||||
|
||||
if (Getattr(n, "feature:python:callback") || !have_addtofunc(n)) {
|
||||
/* If there is no addtofunc directive then just assign from the extension module (for speed up) */
|
||||
Printv(f_dest, name, " = ", module, ".", name, "\n", NIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2488,7 +2740,7 @@ public:
|
|||
Printf(f_directors_h, " PyObject *swig_get_method(size_t method_index, const char *method_name) const {\n");
|
||||
Printf(f_directors_h, " PyObject *method = vtable[method_index];\n");
|
||||
Printf(f_directors_h, " if (!method) {\n");
|
||||
Printf(f_directors_h, " swig::PyObject_var name = PyString_FromString(method_name);\n");
|
||||
Printf(f_directors_h, " swig::PyObject_var name = SWIG_Python_str_FromChar(method_name);\n");
|
||||
Printf(f_directors_h, " method = PyObject_GetAttr(swig_get_self(), name);\n");
|
||||
Printf(f_directors_h, " if (method == NULL) {\n");
|
||||
Printf(f_directors_h, " std::string msg = \"Method in class %s doesn't exist, undefined \";\n", classname);
|
||||
|
|
@ -2623,6 +2875,16 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* dealing with abstract base class */
|
||||
String *abcs = Getattr(n, "feature:python:abc");
|
||||
if (py3 && abcs) {
|
||||
if (Len(base_class)) {
|
||||
Putc(',', base_class);
|
||||
}
|
||||
Printv(base_class, abcs, NIL);
|
||||
}
|
||||
|
||||
Printv(f_shadow, "class ", class_name, NIL);
|
||||
|
||||
if (Len(base_class)) {
|
||||
|
|
@ -2631,6 +2893,9 @@ public:
|
|||
if (!classic) {
|
||||
Printf(f_shadow, modern ? "(object)" : "(_object)");
|
||||
}
|
||||
if (GetFlag(n, "feature:exceptionclass") ) {
|
||||
Printf(f_shadow, "(Exception)");
|
||||
}
|
||||
}
|
||||
Printf(f_shadow, ":\n");
|
||||
if (have_docstring(n)) {
|
||||
|
|
@ -2721,7 +2986,7 @@ public:
|
|||
Delete(realct);
|
||||
}
|
||||
if (!have_constructor) {
|
||||
Printv(f_shadow_file, tab4, "def __init__(self, *args, **kwargs): raise AttributeError, \"No constructor defined\"\n", NIL);
|
||||
Printv(f_shadow_file, tab4, "def __init__(self, *args, **kwargs): raise AttributeError(\"No constructor defined\")\n", NIL);
|
||||
} else if (fastinit) {
|
||||
|
||||
Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
|
||||
|
|
@ -2834,13 +3099,15 @@ public:
|
|||
Delete(pycode);
|
||||
fproxy = 0;
|
||||
} else {
|
||||
String *parms = make_pyParmList(n, true, false, allow_kwargs);
|
||||
String *callParms = make_pyParmList(n, true, true, allow_kwargs);
|
||||
if (!have_addtofunc(n)) {
|
||||
if (!fastproxy || olddefs) {
|
||||
Printv(f_shadow, tab4, "def ", symname, "(*args", (allow_kwargs ? ", **kwargs" : ""), "):", NIL);
|
||||
Printv(f_shadow, " return ", funcCallHelper(Swig_name_member(class_name, symname), allow_kwargs), "\n", NIL);
|
||||
Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL);
|
||||
Printv(f_shadow, " return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL);
|
||||
}
|
||||
} else {
|
||||
Printv(f_shadow, tab4, "def ", symname, "(*args", (allow_kwargs ? ", **kwargs" : ""), "):", NIL);
|
||||
Printv(f_shadow, tab4, "def ", symname, "(",parms , ")", returnTypeAnnotation(n), ":", NIL);
|
||||
Printv(f_shadow, "\n", NIL);
|
||||
if (have_docstring(n))
|
||||
Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL);
|
||||
|
|
@ -2850,11 +3117,11 @@ public:
|
|||
}
|
||||
if (have_pythonappend(n)) {
|
||||
fproxy = 0;
|
||||
Printv(f_shadow, tab8, "val = ", funcCallHelper(Swig_name_member(class_name, symname), allow_kwargs), "\n", NIL);
|
||||
Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL);
|
||||
Printv(f_shadow, tab8, pythonappend(n), "\n", NIL);
|
||||
Printv(f_shadow, tab8, "return val\n\n", NIL);
|
||||
} else {
|
||||
Printv(f_shadow, tab8, "return ", funcCallHelper(Swig_name_member(class_name, symname), allow_kwargs), "\n\n", NIL);
|
||||
Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n\n", NIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2887,17 +3154,19 @@ public:
|
|||
if (shadow) {
|
||||
if (!classic && !Getattr(n, "feature:python:callback") && have_addtofunc(n)) {
|
||||
int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
|
||||
Printv(f_shadow, tab4, "def ", symname, "(*args", (kw ? ", **kwargs" : ""), "):\n", NIL);
|
||||
String *parms = make_pyParmList(n, true, false, kw);
|
||||
String *callParms = make_pyParmList(n, true, true, kw);
|
||||
Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
|
||||
if (have_docstring(n))
|
||||
Printv(f_shadow, tab8, docstring(n, AUTODOC_STATICFUNC, tab8), "\n", NIL);
|
||||
if (have_pythonprepend(n))
|
||||
Printv(f_shadow, tab8, pythonprepend(n), "\n", NIL);
|
||||
if (have_pythonappend(n)) {
|
||||
Printv(f_shadow, tab8, "val = ", funcCallHelper(Swig_name_member(class_name, symname), kw), "\n", NIL);
|
||||
Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL);
|
||||
Printv(f_shadow, tab8, pythonappend(n), "\n", NIL);
|
||||
Printv(f_shadow, tab8, "return val\n\n", NIL);
|
||||
} else {
|
||||
Printv(f_shadow, tab8, "return ", funcCallHelper(Swig_name_member(class_name, symname), kw), "\n\n", NIL);
|
||||
Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n\n", NIL);
|
||||
}
|
||||
Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", symname, ")\n", NIL);
|
||||
|
||||
|
|
@ -2969,8 +3238,8 @@ public:
|
|||
handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0);
|
||||
Delete(cname);
|
||||
}
|
||||
|
||||
if (!have_constructor && handled_as_init) {
|
||||
|
||||
if (!have_constructor && handled_as_init) {
|
||||
if (Getattr(n, "feature:shadow")) {
|
||||
String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4);
|
||||
String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(symname));
|
||||
|
|
@ -2984,23 +3253,30 @@ public:
|
|||
String *classname = Swig_class_name(parent);
|
||||
String *rclassname = Swig_class_name(getCurrentClass());
|
||||
assert(rclassname);
|
||||
if (use_director) {
|
||||
|
||||
String *parms = make_pyParmList(n, true, false, allow_kwargs);
|
||||
/* Pass 'self' only if using director */
|
||||
String *callParms = make_pyParmList(n, false, true, allow_kwargs);
|
||||
|
||||
if (use_director) {
|
||||
Insert(callParms, 0, "_self, ");
|
||||
Printv(pass_self, tab8, NIL);
|
||||
Printf(pass_self, "if self.__class__ == %s:\n", classname);
|
||||
Printv(pass_self, tab8, tab4, "args = (None,) + args\n", tab8, "else:\n", tab8, tab4, "args = (self,) + args\n", NIL);
|
||||
//Printv(pass_self, tab8, tab4, "args = (None,) + args\n", tab8, "else:\n", tab8, tab4, "args = (self,) + args\n", NIL);
|
||||
Printv(pass_self, tab8, tab4, "_self = None\n", tab8, "else:\n", tab8, tab4, "_self = self\n", NIL);
|
||||
}
|
||||
|
||||
Printv(f_shadow, tab4, "def __init__(self, *args", (allow_kwargs ? ", **kwargs" : ""), "): \n", NIL);
|
||||
Printv(f_shadow, tab4, "def __init__(", parms, ")", returnTypeAnnotation(n), ": \n", NIL);
|
||||
if (have_docstring(n))
|
||||
Printv(f_shadow, tab8, docstring(n, AUTODOC_CTOR, tab8), "\n", NIL);
|
||||
if (have_pythonprepend(n))
|
||||
Printv(f_shadow, tab8, pythonprepend(n), "\n", NIL);
|
||||
Printv(f_shadow, pass_self, NIL);
|
||||
if (fastinit) {
|
||||
Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self,", funcCallHelper(Swig_name_construct(symname), allow_kwargs), ")\n", NIL);
|
||||
Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self,", funcCall(Swig_name_construct(symname), callParms), ")\n", NIL);
|
||||
} else {
|
||||
Printv(f_shadow,
|
||||
tab8, "this = ", funcCallHelper(Swig_name_construct(symname), allow_kwargs), "\n",
|
||||
tab8, "this = ", funcCall(Swig_name_construct(symname), callParms), "\n",
|
||||
tab8, "try: self.this.append(this)\n", tab8, "except: self.this = this\n", NIL);
|
||||
}
|
||||
if (have_pythonappend(n))
|
||||
|
|
@ -3020,13 +3296,15 @@ public:
|
|||
Printv(f_shadow_stubs, pycode, "\n", NIL);
|
||||
Delete(pycode);
|
||||
} else {
|
||||
String *parms = make_pyParmList(n, true, false, allow_kwargs);
|
||||
String *callParms = make_pyParmList(n, true, true, allow_kwargs);
|
||||
|
||||
Printv(f_shadow_stubs, "\ndef ", symname, "(*args", (allow_kwargs ? ", **kwargs" : ""), "):\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, tab4, pythonprepend(n), "\n", NIL);
|
||||
Printv(f_shadow_stubs, tab4, "val = ", funcCallHelper(Swig_name_construct(symname), allow_kwargs), "\n", NIL);
|
||||
Printv(f_shadow_stubs, tab4, "val = ", funcCall(Swig_name_construct(symname), callParms), "\n", NIL);
|
||||
#ifdef USE_THISOWN
|
||||
Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
|
||||
#endif
|
||||
|
|
@ -3605,15 +3883,15 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
|
|||
if (use_parse || !modernargs) {
|
||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n",
|
||||
pyname, parse_args, arglist);
|
||||
} else {
|
||||
Printf(w->code, "swig::PyObject_var swig_method_name = PyString_FromString((char *)\"%s\");\n", pyname);
|
||||
} else {
|
||||
Printf(w->code, "swig::PyObject_var swig_method_name = SWIG_Python_str_FromChar((char *)\"%s\");\n", pyname);
|
||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n", arglist);
|
||||
}
|
||||
} else {
|
||||
if (!modernargs) {
|
||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *) \"%s\", NULL);\n", pyname);
|
||||
} else {
|
||||
Printf(w->code, "swig::PyObject_var swig_method_name = PyString_FromString((char *)\"%s\");\n", pyname);
|
||||
Printf(w->code, "swig::PyObject_var swig_method_name = SWIG_Python_str_FromChar((char *)\"%s\");\n", pyname);
|
||||
Append(w->code, "swig::PyObject_var result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue