diff options
Diffstat (limited to 'Source/Modules/python.cxx')
-rw-r--r-- | Source/Modules/python.cxx | 454 |
1 files changed, 309 insertions, 145 deletions
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 06c1c4868..dde1b6023 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -17,6 +17,8 @@ static int treduce = SWIG_cparse_template_reduce(0); #include <ctype.h> +#include <errno.h> +#include <stdlib.h> #define PYSHADOW_MEMBER 0x2 #define WARN_PYTHON_MULTIPLE_INH 405 @@ -807,7 +809,7 @@ public: Printv(f_shadow, "\nfrom sys import version_info\n", NULL); if (!builtin && fastproxy) { - Printv(f_shadow, "if version_info >= (3,0,0):\n", NULL); + 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); @@ -822,7 +824,7 @@ public: * isn't available in python 2.4 or earlier, so we have to write some * code conditional on the python version. */ - Printv(f_shadow, "if version_info >= (2,6,0):\n", NULL); + Printv(f_shadow, "if version_info >= (2, 6, 0):\n", NULL); Printv(f_shadow, tab4, "def swig_import_helper():\n", NULL); Printv(f_shadow, tab8, "from os.path import dirname\n", NULL); Printv(f_shadow, tab8, "import imp\n", NULL); @@ -852,40 +854,45 @@ public: Printf(f_shadow, "from %s import *\n", module); } 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); + 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); } /* 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, - "def _swig_setattr_nondynamic(self,class_type,name,value,static=1):\n", - tab4, "if (name == \"thisown\"): return self.this.own(value)\n", - tab4, "if (name == \"this\"):\n", tab4, tab4, "if type(value).__name__ == 'SwigPyObject':\n", tab4, tab8, "self.__dict__[name] = value\n", + "\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\"): self.__dict__[\"thisown\"] = value.thisown\n", tab4, tab8, "del value.thisown\n", + 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: return method(self,value)\n", + 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 - tab4, tab4, "self.__dict__[name] = value\n", + tab4, tab4, "object.__setattr__(self, name, value)\n", tab4, "else:\n", tab4, tab4, "raise AttributeError(\"You cannot add attributes to %s\" % self)\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); + "\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, - "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); + "\n", "def _swig_getattr_nondynamic(self, class_type, name, static=1):\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, "if (not static):\n", + tab4, tab4, "return object.__getattr__(self, name)\n", + tab4, "else:\n", + tab4, tab4, "raise AttributeError(name)\n\n", + "def _swig_getattr(self, class_type, name):\n", tab4, "return _swig_getattr_nondynamic(self, class_type, name, 0)\n\n", NIL); Printv(f_shadow, - "def _swig_repr(self):\n", - tab4, "try: strthis = \"proxy of \" + self.this.__repr__()\n", - tab4, "except: strthis = \"\"\n", tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL); + "\n", "def _swig_repr(self):\n", + tab4, "try:\n", tab8, "strthis = \"proxy of \" + self.this.__repr__()\n", + tab4, "except:\n", tab8, "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. @@ -895,19 +902,19 @@ public: // "import types\n", "try:\n", // " _object = types.ObjectType\n", - " _object = object\n", " _newclass = 1\n", "except AttributeError:\n", " class _object : pass\n", " _newclass = 0\n", + tab4, "_object = object\n", tab4, "_newclass = 1\n", "except AttributeError:\n", tab4, "class _object:\n", tab8, "pass\n", tab4, "_newclass = 0\n", // "del types\n", "\n\n", NIL); } } if (modern) { - Printv(f_shadow, "def _swig_setattr_nondynamic_method(set):\n", tab4, "def set_attr(self,name,value):\n", + Printv(f_shadow, "\n", "def _swig_setattr_nondynamic_method(set):\n", tab4, "def set_attr(self, name, value):\n", #ifdef USE_THISOWN - tab4, tab4, "if hasattr(self,name) or (name in (\"this\", \"thisown\")):\n", + tab4, tab4, "if hasattr(self, name) or (name in (\"this\", \"thisown\")):\n", #else - tab4, tab4, "if (name == \"thisown\"): return self.this.own(value)\n", tab4, tab4, "if hasattr(self,name) or (name == \"this\"):\n", + tab4, tab4, "if (name == \"thisown\"):\n", tab8, tab4, "return self.this.own(value)\n", tab4, tab4, "if hasattr(self, name) or (name == \"this\"):\n", #endif - tab4, tab4, tab4, "set(self,name,value)\n", + 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); } @@ -1523,6 +1530,21 @@ public: 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. @@ -1534,13 +1556,14 @@ public: * The "lname" attribute in each parameter in plist will be contain a parameter name * ----------------------------------------------------------------------------- */ - void addMissingParameterNames(ParmList *plist, int arg_offset) { + void addMissingParameterNames(Node *n, ParmList *plist, int arg_offset) { Parm *p = plist; int i = arg_offset; while (p) { if (!Getattr(p, "lname")) { - String *pname = Swig_cparm_name(p, i); - Delete(pname); + String *name = makeParameterName(n, p, i); + Setattr(p, "lname", name); + Delete(name); } i++; p = nextSibling(p); @@ -1563,14 +1586,18 @@ public: Parm *pnext; - int lines = 0; - int start_arg_num = is_wrapping_class() ? 1 : 0; - const int maxwidth = 80; + // 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; - addMissingParameterNames(plist, start_arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms + addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms Swig_typemap_attach_parms("in", plist, 0); Swig_typemap_attach_parms("doc", plist, 0); @@ -1579,7 +1606,7 @@ public: return doc; } - for (p = plist; p; p = pnext) { + for (p = plist; p; p = pnext, arg_num++) { String *tm = Getattr(p, "tmap:in"); if (tm) { @@ -1602,25 +1629,22 @@ public: } // Note: the generated name should be consistent with that in kwnames[] - name = name ? name : Getattr(p, "name"); - name = name ? name : Getattr(p, "lname"); - name = Swig_name_make(p, 0, name, 0, 0); // rename parameter if a keyword + String *made_name = 0; + if (!name) { + name = made_name = makeParameterName(n, p, arg_num); + } type = type ? type : Getattr(p, "type"); value = value ? value : Getattr(p, "value"); - if (SwigType_isvarargs(type)) + if (SwigType_isvarargs(type)) { + Delete(made_name); break; + } if (Len(doc)) { // add a comma to the previous one if any Append(doc, ", "); - - // Do we need to wrap a long line? - if ((Len(doc) - lines * maxwidth) > maxwidth) { - Printf(doc, "\n%s", tab4); - lines += 1; - } } // Do the param type too? @@ -1637,22 +1661,16 @@ 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 { - 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(type_str); - Delete(name); + Delete(made_name); } if (pdocs) Setattr(n, "feature:pdocs", pdocs); @@ -1799,57 +1817,192 @@ public: } /* ------------------------------------------------------------ + * convertDoubleValue() + * Check if the given string looks like a decimal floating point constant + * and return it if it does, otherwise return NIL. + * ------------------------------------------------------------ */ + String *convertDoubleValue(String *v) { + const char *const s = Char(v); + char *end; + + double value = strtod(s, &end); + (void) value; + if (errno != ERANGE && end != s) { + // An added complication: at least some versions of strtod() recognize + // hexadecimal floating point numbers which don't exist in Python, so + // detect them ourselves and refuse to convert them (this can't be done + // without loss of precision in general). + // + // Also don't accept neither "NAN" nor "INFINITY" (both of which + // conveniently contain "n"). + if (strpbrk(s, "xXnN")) + return NIL; + + // Disregard optional "f" suffix, it can be just dropped in Python as it + // uses doubles for everything anyhow. + for (char* p = end; *p != '\0'; ++p) { + switch (*p) { + case 'f': + case 'F': + break; + + default: + return NIL; + } + } + + // Avoid unnecessary string allocation in the common case when we don't + // need to remove any suffix. + return *end == '\0' ? v : NewStringWithSize(s, end - s); + } + + return NIL; + } + + /* ------------------------------------------------------------ * convertValue() - * Check if string v can be a Python value literal, - * (eg. number or string), or translate it to a Python literal. + * Check if string v can be a Python value literal or a + * constant. Return NIL if it isn't. * ------------------------------------------------------------ */ String *convertValue(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; + const char *const s = Char(v); + char *end; + + // 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. + return NIL; + } + + 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) + return NIL; + 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. + return convertDoubleValue(v); + } + } + } + + // 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(t)) + return NewString("None"); + else + return 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) { + String *res = NewString("0o"); + Append(res, NewStringWithSize(s + 1, end - s - 1)); + return res; + } + } + } } - if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0) - return NewString("True"); - if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) - return NewString("False"); - if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) - return SwigType_ispointer(t) ? NewString("None") : NewString("0"); + + // Avoid unnecessary string allocation in the common case when we don't + // need to remove any suffix. + return *end == '\0' ? v : NewStringWithSize(s, end - s); } - return 0; + + // Check if this is a floating point number (notice that it wasn't + // necessarily parsed as a long above, consider e.g. ".123"). + if (String *res = convertDoubleValue(v)) { + return res; + } + + if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0) + return NewString("True"); + if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) + return NewString("False"); + if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) + return SwigType_ispointer(t) ? 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). + if (!Strchr(s, ':')) { + Node *lookup = Swig_symbol_clookup(v, 0); + if (lookup) { + if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0) + return Getattr(lookup, "sym:name"); + } + } + + return NIL; } + /* ------------------------------------------------------------ - * is_primitive_defaultargs() - * Check if all the default args have primitive type. - * (So we can generate proper parameter list with default - * values..) + * is_representable_as_pyargs() + * Check if the function parameters default argument values + * can be represented in Python. + * + * If this method returns false, the parameters will be translated + * to a generic "*args" which allows us to deal with default values + * at C++ code level where they can always be handled. * ------------------------------------------------------------ */ - bool is_primitive_defaultargs(Node *n) { - ParmList *plist = CopyParmList(Getattr(n, "parms")); - Parm *p; - Parm *pnext; + bool is_representable_as_pyargs(Node *n) { + bool is_representable = true; - 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; + if (Getattr(n, "sym:overloaded")) { + ParmList *plist = CopyParmList(Getattr(n, "parms")); + Parm *p; + Parm *pnext; + + for (p = plist; p; p = pnext) { + pnext = NIL; + String *tm = Getattr(p, "tmap:in"); + if (tm) { + pnext = Getattr(p, "tmap:in:next"); + if (checkAttribute(p, "tmap:in:numinputs", "0")) { + continue; + } + } + if (!pnext) { + pnext = nextSibling(p); + } + if (String *value = Getattr(p, "value")) { + String *type = Getattr(p, "type"); + if (!convertValue(value, type)) { + is_representable = false; + break; + } } - } else { - pnext = nextSibling(p); } - String *type = Getattr(p, "type"); - String *value = Getattr(p, "value"); - if (!convertValue(value, type)) - return false; } - return true; + return is_representable; } @@ -1892,7 +2045,7 @@ public: n = nn; /* For overloaded function, just use *args */ - if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || !is_primitive_defaultargs(n)) { + if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || !is_representable_as_pyargs(n)) { String *parms = NewString(""); if (in_class) Printf(parms, "self, "); @@ -2012,7 +2165,7 @@ public: if (ret) ret = SwigType_str(ret, 0); } - return (ret && py3) ? NewStringf(" -> \"%s\" ", ret) + return (ret && py3) ? NewStringf(" -> \"%s\"", ret) : NewString(""); } @@ -2029,15 +2182,15 @@ public: /* 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, " ", docstring(n, AUTODOC_FUNC, tab4), "\n", NIL); + Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4), "\n", NIL); if (have_pythonprepend(n)) - Printv(f_dest, pythoncode(pythonprepend(n), " "), "\n", NIL); + Printv(f_dest, pythoncode(pythonprepend(n), tab4), "\n", NIL); if (have_pythonappend(n)) { - Printv(f_dest, " val = ", funcCall(name, callParms), "\n", NIL); - Printv(f_dest, pythoncode(pythonappend(n), " "), "\n", NIL); - Printv(f_dest, " return val\n", NIL); + Printv(f_dest, tab4 "val = ", funcCall(name, callParms), "\n", NIL); + Printv(f_dest, pythoncode(pythonappend(n), tab4), "\n", NIL); + Printv(f_dest, tab4 "return val\n", NIL); } else { - Printv(f_dest, " return ", funcCall(name, callParms), "\n", NIL); + Printv(f_dest, tab4 "return ", funcCall(name, callParms), "\n", NIL); } if (Getattr(n, "feature:python:callback") || !have_addtofunc(n)) { @@ -2052,7 +2205,7 @@ public: * check if using kwargs is allowed for this Node * ------------------------------------------------------------ */ - int check_kwargs(Node *n) { + int check_kwargs(Node *n) const { return (use_kw || GetFlag(n, "feature:kwargs")) && !GetFlag(n, "memberset") && !GetFlag(n, "memberget"); } @@ -2154,7 +2307,7 @@ public: Append(f->code, "--argc;\n"); } - Replaceall(dispatch, "$args", "self,args"); + Replaceall(dispatch, "$args", "self, args"); Printv(f->code, dispatch, "\n", NIL); @@ -2431,7 +2584,6 @@ public: } SwigType *pt = Getattr(p, "type"); - String *pn = Getattr(p, "name"); String *ln = Getattr(p, "lname"); bool parse_from_tuple = (i > 0 || !add_self); if (SwigType_type(pt) == T_VARARGS) { @@ -2453,18 +2605,9 @@ public: /* Keyword argument handling */ if (allow_kwargs && parse_from_tuple) { - if (Len(pn)) { - String *tmp = 0; - String *name = pn; - if (!Getattr(p, "hidden")) { - name = tmp = Swig_name_make(p, 0, pn, 0, 0); // rename parameter if a keyword - } - Printf(kwargs, "(char *) \"%s\",", name); - if (tmp) - Delete(tmp); - } else { - Printf(kwargs, "(char *)\"arg%d\",", i + 1); - } + String *name = makeParameterName(n, p, i + 1); + Printf(kwargs, "(char *) \"%s\",", name); + Delete(name); } /* Look for an input typemap */ @@ -2595,7 +2738,6 @@ public: /* Insert cleanup code */ for (p = l; p;) { - // if (!checkAttribute(p,"tmap:in:numinputs","0") && !Getattr(p,"tmap:in:parse")) { if (!Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) { if (Getattr(p, "tmap:freearg:implicitconv")) { const char *convflag = "0"; @@ -3203,7 +3345,7 @@ public: * BEGIN C++ Director Class modifications * ------------------------------------------------------------------------- */ - /* C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose <mrose@stm.lbl.gov> + /* C++/Python polymorphism demo code * * TODO * @@ -3901,7 +4043,7 @@ public: Printv(base_class, bname, NIL); b = Next(b); if (b.item) { - Putc(',', base_class); + Printv(base_class, ", ", NIL); } } } @@ -3922,7 +4064,7 @@ public: String *abcs = Getattr(n, "feature:python:abc"); if (py3 && abcs) { if (Len(base_class)) { - Putc(',', base_class); + Printv(base_class, ", ", NIL); } Printv(base_class, abcs, NIL); } @@ -3957,7 +4099,7 @@ public: if (!modern) { Printv(f_shadow, tab4, "__swig_setmethods__ = {}\n", NIL); if (Len(base_class)) { - Printf(f_shadow, "%sfor _s in [%s]: __swig_setmethods__.update(getattr(_s,'__swig_setmethods__',{}))\n", tab4, 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")) { @@ -3968,7 +4110,7 @@ public: Printv(f_shadow, tab4, "__swig_getmethods__ = {}\n", NIL); if (Len(base_class)) { - Printf(f_shadow, "%sfor _s in [%s]: __swig_getmethods__.update(getattr(_s,'__swig_getmethods__',{}))\n", tab4, 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); @@ -4056,7 +4198,7 @@ public: Delete(realct); if (!have_constructor) { if (!builtin) - Printv(f_shadow_file, tab4, "def __init__(self, *args, **kwargs): raise AttributeError(\"", "No constructor defined", + 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) { @@ -4094,12 +4236,12 @@ public: 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: self.this.append(this)\n", - tab8, "except: self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL); + tab8, "try:\n", tab8, tab4, "self.this.append(this)\n", + tab8, "except:\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: self.this.append(this)\n", - tab8, "except: self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL); + tab8, "try:\n", tab8, tab4, "self.this.append(this)\n", + tab8, "except:\n", tab8, tab4, "self.this = this\n", tab8, "self.this.own(0)\n", tab8, "self.__class__ = ", class_name, "\n\n", NIL); } } @@ -4108,7 +4250,7 @@ public: 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), + 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); } } @@ -4223,12 +4365,11 @@ public: String *callParms = make_pyParmList(n, true, true, allow_kwargs); if (!have_addtofunc(n)) { if (!fastproxy || olddefs) { - Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL); - Printv(f_shadow, " return ", funcCall(fullname, callParms), "\n", NIL); + Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); + Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n", NIL); } } else { - Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL); - Printv(f_shadow, "\n", NIL); + 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); if (have_pythonprepend(n)) { @@ -4314,7 +4455,7 @@ public: 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, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", 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); if (have_pythonprepend(n)) @@ -4326,7 +4467,9 @@ public: } else { Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n\n", NIL); } - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", symname, ")\n", NIL); + if (!modern) + Printv(f_shadow, tab4, "if _newclass:\n", tab4, NIL); + Printv(f_shadow, tab4, symname, " = staticmethod(", symname, ")\n", NIL); if (!modern) { Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", symname, "\n", NIL); @@ -4338,7 +4481,9 @@ public: NIL); } if (!classic) { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), + 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); } } @@ -4427,7 +4572,7 @@ public: Printv(pass_self, tab8, tab4, "_self = None\n", tab8, "else:\n", tab8, tab4, "_self = self\n", NIL); } - Printv(f_shadow, tab4, "def __init__(", parms, ")", returnTypeAnnotation(n), ": \n", NIL); + Printv(f_shadow, "\n", 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)) @@ -4438,7 +4583,7 @@ public: } else { Printv(f_shadow, tab8, "this = ", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), "\n", - tab8, "try: self.this.append(this)\n", tab8, "except: self.this = this\n", NIL); + tab8, "try:\n", tab8, tab4, "self.this.append(this)\n", tab8, "except:\n", tab8, tab4, "self.this = this\n", NIL); } if (have_pythonappend(n)) Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n\n", NIL); @@ -4524,7 +4669,7 @@ public: 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); + Printv(f_shadow, tab4, "__del__ = lambda self: None\n", NIL); } return SWIG_OK; } @@ -4535,7 +4680,7 @@ public: Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL); #ifdef USE_THISOWN Printv(f_shadow, tab8, "try:\n", NIL); - Printv(f_shadow, tab8, tab4, "if self.thisown: ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL); + Printv(f_shadow, tab8, tab4, "if self.thisown:", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL); Printv(f_shadow, tab8, "except: pass\n", NIL); #else #endif @@ -4573,11 +4718,12 @@ public: Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL); } if (!classic) { - if (!assignable) { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ")\n", NIL); - } else { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ", ", module, ".", setname, ")\n", NIL); - } + 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); } Delete(mname); Delete(setname); @@ -4646,11 +4792,12 @@ public: Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", getname, "\n", NIL); } if (!classic && !builtin) { - if (!assignable) { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ")\n", NIL); - } else { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = _swig_property(", module, ".", getname, ", ", module, ".", setname, ")\n", NIL); - } + 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); } String *getter = Getattr(n, "pybuiltin:getter"); String *setter = Getattr(n, "pybuiltin:setter"); @@ -4776,6 +4923,13 @@ public: return NewString("swigpyrun.h"); } + /*---------------------------------------------------------------------- + * kwargsSupport() + *--------------------------------------------------------------------*/ + + bool kwargsSupport() const { + return true; + } }; /* --------------------------------------------------------------- @@ -4813,6 +4967,16 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { int idx; bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; + if (builtin) { + // Rename any wrapped parameters called 'self' as the generated code contains a variable with same name + Parm *p; + for (p = l; p; p = nextSibling(p)) { + String *arg = Getattr(p, "name"); + if (arg && Cmp(arg, "self") == 0) + Delattr(p, "name"); + } + } + if (Cmp(storage, "virtual") == 0) { if (Cmp(value, "0") == 0) { pure_virtual = true; |