added the highly expected Robin's docstring [atch, plus some fixes and extensions. see autodoc.i

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6291 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-10-03 05:01:17 +00:00
commit 415420c4c4
4 changed files with 730 additions and 40 deletions

View file

@ -3853,5 +3853,195 @@ that has a <tt>this</tt> attribute. In addition,
<tt>SWIG_NewPointerObj()</tt> can automatically generate a proxy
class object (if applicable).
<H2><a name="Python_nn65"></a>26.10 Docstring Features</H2>
Usign docstrings in Python code is becoming more and more important
ans more tools are coming on the scene that take advantage of them,
everything from full-blown documentaiton generators to class browsers
and popup call-tips in Python-aware IDEs. Given the way that SWIG
generates the proxy code by default, your users will normally get
something like <tt>"function_name(*args)"</tt> in the popup calltip of
their IDE which is next to useless when the real function prototype
might be something like this:
<blockquote>
<pre>
bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL);
</pre>
</blockquote>
The features described in this section make it easy for you to add
docstrings to your modules, functions and methods that can then be
used by the various tools out there to make the programming experience
of your users much simpler.
<H3><a name="Python_nn66"></a>26.10.1 Module docstring</H3>
Python allows a docstring at the begining of the <tt>.py</tt> file
before any other statements, and it is typically used to give a
general description of the entire module. SWIG supports this by
setting an option of the <tt>%module</tt> directive. For example:
<blockquote>
<pre>
%module(docstring="This is the example module's docstring") example
</pre>
</blockquote>
When you have more than just a line or so then you can retain the easy
readability of the <tt>%module</tt> directive by using a macro. For
example:
<blockquote>
<pre>
%define DOCSTRING
"The `XmlResource` class allows program resources defining menus,
layout of controls on a panel, etc. to be loaded from an XML file."
%enddef
%module(docstring=DOCSTRING) xrc
</pre>
</blockquote>
<H3><a name="Python_nn67"></a>26.10.2 %feature("autodoc")</H3>
As alluded to above SWIG will generate all the function and method
proxy wrappers with just "*args" (or "*args, **kwargs" if the -keyword
option is used) for a parameter list and will then sort out the
individual parameters in the C wrapper code. This is nice and simple
for the wrapper code, but makes it difficult to be programmer and tool
friendly as anyone looking at the <tt>.py</tt> file will not be able
to find out anything about the parameters that the fuctions accept.
<p>But since SWIG does know everything about the fucntion it is
possible to generate a docstring containing the parameter types, names
and default values. Since many of the doctring tools are adopting a
standard of recognizing if the first thing in the docstring is a
function prototype then using that instead of what they found from
introspeciton, then life is good once more.
<p>SWIG's Python module provides support for the "autodoc" feature,
which when attached to a node in the parse tree will cause a docstring
to be generated that includes the name of the funciton, parameter
names, default values if any, and return type if any. There are also
three options for autodoc controlled by the value given to the
feature, described below.
<H4>%feature("autodoc", "0")</H4>
When the "0" option is given then the types of the parameters will
<em>not</em> be included in the autodoc string. For example, given
this function prototype:
<blockquote>
<pre>
%feature("autodoc", "0");
bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL);
</pre>
</blockquote>
Then Python code like this will be generated:
<blockquote>
<pre>
def function_name(*args, **kwargs):
"""function_name(x, y, foo=None, bar=None) -> bool"""
...
</pre>
</blockquote>
<H4>%feature("autodoc", "1")</H4>
When the "1" option is used then the parameter types <em>will</em> be
used in the autodoc string. In addition, an atempt is made to
simplify the type name such that it makes more sense to the Python
user. Pointer, reference and const info is removed,
<tt>%rename</tt>'s are evaluated, etc. (This is not always
successful, but works most of the time. See the next section for what
to do when it doesn't.) Given the example above, then turning on the
parameter types with the "1" option will result in Python code like
this:
<blockquote>
<pre>
def function_name(*args, **kwargs):
"""function_name(int x, int y, Foo foo=None, Bar bar=None) -> bool"""
...
</pre>
</blockquote>
<H4>%feature("autodoc", "docstring")</H4>
Finally, there are times when the automatically generated autodoc
string will make no sense for a Python programmer, particularly when a
typemap is involved. So if you give an explicit value for the autodoc
feature then that string will be used in place of the automatically
generated string. For example:
<blockquote>
<pre>
%feature("autodoc", "GetPosition() -> (x, y)") GetPosition;
void GetPosition(int* OUTPUT, int* OUTPUT);
</pre>
</blockquote>
<H3><a name="Python_nn68"></a>26.10.3 %feature("docstring")</H3>
In addition to the autodoc strings described above, you can also
attach any arbitrary descriptive text to a node in the parse tree with
the "docstring" feature. When the proxy module is generated then any
docstring associated with classes, function or methods are output.
If an item already has an autodoc string then it is combined with the
docstring and they are output together. If the docstring is all on a
single line then it is output like this::
<blockquote>
<pre>
"""This is the docstring"""
</pre>
</blockquote>
Otherwise, to aid readability it is output like this:
<blockquote>
<pre>
"""
This is a multi-line docstring
with more than one line.
"""
</pre>
</blockquote>
<H2><a name="Python_nn70"></a>26.11 Python Packages</H2>
Using the <tt>package</tt> option of the <tt>%module</tt> directive
allows you to specify what Python package that the module will be
living in when installed.
<blockquote>
<pre>
%module(package="wx") xrc
</pre>
</blockquote>
This is useful when the <tt>.i</tt> file is <tt>%import</tt>ed by
another <tt>.i</tt> file. By default SWIG will assume that the
importer is able to find the importee with just the module name, but
if they live in separate Python packages then that won't work.
However if the importee specifies what its package is with the
<tt>%module</tt> option then the Python code generated for the
importer will use that package name when importing the other module
and also in base class declarations, etc. if the pacakge name is
different than its own.
</body>
</html>

