Index: Source/Modules/python.cxx =================================================================== RCS file: /cvsroot/SWIG/Source/Modules/python.cxx,v retrieving revision 1.25 diff -u -r1.25 python.cxx --- Source/Modules/python.cxx 23 Sep 2003 21:26:04 -0000 1.25 +++ Source/Modules/python.cxx 30 Oct 2003 02:39:33 -0000 @@ -292,6 +292,9 @@ 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 = 0; /* C++ Support + Shadow Classes */ @@ -306,6 +309,9 @@ -interface - Set the lib name to \n\ -keyword - Use keyword arguments\n\ -classic - Use classic classes only\n\ + -modern - Use modern python features only, without compatibility code\n\ + -apply - Use apply() in proxy classes\n\ + -new_repr - Use more informative version of __repr__ in proxy classes\n\ -noexcept - No automatic exception handling\n\ -noproxy - Don't generate proxy classes \n\n"; @@ -344,6 +350,12 @@ } 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) { + new_repr = 1; + Swig_mark_arg(i); } else if ((strcmp(argv[i],"-noproxy") == 0)) { shadow = 0; Swig_mark_arg(i); @@ -353,6 +365,10 @@ } else if (strcmp(argv[i],"-classic") == 0) { classic = 1; Swig_mark_arg(i); + } else if (strcmp(argv[i],"-modern") == 0) { + classic = 0; + modern = 1; + Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); } else if (strcmp (argv[i], "-ldflags") == 0) { @@ -480,47 +496,54 @@ Printv(f_shadow, "# This file was created automatically by SWIG.\n", "# Don't modify this file, modify the SWIG interface instead.\n", - "# This file is compatible with both classic and new-style classes.\n", NIL); - Printf(f_shadow,"import %s\n", module); - - // Python-2.2 object hack - - Printv(f_shadow, - "def _swig_setattr(self,class_type,name,value):\n", - tab4, "if (name == \"this\"):\n", - tab4, tab4, "if isinstance(value, class_type):\n", - tab4, tab8, "self.__dict__[name] = value.this\n", - tab4, tab8, "if hasattr(value,\"thisown\"): self.__dict__[\"thisown\"] = value.thisown\n", - tab4, tab8, "del value.thisown\n", - tab4, tab8, "return\n", - // tab8, "if (name == \"this\") or (name == \"thisown\"): self.__dict__[name] = value; return\n", - tab4, "method = class_type.__swig_setmethods__.get(name,None)\n", - tab4, "if method: return method(self,value)\n", - tab4, "self.__dict__[name] = value\n\n", - NIL); + if (! modern) { + Printv(f_shadow, + "# This file is compatible with both classic and new-style classes.\n", + NIL); + } + + Printf(f_shadow,"\nimport %s\n\n", module); - Printv(f_shadow, - "def _swig_getattr(self,class_type,name):\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); + if (! modern) { + // Python-2.2 object hack + Printv(f_shadow, + "def _swig_setattr(self,class_type,name,value):\n", + tab4, "if (name == \"this\"):\n", + tab4, tab4, "if isinstance(value, class_type):\n", + tab4, tab8, "self.__dict__[name] = value.this\n", + tab4, tab8, "if hasattr(value,\"thisown\"): self.__dict__[\"thisown\"] = value.thisown\n", + tab4, tab8, "del value.thisown\n", + tab4, tab8, "return\n", + // tab8, "if (name == \"this\") or (name == \"thisown\"): self.__dict__[name] = value; return\n", + tab4, "method = class_type.__swig_setmethods__.get(name,None)\n", + tab4, "if method: return method(self,value)\n", + tab4, "self.__dict__[name] = value\n\n", + NIL); - if (!classic) { - Printv(f_shadow, - "import types\n", - "try:\n", - " _object = types.ObjectType\n", - " _newclass = 1\n", - "except AttributeError:\n", - " class _object : pass\n", - " _newclass = 0\n", - "\n\n", - NIL); + Printv(f_shadow, + "def _swig_getattr(self,class_type,name):\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); + + if (!classic) { + Printv(f_shadow, + "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); + } } - + if (directorsEnabled()) { // Try loading weakref.proxy, which is only available in Python 2.1 and higher Printv(f_shadow, @@ -610,6 +633,83 @@ 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. + * ------------------------------------------------------------ */ + + 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); + } + return str; + } + + + /* ------------------------------------------------------------ + * emitFunctionShadowHelper() + * Refactoring some common code out of functionWrapper and + * dispatchFunction that writes the proxy code for non-member + * functions. + * ------------------------------------------------------------ */ + + void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) { + if ( ! have_addtofunc(n) ) { + /* If there is no addtofunc directive then just assign from the extension module */ + Printv(f_dest, "\n", name, " = ", module, ".", name, "\n", NIL); + } else { + /* Otherwise make a wrapper function to insert the code into */ + Printv(f_dest, "\ndef ", name, "(*args", (kw ? ", **kwargs" : ""), "):\n", NIL); + Printv(f_dest, tab4, "val = ", funcCallHelper(name, kw), "\n", NIL); + Printv(f_dest, tab4, addtofunc(n), "\n", NIL); + Printv(f_dest, tab4, "return val\n", NIL); + } + } + + + /* ------------------------------------------------------------ + * check_kwargs() + * check if using kwargs is allowed for this Node + * ------------------------------------------------------------ */ + + int check_kwargs(Node *n) { + return ((use_kw || Getattr(n,"feature:kwargs")) && !Getattr(n, "feature:nokwargs")) ? 1 : 0; + } + + + /* ------------------------------------------------------------ + * have_addtofunc() + * Check if there is a %addtofunc directive and it has text + * ------------------------------------------------------------ */ + + bool have_addtofunc(Node *n) { + String* str = Getattr(n, "feature:addtofunc"); + return (str != NULL && Len(str) > 0); + } + + /* ------------------------------------------------------------ + * addtofunc() + * Get the %addtofunc code, stripping off {} if neccessary + * ------------------------------------------------------------ */ + + String *addtofunc(Node *n) { + String* str = Getattr(n, "feature:addtofunc"); + char* t = Char(str); + if (*t == '{') { + Delitem(str ,0); + Delitem(str,DOH_END); + } + return str; + } + /* ------------------------------------------------------------ * add_method() * ------------------------------------------------------------ */ @@ -650,7 +750,7 @@ int num_required; int num_arguments; int varargs = 0; - int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0; + int allow_kwargs = check_kwargs(n); /* member of a director class? */ String *nodeType = Getattr(n, "nodeType"); @@ -1007,11 +1107,7 @@ /* Create a shadow for this function (if enabled and not in a member function) */ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - if (in_class) { - Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n\n", NIL); - } else { - Printv(f_shadow,iname, " = ", module, ".", iname, "\n\n", NIL); - } + emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs); } } else { if (!Getattr(n,"sym:nextSibling")) { @@ -1068,7 +1164,7 @@ /* Create a shadow for this function (if enabled and not in a member function) */ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { - Printv(f_shadow_stubs,symname, " = ", module, ".", symname, "\n\n", NIL); + emitFunctionShadowHelper(n, f_shadow_stubs, symname, 0); } DelWrapper(f); Delete(dispatch); @@ -1754,6 +1850,7 @@ virtual int classHandler(Node *n) { int oldclassic = classic; + int oldmodern = modern; if (shadow) { @@ -1763,8 +1860,16 @@ if (Getattr(n,"cplus:exceptionclass")) { classic = 1; + modern = 0; + } + if (Getattr(n,"feature:classic")) { + classic = 1; + modern = 0; + } + if (Getattr(n,"feature:modern")) { + classic = 0; + modern = 1; } - if (Getattr(n,"feature:classic")) classic = 1; shadow_indent = (String *) tab4; @@ -1798,30 +1903,32 @@ Printf(f_shadow,"(%s)", base_class); } else { if (!classic) { - Printf(f_shadow,"(_object)"); + Printf(f_shadow, modern ? "(object)" : "(_object)"); } } Printf(f_shadow,":\n"); - Printv(f_shadow,tab4,"__swig_setmethods__ = {}\n",NIL); - if (Len(base_class)) { - Printf(f_shadow,"%sfor _s in [%s]: __swig_setmethods__.update(_s.__swig_setmethods__)\n",tab4,base_class); - } + if (!modern) { + Printv(f_shadow,tab4,"__swig_setmethods__ = {}\n",NIL); + if (Len(base_class)) { + Printf(f_shadow,"%sfor _s in [%s]: __swig_setmethods__.update(_s.__swig_setmethods__)\n",tab4,base_class); + } - Printv(f_shadow, - tab4, "__setattr__ = lambda self, name, value: _swig_setattr(self, ", class_name, ", name, value)\n", - NIL); + Printv(f_shadow, + tab4, "__setattr__ = lambda self, name, value: _swig_setattr(self, ", class_name, ", name, value)\n", + NIL); - Printv(f_shadow,tab4,"__swig_getmethods__ = {}\n",NIL); - if (Len(base_class)) { - Printf(f_shadow,"%sfor _s in [%s]: __swig_getmethods__.update(_s.__swig_getmethods__)\n",tab4,base_class); - } + Printv(f_shadow,tab4,"__swig_getmethods__ = {}\n",NIL); + if (Len(base_class)) { + Printf(f_shadow,"%sfor _s in [%s]: __swig_getmethods__.update(_s.__swig_getmethods__)\n",tab4,base_class); + } - Printv(f_shadow, - tab4, "__getattr__ = lambda self, name: _swig_getattr(self, ", class_name, ", name)\n", - NIL); + Printv(f_shadow, + tab4, "__getattr__ = lambda self, name: _swig_getattr(self, ", class_name, ", name)\n", + NIL); + } } - + /* Emit all of the members */ in_class = 1; @@ -1853,21 +1960,37 @@ if (!have_repr) { /* Supply a repr method for this class */ - Printv(f_shadow, - tab4, "def __repr__(self):\n", - tab8, "return \"\" % (self.this,)\n", - NIL); + if (new_repr) { + Printv(f_shadow, + tab4, "def __repr__(self):\n", + tab8, "return \"<%s.%s; proxy of ", CPlusPlus ? "C++ " : "C ", real_classname," instance at %s>\" % (self.__class__.__module__, self.__class__.__name__, self.this,)\n", + NIL); + } + else { + Printv(f_shadow, + tab4, "def __repr__(self):\n", + tab8, "return \"\" % (self.this,)\n", + NIL); + } } - /* Now build the real class with a normal constructor */ + /* Now the Ptr class */ Printv(f_shadow, "\nclass ", class_name, "Ptr(", class_name, "):\n", - tab4, "def __init__(self,this):\n", - tab8, "_swig_setattr(self, ", class_name, ", 'this', this)\n", - tab8, "if not hasattr(self,\"thisown\"): _swig_setattr(self, ", class_name, ", 'thisown', 0)\n", + tab4, "def __init__(self, this):\n", NIL); + if (!modern) { + Printv(f_shadow, + tab8, "_swig_setattr(self, ", class_name, ", 'this', this)\n", + tab8, "if not hasattr(self,\"thisown\"): _swig_setattr(self, ", class_name, ", 'thisown', 0)\n", + tab8, "_swig_setattr(self, ", class_name, ",self.__class__,", class_name, ")\n", + NIL); + } else { + Printv(f_shadow, + tab8, "self.this = this\n", + tab8, "if not hasattr(self,\"thisown\"): self.thisown = 0\n", + tab8, "self.__class__ = ", class_name, "\n", NIL); // tab8,"try: self.this = this.this; self.thisown = getattr(this,'thisown',0); this.thisown=0\n", // tab8,"except AttributeError: self.this = this\n" - tab8, "_swig_setattr(self, ", class_name, ",self.__class__,", class_name, ")\n", - NIL); + } Printf(f_shadow,"%s.%s_swigregister(%sPtr)\n", module, class_name, class_name,0); shadow_indent = 0; @@ -1875,6 +1998,7 @@ Clear(f_shadow_stubs); } classic = oldclassic; + modern = oldmodern; return SWIG_OK; } @@ -1894,7 +2018,7 @@ if (!Getattr(n,"sym:nextSibling")) { if (shadow) { - int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0; + int allow_kwargs = (check_kwargs(n) && !Getattr(n,"sym:overloaded")) ? 1 : 0; if (Strcmp(symname,"__repr__") == 0) have_repr = 1; @@ -1902,14 +2026,18 @@ String *pycode = pythoncode(Getattr(n,"feature:shadow"),tab4); Printv(f_shadow,pycode,"\n",NIL); } else { - if (allow_kwargs && !Getattr(n,"sym:overloaded")) { - Printv(f_shadow,tab4, "def ", symname, "(*args, **kwargs): ", NIL); - Printv(f_shadow, "return apply(", module, ".", Swig_name_member(class_name,symname), ",args, kwargs)\n", NIL); - } else { - Printv(f_shadow, tab4, "def ", symname, "(*args): ", NIL); - Printv(f_shadow, "return apply(", module, ".", Swig_name_member(class_name,symname), ",args)\n",NIL); - } - } + + Printv(f_shadow, tab4, "def ", symname, "(*args", (allow_kwargs ? ", **kwargs" : ""), "): ", NIL); + if ( have_addtofunc(n) ) { + Printv(f_shadow, "\n", NIL); + Printv(f_shadow, tab8, "val = ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL); + Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); + Printv(f_shadow, tab8, "return val\n", NIL); + } else { + Printv(f_shadow, "return ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL); + } + } + } } return SWIG_OK; @@ -1923,10 +2051,28 @@ String *symname = Getattr(n,"sym:name"); Language::staticmemberfunctionHandler(n); if (shadow) { - Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(class_name, symname), "\n", NIL); - if (!classic) { - Printv(f_shadow, tab4, "if _newclass:", symname, " = staticmethod(", module, ".", - Swig_name_member(class_name, symname), ")\n", NIL); + if ( !classic && 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); + Printv(f_shadow, tab8, "val = ", funcCallHelper(Swig_name_member(class_name, symname), kw), "\n", NIL); + Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); + Printv(f_shadow, tab8, "return val\n", NIL); + Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, + " = staticmethod(", symname, ")\n", NIL); + + if (!modern) { + Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", symname, "\n", NIL); + } + + } else { + if (!modern) { + Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(class_name, symname), "\n", NIL); + } + if (!classic) { + Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, + " = staticmethod(", module, ".", + Swig_name_member(class_name, symname), ")\n", NIL); + } } } return SWIG_OK; @@ -1972,7 +2118,7 @@ if (!Getattr(n,"sym:nextSibling")) { if (shadow) { - int allow_kwargs = (use_kw || Getattr(n,"feature:kwargs")) ? 1 : 0; + int allow_kwargs = (check_kwargs(n) && (!Getattr(n,"sym:overloaded"))) ? 1 : 0; if (!have_constructor) { if (Getattr(n,"feature:shadow")) { String *pycode = pythoncode(Getattr(n,"feature:shadow"),tab4); @@ -1991,18 +2137,25 @@ tab8, tab4, "args = (self,) + args\n", NIL); } - if ((allow_kwargs) && (!Getattr(n,"sym:overloaded"))) { - Printv(f_shadow, tab4, "def __init__(self,*args,**kwargs):\n", NIL); - Printv(f_shadow, pass_self, NIL); - Printv(f_shadow, tab8, "_swig_setattr(self, ", rclassname, ", 'this', apply(", module, ".", Swig_name_construct(symname), ",args, kwargs))\n", NIL); - } else { - Printv(f_shadow, tab4, "def __init__(self,*args):\n",NIL); - Printv(f_shadow, pass_self, NIL); - Printv(f_shadow, tab8, "_swig_setattr(self, ", rclassname, ", 'this', apply(", module, ".", Swig_name_construct(symname), ",args))\n", NIL); - } - Printv(f_shadow, - tab8, "_swig_setattr(self, ", rclassname, ", 'thisown', 1)\n", - NIL); + + Printv(f_shadow, tab4, "def __init__(self, *args", + (allow_kwargs ? ", **kwargs" : ""), "):\n", NIL); + Printv(f_shadow, pass_self, NIL); + if (!modern) { + Printv(f_shadow, tab8, "_swig_setattr(self, ", rclassname, ", 'this', ", + funcCallHelper(Swig_name_construct(symname), allow_kwargs), ")\n", NIL); + Printv(f_shadow, + tab8, "_swig_setattr(self, ", rclassname, ", 'thisown', 1)\n", + NIL); + } else { + Printv(f_shadow, tab8, "newobj = ", + funcCallHelper(Swig_name_construct(symname), allow_kwargs), "\n", NIL); + Printv(f_shadow, tab8, "self.this = newobj.this\n", NIL); + Printv(f_shadow, tab8, "self.thisown = 1\n", NIL); + Printv(f_shadow, tab8, "del newobj.thisown\n", NIL); + } + if ( have_addtofunc(n) ) + Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); Delete(pass_self); } have_constructor = 1; @@ -2014,19 +2167,16 @@ String *pycode = pythoncode(Getattr(n,"feature:shadow"),""); Printv(f_shadow_stubs,pycode,"\n",NIL); } else { - if ((allow_kwargs) && (!Getattr(n,"sym:overloaded"))) - Printv(f_shadow_stubs, "def ", symname, "(*args,**kwargs):\n", NIL); - else - Printv(f_shadow_stubs, "def ", symname, "(*args):\n", NIL); - - Printv(f_shadow_stubs, tab4, "val = apply(", NIL); - if ((allow_kwargs) && (!Getattr(n,"sym:overloaded"))) - Printv(f_shadow_stubs, module, ".", Swig_name_construct(symname), ",args,kwargs)\n", NIL); - else - Printv(f_shadow_stubs, module, ".", Swig_name_construct(symname), ",args)\n", NIL); - Printv(f_shadow_stubs,tab4, "val.thisown = 1\n", - tab4, "return val\n\n", NIL); - } + + Printv(f_shadow_stubs, "\ndef ", symname, "(*args", + (allow_kwargs ? ", **kwargs" : ""), "):\n", NIL); + Printv(f_shadow_stubs, tab4, "val = ", + funcCallHelper(Swig_name_construct(symname), allow_kwargs), "\n", NIL); + Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL); + if ( have_addtofunc(n) ) + Printv(f_shadow_stubs, tab4, addtofunc(n), "\n", NIL); + Printv(f_shadow_stubs, tab4, "return val\n", NIL); + } } } } @@ -2045,7 +2195,9 @@ Language::destructorHandler(n); shadow = oldshadow; if (shadow) { - Printv(f_shadow, tab4, "def __del__(self, destroy= ", module, ".", Swig_name_destroy(symname), "):\n", NIL); + Printv(f_shadow, tab4, "def __del__(self, destroy=", module, ".", Swig_name_destroy(symname), "):\n", NIL); + if ( have_addtofunc(n) ) + Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); Printv(f_shadow, tab8, "try:\n", NIL); Printv(f_shadow, tab4, tab8, "if self.thisown: destroy(self)\n", NIL); Printv(f_shadow, tab8, "except: pass\n", NIL); @@ -2066,21 +2218,22 @@ shadow = oldshadow; if (shadow) { - int immutable = 0; - if (!Getattr(n,"feature:immutable")) { - Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)), "\n", NIL); - } else { - immutable = 1; + int immutable = (Getattr(n,"feature:immutable") != NULL); + if (!modern) { + if (!immutable) { + Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)), "\n", NIL); + } + Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),"\n", NIL); } - Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),"\n", NIL); - if (!classic) { if (immutable) { - Printv(f_shadow,tab4,"if _newclass:", symname," = property(", module, ".", + Printv(f_shadow,tab4, modern ? "" : "if _newclass:", + symname," = property(", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),")\n", NIL); } else { - Printv(f_shadow,tab4,"if _newclass:", symname," = property(", - module, ".", Swig_name_get(Swig_name_member(class_name,symname)),",", + Printv(f_shadow,tab4, modern ? "" : "if _newclass:", + symname," = property(", + module, ".", Swig_name_get(Swig_name_member(class_name,symname)),", ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)),")\n", NIL); } } @@ -2142,8 +2295,9 @@ Delitem(temp,0); Delitem(temp,DOH_END); } + /* Split the input text into lines */ - List *clist = DohSplit(temp,'\n',-1); + List *clist = DohSplitLines(temp); Delete(temp); int initial = 0; String *s = 0; @@ -2194,7 +2348,7 @@ if ((!ImportMode) && ((Cmp(section,"python") == 0) || (Cmp(section,"shadow") == 0))) { if (shadow) { String *pycode = pythoncode(code,shadow_indent); - Printv(f_shadow, pycode, "\n", NIL); + Printv(f_shadow, pycode, NIL); Delete(pycode); } } else {