View file

@ -0,0 +1,74 @@
%module autodoc
%feature("autodoc","extended");
// especial typemap and its docs
%typemap(in) (int c, int d) "$1 =0; $2 = 0;";
%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]";
%inline {
enum Hola {
hi, hello
};
struct A
{
A(int a, short b, Hola h)
{
}
int func1(int c, int d)
{
return c;
}
int func2(A* c, double d = 2)
{
return 2;
}
};
}
// deleting typemaps and docs
%typemap(in) (int c, int d) ;
%typemap(doc) (int c, int d);
// docs for some parameters
%typemap(doc) int a "a: special comment for parameter a";
%typemap(doc) int b "b: another special comment for parameter b";
%pythoncallback(1) func_cb;
%inline {
struct B
{
B(int a, int b, Hola h)
{
}
int func(int c, int d)
{
return c;
}
};
int func(int c, int d) {
return c;
}
int funcio(int *INOUT) {
return 1;
}
int func_cb(int c, int d) {
return c;
}
}

View file

@ -58,6 +58,12 @@
* ------------------------------------------------------------ */
%include <pythonkw.swg>
/* ------------------------------------------------------------
* The Python autodoc support
* ------------------------------------------------------------ */
%include <pydocs.swg>
/* ------------------------------------------------------------
* The Python initialization function
* ------------------------------------------------------------ */

View file

@ -20,6 +20,7 @@ char cvsroot_python_cxx[] = "$Header$";
static String *const_code = 0;
static String *shadow_methods = 0;
static String *module = 0;
static String *package = 0;
static String *mainmodule = 0;
static String *interface = 0;
static String *global_name = 0;
@ -51,6 +52,16 @@ static int have_constructor;
static int have_repr;
static String *real_classname;
/* flags for the make_autodoc function */
enum autodoc_t {
AUTODOC_CLASS,
AUTODOC_CTOR,
AUTODOC_DTOR,
AUTODOC_STATICFUNC,
AUTODOC_FUNC,
AUTODOC_METHOD
};
static const char *usage = (char *)"\
Python Options (available with -python)\n\
-globals <name> - Set <name> used to access C global variable [default: 'cvar']\n\
@ -146,10 +157,11 @@ public:
* use %module(directors="1") modulename at the start of the
* interface file to enable director generation.
*/
String* mod_docstring = NULL;
{
Node *module = Getattr(n, "module");
if (module) {
Node *options = Getattr(module, "options");
Node *mod = Getattr(n, "module");
if (mod) {
Node *options = Getattr(mod, "options");
if (options) {
if (Getattr(options, "directors")) {
allow_directors();
@ -157,6 +169,8 @@ public:
if (Getattr(options, "dirprot")) {
allow_dirprot();
}
mod_docstring = Getattr(options, "docstring");
package = Getattr(options, "package");
}
}
}
@ -258,6 +272,11 @@ public:
"# This file is compatible with both classic and new-style classes.\n",
NIL);
}
if (mod_docstring && Len(mod_docstring)) {
Printv(f_shadow, "\n\"\"\"\n", mod_docstring, "\n\"\"\"\n", NIL);
Delete(mod_docstring); mod_docstring = NULL;
}
Printf(f_shadow,"\nimport %s\n\n", module);
@ -399,7 +418,25 @@ public:
if (shadow) {
String *modname = Getattr(n,"module");
if (modname) {
Printf(f_shadow,"import %s\n", modname);
Printf(f_shadow,"import ");
// Find the module node for this imported module. It should be the
// first child but search just in case.
Node* mod = firstChild(n);
while (mod && Strcmp(nodeType(mod), "module") != 0)
mod = nextSibling(mod);
// Is the imported module in another package? (IOW, does it use the
// %module(package="name") option and it's different than the package
// of this module.)
Node *options = Getattr(mod, "options");
String* pkg = options ? Getattr(options, "package") : 0;
if (pkg && (!package || Strcmp(pkg, package) != 0)) {
Printf(f_shadow, "%s.", pkg);
}
// finally, output the name of the imported module
Printf(f_shadow, "%s\n", modname);
}
}
return Language::importDirective(n);
@ -429,6 +466,9 @@ public:
int functionHandler(Node *n) {
if (checkAttribute(n,"feature:python:callback","1")) {
Setattr(n,"feature:callback","%s_cb_ptr");
if (checkAttribute(n,"feature:autodoc","extended")) {
Setattr(n,"feature:autodoc","1");
}
}
return Language::functionHandler(n);
@ -449,9 +489,17 @@ public:
} 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);
if ( have_docstring(n) )
Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4), "\n", NIL);
if ( have_pythonprepend(n) )
Printv(f_dest, tab4, pythonprepend(n), "\n", NIL);
if ( have_pythonappend(n) ) {
Printv(f_dest, tab4, "val = ", funcCallHelper(name, kw), "\n", NIL);
Printv(f_dest, tab4, pythonappend(n), "\n", NIL);
Printv(f_dest, tab4, "return val\n", NIL);
} else {
Printv(f_dest, tab4, "return ", funcCallHelper(name, kw), "\n", NIL);
}
}
}
@ -467,22 +515,314 @@ public:
/* ------------------------------------------------------------
* have_addtofunc()
* Check if there is a %addtofunc directive and it has text
* have_docstring()
* Check if there is a docstring directive and it has text,
* or there is an autodoc flag set
* ------------------------------------------------------------ */
bool have_addtofunc(Node *n) {
String* str = Getattr(n, "feature:addtofunc");
bool have_docstring(Node *n) {
String* str = Getattr(n, "feature:docstring");
return (str != NULL && Len(str) > 0) ||
(Getattr(n,"feature:autodoc") && !Getattr(n, "feature:noautodoc"));
}
/* ------------------------------------------------------------
* docstring()
* Get the docstring text, stripping off {} if neccessary,
* 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 use_triple = true) {
String* str = Getattr(n, "feature:docstring");
bool have_ds = (str != NULL && Len(str) > 0);
bool have_auto = (Getattr(n,"feature:autodoc") && !Getattr(n, "feature:noautodoc"));
const char* triple_double = use_triple ? "\"\"\"" : "";
String* autodoc = NULL;
String* doc = NULL;
if ( have_ds ) {
char* t = Char(str);
if (*t == '{') {
Delitem(str ,0);
Delitem(str,DOH_END);
}
}
if ( have_auto ) {
autodoc = make_autodoc(n, ad_type);
have_auto = (autodoc != NULL && Len(autodoc) > 0);
}
// If there is more than one line then make docstrings like this:
//
// """
// This is line1
// And here is line2 followed by the rest of them
// """
//
// otherwise, put it all on a single line
//
if ( have_auto && have_ds ) { // Both autodoc and docstring are present
doc = NewString("");
Printv(doc, triple_double, "\n",
pythoncode(autodoc, indent), "\n",
pythoncode(str, indent),
indent, triple_double, NIL);
}
else if ( !have_auto && have_ds ) { // only docstring
if (Strchr(str, '\n') == NULL) {
doc = NewStringf("%s%s%s", triple_double, str, triple_double);
}
else {
doc = NewString("");
Printv(doc, triple_double, "\n",
pythoncode(str, indent),
indent, triple_double, NIL);
}
}
else if ( have_auto && !have_ds ) { // only autodoc
if (Strchr(autodoc, '\n') == NULL) {
doc = NewStringf("%s%s%s", triple_double, autodoc, triple_double);
}
else {
doc = NewString("");
Printv(doc, triple_double, "\n",
pythoncode(autodoc, indent),
indent, triple_double, NIL);
}
}
else
doc = NewString("");
// 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;
}
/* ------------------------------------------------------------
* make_autodoc()
* Build a docstring for the node, using parameter and other
* info in the parse tree. If the value of the autodoc
* attribute is "0" then do not include parameter types, if
* it is "1" (the default) then do. If it has some other
* value then assume it is supplied by the extension writer
* and use it directly.
* ------------------------------------------------------------ */
String* make_autodoc(Node *n, autodoc_t ad_type) {
int extended = 0;
// If the function is overloaded then this funciton is called
// for the last one. Rewind to the first so the docstrings are
// in order.
while ( Getattr(n, "sym:previousSibling") )
n = Getattr(n, "sym:previousSibling");
String* doc = NewString("");
while (n) {
bool showTypes = false;
bool skipAuto = false;
// check how should the parameters be rendered?
String* autodoc = Getattr(n, "feature:autodoc");
if (Strcmp(autodoc, "0") == 0)
showTypes = false;
else if (Strcmp(autodoc, "1") == 0)
showTypes = true;
else if (Strcmp(autodoc, "extended") == 0) {
extended = 1;
showTypes = false;
} else {
// if not "0" or "1" then autodoc is already the string that should be used
Printf(doc, "%s", autodoc);
skipAuto = true;
}
if (!skipAuto) {
String* symname = Getattr(n, "sym:name");
SwigType* type = Getattr(n, "type");
if (type) {
if (Strcmp(type, "void") == 0)
type = NULL;
else {
SwigType* qt = SwigType_typedef_resolve_all(type);
if (SwigType_isenum(qt))
type = NewString("int");
else {
type = SwigType_base(type);
Node* lookup = Swig_symbol_clookup(type, 0);
if (lookup)
type = Getattr(lookup, "sym:name");
}
}
}
switch ( ad_type ) {
case AUTODOC_CLASS:
Printf(doc, "Automatic wrap of C/C++ '%s' type", class_name);
break;
case AUTODOC_CTOR:
if ( Strcmp(class_name, symname) == 0) {
String* paramList = make_autodocParmList(n, showTypes);
if (Len(paramList))
Printf(doc, "__init__(self, %s) -> %s", paramList, class_name);
else
Printf(doc, "__init__(self) -> %s", class_name);
}
else
Printf(doc, "%s(%s) -> %s", symname, make_autodocParmList(n, showTypes), class_name);
break;
case AUTODOC_DTOR:
Printf(doc, "__del__(self)");
break;
case AUTODOC_STATICFUNC:
Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
if (type) Printf(doc, " -> %s", type);
break;
case AUTODOC_FUNC:
Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes));
if (type) Printf(doc, " -> %s", type);
break;
case AUTODOC_METHOD:
String* paramList = make_autodocParmList(n, showTypes);
if (Len(paramList))
Printf(doc, "%s(self, %s)", symname, paramList);
else
Printf(doc, "%s(self)", symname);
if (type) Printf(doc, " -> %s", type);
break;
}
}
if (extended) {
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)
Printf(doc, "\n");
}
return doc;
}
String* make_autodocParmList(Node* n, bool showTypes) {
String* doc = NewString("");
String* pdocs = Copy(Getattr(n,"feature:pdocs"));
ParmList* plist = Getattr(n,"parms");
Parm* p;
Parm* pnext;
Node* lookup;
int lines = 0;
const int maxwidth = 50;
if (pdocs) Printf(pdocs, "\n");
Swig_typemap_attach_parms("in",plist,0);
Swig_typemap_attach_parms("doc",plist,0);
for (p = plist; p; p = pnext) {
String* name = 0;
String* type = 0;
String* value = 0;
String* ptype = 0;
String* pdoc = Getattr(p, "tmap:doc");
if (pdoc) {
name = Getattr(p, "tmap:doc:name");
type = Getattr(p, "tmap:doc:type");
value = Getattr(p, "tmap:doc:value");
ptype = Getattr(p, "tmap:doc:pytype");
}
name = name ? name : Getattr(p,"name");
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);
}
if ( Len(doc) ) {
// add a comma to the previous one if any
Printf(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?
if (showTypes) {
type = SwigType_base(type);
lookup = Swig_symbol_clookup(type, 0);
if (lookup) type = Getattr(lookup, "sym:name");
Printf(doc, "%s ", type);
}
if (name) {
Printf(doc, "%s", name);
if (pdoc) {
if (!pdocs) pdocs = NewString("Parameters:\n");
Printf(pdocs, " %s\n", pdoc);
}
} else {
Printf(doc, "??");
}
if (value) {
if (Strcmp(value, "NULL") == 0)
value = NewString("None");
else {
lookup = Swig_symbol_clookup(value, 0);
if (lookup)
value = Getattr(lookup, "sym:name");
}
Printf(doc, "=%s", value);
}
}
if (pdocs) Setattr(n,"feature:pdocs", pdocs);
return doc;
}
/* ------------------------------------------------------------
* have_pythonprepend()
* Check if there is a %pythonprepend directive and it has text
* ------------------------------------------------------------ */
bool have_pythonprepend(Node *n) {
String* str = Getattr(n, "feature:pythonprepend");
return (str != NULL && Len(str) > 0);
}
/* ------------------------------------------------------------
* addtofunc()
* Get the %addtofunc code, stripping off {} if neccessary
* pythonprepend()
* Get the %pythonprepend code, stripping off {} if neccessary
* ------------------------------------------------------------ */
String *addtofunc(Node *n) {
String* str = Getattr(n, "feature:addtofunc");
String *pythonprepend(Node *n) {
String* str = Getattr(n, "feature:pythonprepend");
char* t = Char(str);
if (*t == '{') {
Delitem(str ,0);
@ -491,6 +831,44 @@ public:
return str;
}
/* ------------------------------------------------------------
* have_pythonappend()
* Check if there is a %pythonappend directive and it has text
* ------------------------------------------------------------ */
bool have_pythonappend(Node *n) {
String* str = Getattr(n, "feature:pythonappend");
if (!str) str = Getattr(n, "feature:addtofunc");
return (str != NULL && Len(str) > 0);
}
/* ------------------------------------------------------------
* pythonappend()
* Get the %pythonappend code, stripping off {} if neccessary
* ------------------------------------------------------------ */
String *pythonappend(Node *n) {
String* str = Getattr(n, "feature:pythonappend");
if (!str) str = Getattr(n, "feature:addtofunc");
char* t = Char(str);
if (*t == '{') {
Delitem(str ,0);
Delitem(str,DOH_END);
}
return str;
}
/* ------------------------------------------------------------
* have_addtofunc()
* Check if there is a %addtofunc directive and it has text
* ------------------------------------------------------------ */
bool have_addtofunc(Node *n) {
return have_pythonappend(n) || have_pythonprepend(n) || have_docstring(n);
}
/* ------------------------------------------------------------
* add_method()
* ------------------------------------------------------------ */
@ -502,7 +880,13 @@ public:
Printf(methods,"\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS, ", name, function);
if (n && Getattr(n,"feature:callback")) {
Printf(methods,"\"swig_ptr: %s\"", Getattr(n,"feature:callback:name"));
if (have_docstring(n)) {
Printf(methods,"\"%s\\nswig_ptr: %s\"",
docstring(n, AUTODOC_FUNC, "", false),
Getattr(n,"feature:callback:name"));
} else {
Printf(methods,"\"swig_ptr: %s\"",Getattr(n,"feature:callback:name"));
}
} else {
Printf(methods,"NULL");
}
@ -1726,17 +2110,21 @@ public:
* ------------------------------------------------------------ */
virtual int classDeclaration(Node *n) {
String *importname;
Node *mod;
if (shadow) {
mod = Getattr(n,"module");
Node *mod = Getattr(n,"module");
if (mod) {
String *importname = NewString("");
String *modname = Getattr(mod,"name");
if (Strcmp(modname,mainmodule) != 0) {
importname = NewStringf("%s.%s", modname, Getattr(n,"sym:name"));
} else {
importname = NewString(Getattr(n,"sym:name"));
// check if the module has a package option
Node *options = Getattr(mod, "options");
String* pkg = options ? Getattr(options, "package") : 0;
if (pkg && (!package || Strcmp(pkg, package) != 0)) {
Printf(importname,"%s.", pkg);
}
Printf(importname,"%s.", modname);
}
Printf(importname,"%s", Getattr(n,"sym:name"));
Setattr(n,"python:proxy",importname);
}
}
@ -1807,7 +2195,9 @@ public:
}
}
Printf(f_shadow,":\n");
if ( have_docstring(n) )
Printv(f_shadow, tab4, docstring(n, AUTODOC_CLASS, tab4), "\n", NIL);
if (!modern) {
Printv(f_shadow,tab4,"__swig_setmethods__ = {}\n",NIL);
if (Len(base_class)) {
@ -1969,14 +2359,23 @@ public:
Printv(f_shadow,pycode,"\n",NIL);
} else {
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);
} else {
if (!have_addtofunc(n)) {
Printv(f_shadow, "return ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL);
} else {
Printv(f_shadow, "\n", NIL);
if ( have_docstring(n) )
Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, 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), allow_kwargs), "\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);
}
}
}
}
}
}
return SWIG_OK;
@ -1990,12 +2389,20 @@ public:
String *symname = Getattr(n,"sym:name");
Language::staticmemberfunctionHandler(n);
if (shadow) {
if ( !classic && have_addtofunc(n) ) {
if ( !classic && (have_pythonprepend(n) || have_pythonappend(n) || have_docstring(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);
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, 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, tab4, modern ? "" : "if _newclass:", symname,
" = staticmethod(", symname, ")\n", NIL);
@ -2082,6 +2489,10 @@ public:
Printv(f_shadow, tab4, "def __init__(self, *args",
(allow_kwargs ? ", **kwargs" : ""), "):\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 (!modern) {
Printv(f_shadow, tab8, "_swig_setattr(self, ", rclassname, ", 'this', ",
@ -2096,8 +2507,8 @@ public:
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);
if ( have_pythonappend(n) )
Printv(f_shadow, tab8, pythonappend(n), "\n\n", NIL);
Delete(pass_self);
}
have_constructor = 1;
@ -2115,11 +2526,15 @@ public:
Printv(f_shadow_stubs, "\ndef ", symname, "(*args",
(allow_kwargs ? ", **kwargs" : ""), "):\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.thisown = 1\n", NIL);
if ( have_addtofunc(n) )
Printv(f_shadow_stubs, tab4, addtofunc(n), "\n", NIL);
if ( have_pythonappend(n) )
Printv(f_shadow_stubs, tab4, pythonappend(n), "\n", NIL);
Printv(f_shadow_stubs, tab4, "return val\n", NIL);
}
}
@ -2148,11 +2563,16 @@ public:
Printv(f_shadow,pycode,"\n", NIL);
} else {
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);
if ( have_docstring(n) )
Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL);
if ( have_pythonprepend(n) )
Printv(f_shadow, tab8, pythonprepend(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, tab4, "if self.thisown: destroy(self)\n", NIL);
Printv(f_shadow, tab8, "except: pass\n", NIL);
if ( have_pythonappend(n) )
Printv(f_shadow, tab8, pythonappend(n), "\n", NIL);
Printv(f_shadow, "\n", NIL);
}
}
return SWIG_OK;