diff --git a/CHANGES.current b/CHANGES.current index 3fab761b8..269c71bf7 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,15 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.5 (in progress) =========================== +2011-06-10: wsfulton + [Python] Few subtle bugfixes in autodoc documentation generation, + - Unnamed argument names fix for autodoc levels > 0. + - Display of template types fixed for autodoc levels > 1. + - Fix SF #3310528 - display of typedef structs for autodoc levels > 1. + - Add missing type for self for autodoc levels 1 and 3. + - autodoc levels 2 and 3 documented. + - Minor tweaks to autodoc style to conform with PEP8. + 2011-05-30: olly [PHP] Fix handling of directors when -prefix is used. diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index 07f9e87d7..165fa94cb 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -98,6 +98,8 @@
  • %feature("docstring") @@ -5114,14 +5116,15 @@ introspection, then life is good once more. which when attached to a node in the parse tree will cause a docstring to be generated that includes the name of the function, 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. +four levels for autodoc controlled by the value given to the +feature, %feature("autodoc", "level"). +The four values for level are covered in the following sub-sections.

    33.10.2.1 %feature("autodoc", "0")

    -When the "0" option is given then the types of the parameters will +When level "0" is used then the types of the parameters will not be included in the autodoc string. For example, given this function prototype:

    @@ -5150,14 +5153,15 @@ def function_name(*args, **kwargs):

    -When the "1" option is used then the parameter types will be +When level "1" is used then the parameter types will be used in the autodoc string. In addition, an attempt is made to simplify the type name such that it makes more sense to the Python -user. Pointer, reference and const info is removed, -%rename'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 +user. Pointer, reference and const info is removed if the associated type +is has an associated Python type (%rename's are thus shown correctly). +This works most of the time, otherwise a C/C++ type will be used. +See the next section for the "docstring" feature for tweaking the docstrings to your liking. +Given the example above, then turning on the +parameter types with level "1" will result in Python code like this:

    @@ -5170,8 +5174,92 @@ def function_name(*args, **kwargs): +

    33.10.2.3 %feature("autodoc", "2")

    -

    33.10.2.3 %feature("autodoc", "docstring")

    + +

    +Level "2" results in the function prototype as per level "0". In addition, a line of +documentation is generated for each parameter. Using the previous example, the generated +code will be: +

    + +
    +
    +def function_name(*args, **kwargs):
    +    """
    +    function_name(x, y, foo=None, bar=None) -> bool
    +
    +    Parameters:
    +        x: int
    +        y: int
    +        foo: Foo *
    +        bar: Bar *
    +
    +    """
    +    ...
    +
    +
    + +

    +Note that the documentation for each parameter is sourced from the "doc" typemap which by default shows the +C/C++ type rather than the simplified Python type name described earlier for level "1". +Typemaps can of course change the output for any particular type, for example the int x parameter: +

    + +
    +
    +%feature("autodoc", "2");
    +%typemap("doc") int x "$1_name (C++ type: $1_type) -- Input $1_name dimension"
    +bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL);
    +
    +
    + +

    +resulting in +

    + +
    +
    +def function_name(*args, **kwargs):
    +  """
    +    function_name(x, y, foo=None, bar=None) -> bool
    +
    +    Parameters:
    +        x (C++ type: int) -- Input x dimension
    +        y: int
    +        foo: Foo *
    +        bar: Bar *
    +
    +    """
    +
    +
    + +

    33.10.2.4 %feature("autodoc", "3")

    + + +

    +Level "3" results in the function prototype as per level "1" but also contains the same additional line of documentation for each parameter as per level "2". Using our earlier example again, the generated code will be: +

    + +
    +
    +def function_name(*args, **kwargs):
    +    """
    +    function_name(int x, int y, Foo foo=None, Bar bar=None) -> bool
    +
    +    Parameters:
    +        x: int
    +        y: int
    +        foo: Foo *
    +        bar: Bar *
    +
    +    """
    +    ...
    +
    +
    + + +

    33.10.2.5 %feature("autodoc", "docstring")

    @@ -5285,7 +5373,7 @@ SWIG is able to generate proxy method definitions like this:

    -  def foo(self, bar : "int" = 0) -> "void" : ...
    +  def foo(self, bar : "int"=0) -> "void" : ...
     

    @@ -5294,7 +5382,7 @@ still could be generated:

    -  def foo(self, bar = 0): ...
    +  def foo(self, bar=0): ...
     

    diff --git a/Examples/test-suite/autodoc.i b/Examples/test-suite/autodoc.i index c363e4384..23aa3f0b7 100644 --- a/Examples/test-suite/autodoc.i +++ b/Examples/test-suite/autodoc.i @@ -1,9 +1,9 @@ -%module(docstring="hello") python_autodoc +%module(docstring="hello") autodoc %feature("autodoc"); -// especial typemap and its docs -%typemap(in) (int c, int d) "$1 =0; $2 = 0;"; +// special 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]"; // testing for different documentation levels @@ -12,7 +12,22 @@ %feature("autodoc","2") A::func2; // extended %feature("autodoc","3") A::func3; // extended + types -%feature("autodoc","just a string") A::func; // names +%feature("autodoc","0") A::func0default; // names +%feature("autodoc","1") A::func1default; // names + types +%feature("autodoc","2") A::func2default; // extended +%feature("autodoc","3") A::func3default; // extended + types + +%feature("autodoc","0") A::func0static; // names +%feature("autodoc","1") A::func1static; // names + types +%feature("autodoc","2") A::func2static; // extended +%feature("autodoc","3") A::func3static; // extended + types + +%feature("autodoc","0") A::variable_a; // names +%feature("autodoc","1") A::variable_b; // names + types +%feature("autodoc","2") A::variable_c; // extended +%feature("autodoc","3") A::variable_d; // extended + types + +%feature("autodoc","just a string") A::funk; // names %inline { @@ -20,36 +35,29 @@ hi, hello }; - struct A - { - A(int a, short b, Hola h) - { - } + struct A { + A(int a, short b, Hola h) {} + int funk(int a) { return a; } - int func(int a) - { - return a; - } + int func0(short, int c, int d) { return c; } + int func1(short, int c, int d) { return c; } + int func2(short, int c, int d) { return c; } + int func3(short, int c, int d) { return c; } - int func0(int c, int d) - { - return c; - } - - int func1(int c, int d) - { - return c; - } + int func0default(A *e, short, int c, int d, double f = 2) { return 0; } + int func1default(A *e, short, int c, int d, double f = 2) { return 0; } + int func2default(A *e, short, int c, int d, double f = 2) { return 0; } + int func3default(A *e, short, int c, int d, double f = 2) { return 0; } - int func2(A* c, double d = 2) - { - return 2; - } + static int func0static(A *e, short, int c, int d, double f = 2) { return 0; } + static int func1static(A *e, short, int c, int d, double f = 2) { return 0; } + static int func2static(A *e, short, int c, int d, double f = 2) { return 0; } + static int func3static(A *e, short, int c, int d, double f = 2) { return 0; } - int func3(A* c, double d = 2) - { - return 2; - } + int variable_a; + int variable_b; + int variable_c; + int variable_d; }; } @@ -62,34 +70,66 @@ %typemap(doc) int a "a: special comment for parameter a"; %typemap(doc) int b "b: another special comment for parameter b"; -%callback(1) func_cb; +%feature("autodoc","0") C::C(int a, int b, Hola h); // names +%feature("autodoc","1") D::D(int a, int b, Hola h); // names + types +%feature("autodoc","2") E::E(int a, int b, Hola h); // extended +%feature("autodoc","3") F::F(int a, int b, Hola h); // extended + types %inline { - struct B - { - B(int a, int b, Hola h) - { - } - - - int func(int c, int d) - { - return c; - } - + struct B { + B(int a, int b, Hola h) {} + int funk(int c, int d) { return c; } }; - int func(int c, int d) { - return c; - } + struct C { + C(int a, int b, Hola h) {} + }; + struct D { + D(int a, int b, Hola h) {} + }; + struct E { + E(int a, int b, Hola h) {} + }; + struct F { + F(int a, int b, Hola h) {} + }; - int funcio(int *INOUT) { + int funk(A *e, short, int c, int d) { return c; } + int funkdefaults(A *e, short, int c, int d, double f = 2) { return c; } +} + +%include +%inline %{ + int func_input(int *INPUT) { return 1; } - - int func_cb(int c, int d) { - return c; + int func_output(int *OUTPUT) { + *OUTPUT = 2; + return 1; } - + int func_inout(int *INOUT) { + *INOUT += 1; + return 1; + } +%} + +%callback(1) func_cb; + +%inline { + int func_cb(int c, int d) { return c; } } + +// Bug 3310528 +%feature("autodoc","1") banana; // names + types +%inline %{ +typedef struct tagS { + int a; + char b; +} S; + +typedef int Integer; + +void banana(S *a, const struct tagS *b, int c, Integer d) {} +%} + diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py new file mode 100644 index 000000000..c65ebba24 --- /dev/null +++ b/Examples/test-suite/python/autodoc_runme.py @@ -0,0 +1,176 @@ +from autodoc import * + +def check(got, expected): + if expected != got: + raise RuntimeError("\n" + "Expected: [" + expected + "]\n" + "Got : [" + got + "]") + +check(A.__doc__, "Proxy of C++ A class") +check(A.funk.__doc__, "just a string") +check(A.func0.__doc__, "func0(self, arg2, hello) -> int") +check(A.func1.__doc__, "func1(A self, short arg2, Tuple hello) -> int") +check(A.func2.__doc__, "\n" +" func2(self, arg2, hello) -> int\n" +"\n" +" Parameters:\n" +" arg2: short\n" +" hello: int tuple[2]\n" +"\n" +" " +) +check(A.func3.__doc__, "\n" +" func3(A self, short arg2, Tuple hello) -> int\n" +"\n" +" Parameters:\n" +" arg2: short\n" +" hello: int tuple[2]\n" +"\n" +" " +) + +check(A.func0default.__doc__, "\n" +" func0default(self, e, arg3, hello, f=2) -> int\n" +" func0default(self, e, arg3, hello) -> int\n" +" " +) +check(A.func1default.__doc__, "\n" +" func1default(A self, A e, short arg3, Tuple hello, double f=2) -> int\n" +" func1default(A self, A e, short arg3, Tuple hello) -> int\n" +" " +) +check(A.func2default.__doc__, "\n" +" func2default(self, e, arg3, hello, f=2) -> int\n" +"\n" +" Parameters:\n" +" e: A *\n" +" arg3: short\n" +" hello: int tuple[2]\n" +" f: double\n" +"\n" +" func2default(self, e, arg3, hello) -> int\n" +"\n" +" Parameters:\n" +" e: A *\n" +" arg3: short\n" +" hello: int tuple[2]\n" +"\n" +" " +) +check(A.func3default.__doc__, "\n" +" func3default(A self, A e, short arg3, Tuple hello, double f=2) -> int\n" +"\n" +" Parameters:\n" +" e: A *\n" +" arg3: short\n" +" hello: int tuple[2]\n" +" f: double\n" +"\n" +" func3default(A self, A e, short arg3, Tuple hello) -> int\n" +"\n" +" Parameters:\n" +" e: A *\n" +" arg3: short\n" +" hello: int tuple[2]\n" +"\n" +" " +) + +check(A.func0static.__doc__, "\n" +" func0static(e, arg2, hello, f=2) -> int\n" +" func0static(e, arg2, hello) -> int\n" +" " +) +check(A.func1static.__doc__, "\n" +" func1static(A e, short arg2, Tuple hello, double f=2) -> int\n" +" func1static(A e, short arg2, Tuple hello) -> int\n" +" " +) +check(A.func2static.__doc__, "\n" +" func2static(e, arg2, hello, f=2) -> int\n" +"\n" +" Parameters:\n" +" e: A *\n" +" arg2: short\n" +" hello: int tuple[2]\n" +" f: double\n" +"\n" +" func2static(e, arg2, hello) -> int\n" +"\n" +" Parameters:\n" +" e: A *\n" +" arg2: short\n" +" hello: int tuple[2]\n" +"\n" +" " +) +check(A.func3static.__doc__, "\n" +" func3static(A e, short arg2, Tuple hello, double f=2) -> int\n" +"\n" +" Parameters:\n" +" e: A *\n" +" arg2: short\n" +" hello: int tuple[2]\n" +" f: double\n" +"\n" +" func3static(A e, short arg2, Tuple hello) -> int\n" +"\n" +" Parameters:\n" +" e: A *\n" +" arg2: short\n" +" hello: int tuple[2]\n" +"\n" +" " +) + +check(A.variable_a.__doc__, "A_variable_a_get(self) -> int") +check(A.variable_b.__doc__, "A_variable_b_get(A self) -> int") +check(A.variable_c.__doc__, "\n" +"A_variable_c_get(self) -> int\n" +"\n" +"Parameters:\n" +" self: A *\n" +"\n" +) +check(A.variable_d.__doc__, "\n" +"A_variable_d_get(A self) -> int\n" +"\n" +"Parameters:\n" +" self: A *\n" +"\n" +) + +check(B.__doc__, "Proxy of C++ B class") +check(C.__init__.__doc__, "__init__(self, a, b, h) -> C") +check(D.__init__.__doc__, "__init__(D self, int a, int b, Hola h) -> D") +check(E.__init__.__doc__, "\n" +" __init__(self, a, b, h) -> E\n" +"\n" +" Parameters:\n" +" a: special comment for parameter a\n" +" b: another special comment for parameter b\n" +" h: enum Hola\n" +"\n" +" " +) +check(F.__init__.__doc__, "\n" +" __init__(F self, int a, int b, Hola h) -> F\n" +"\n" +" Parameters:\n" +" a: special comment for parameter a\n" +" b: another special comment for parameter b\n" +" h: enum Hola\n" +"\n" +" " +) + +check(B.funk.__doc__, "funk(B self, int c, int d) -> int") +check(funk.__doc__, "funk(A e, short arg2, int c, int d) -> int") +check(funkdefaults.__doc__, "\n" +" funkdefaults(A e, short arg2, int c, int d, double f=2) -> int\n" +" funkdefaults(A e, short arg2, int c, int d) -> int\n" +" " +) + +check(func_input.__doc__, "func_input(int * INPUT) -> int") +check(func_output.__doc__, "func_output() -> int") +check(func_inout.__doc__, "func_inout(int * INOUT) -> int") +check(banana.__doc__, "banana(S a, S b, int c, Integer d)") diff --git a/Lib/python/pydocs.swg b/Lib/python/pydocs.swg index 862339da7..f4ab9db23 100644 --- a/Lib/python/pydocs.swg +++ b/Lib/python/pydocs.swg @@ -1,18 +1,22 @@ -// basic doc for primitive types.... +// Documentation for use with the autodoc feature. #ifdef SWIG_DOC_DOXYGEN_STYLE -%typemap(doc) SWIGTYPE "@param $1_name $1_type value"; -%typemap(doc) SWIGTYPE * "@param $1_name $1_type value"; -%typemap(doc) const SWIGTYPE & "@param $1_name $1_type value"; -%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type value"; -#else -%typemap(doc) SWIGTYPE "$1_name: $1_type value"; -%typemap(doc) SWIGTYPE * "$1_name: $1_type value"; -%typemap(doc) const SWIGTYPE & "$1_name: $1_type value"; -%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type value"; +%typemap(doc) SWIGTYPE "@param $1_name $1_type"; +%typemap(doc) SWIGTYPE * "@param $1_name $1_type"; +%typemap(doc) const SWIGTYPE & "@param $1_name $1_type"; +%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type"; -%typemap(doc) SWIGTYPE *INOUT "$1_name: $1_type input/ouput value"; -%typemap(doc) SWIGTYPE *INPUT "$1_name: $1_type input value"; -%typemap(doc) SWIGTYPE *OUTPUT "$1_name: $1_type output value"; +%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "@param $1_name $1_type (input/output)"; +%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "@param $1_name $1_type (input)"; +%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "@param $1_name $1_type (output)"; +#else +%typemap(doc) SWIGTYPE "$1_name: $1_type"; +%typemap(doc) SWIGTYPE * "$1_name: $1_type"; +%typemap(doc) const SWIGTYPE & "$1_name: $1_type"; +%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type"; + +%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "$1_name: $1_type (input/output)"; +%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "$1_name: $1_type (input)"; +%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "$1_name: $1_type (output)"; #endif diff --git a/Lib/python/pythonkw.swg b/Lib/python/pythonkw.swg index 2dd4f2f49..8ad0ef11b 100644 --- a/Lib/python/pythonkw.swg +++ b/Lib/python/pythonkw.swg @@ -3,7 +3,7 @@ */ #define PYTHONKW(x) %keywordwarn("'" `x` "' is a python keyword, renaming to '_" `x` "'", rename="_%s") `x` -#define PYTHONBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in python") "::"`x` +#define PYTHONBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in python") `x` /* @@ -105,7 +105,6 @@ PYTHONBN(setattr); PYTHONBN(slice); PYTHONBN(sorted); PYTHONBN(staticmethod); -PYTHONBN(staticmethod); PYTHONBN(str); PYTHONBN(sum); PYTHONBN(super); diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 00f6ebfff..737ecc555 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -1122,9 +1122,9 @@ public: initial++; c++; } - if (*c && !isspace(*c)) + if (*c && !isspace(*c)) { break; - else { + } else { initial = 0; } } @@ -1267,35 +1267,29 @@ public: } /* ----------------------------------------------------------------------------- - * makeParameterName() - * Note: the generated name should consist with that in kwnames[] + * addMissingParameterNames() + * For functions that have not had nameless parameters set in the Language class. * * Inputs: - * n - Node - * p - parameter node - * arg_num - parameter argument number - * Return: - * arg - a unique parameter name + * plist - entire parameter list + * arg_offset - argument number for first parameter + * Side effects: + * The "lname" attribute in each parameter in plist will be contain a 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"); + void addMissingParameterNames(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); + } + i++; + p = nextSibling(p); } - 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 @@ -1305,25 +1299,21 @@ public: String *make_autodocParmList(Node *n, bool showTypes, bool calling = false, bool func_annotation = false) { - String *doc = NewString(""); - String *pdocs = Copy(Getattr(n, "feature:pdocs")); + String *pdocs = 0; ParmList *plist = CopyParmList(Getattr(n, "parms")); Parm *p; Parm *pnext; - Node *lookup; int lines = 0; - int arg_num = 0; - const int maxwidth = 50; + int start_arg_num = is_wrapping_class() ? 1 : 0; + const int maxwidth = 80; if (calling) func_annotation = false; - if (pdocs) - Append(pdocs, "\n"); - + addMissingParameterNames(plist, start_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); @@ -1354,18 +1344,15 @@ public: value = Getattr(p, "tmap:doc:value"); } + // Note: the generated name should be consistent with that in kwnames[] name = name ? name : Getattr(p, "name"); + name = name ? name : Getattr(p, "lname"); + type = type ? type : Getattr(p, "type"); value = value ? value : Getattr(p, "value"); - 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 (SwigType_isvarargs(type)) + break; if (Len(doc)) { // add a comma to the previous one if any @@ -1378,39 +1365,35 @@ public: } } - type = SwigType_base(type); - lookup = Swig_symbol_clookup(type, 0); - if (lookup) - type = Getattr(lookup, "sym:name"); - // Do the param type too? + Node *nn = classLookup(Getattr(p, "type")); + String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); if (showTypes) - Printf(doc, "%s ", type); - + Printf(doc, "%s ", type_str); Append(doc, name); if (pdoc) { if (!pdocs) - pdocs = NewString("Parameters:\n"); - Printf(pdocs, " %s\n", pdoc); + pdocs = NewString("\nParameters:\n"); + Printf(pdocs, " %s\n", pdoc); } - // Write the function annoation + // Write the function annotation if (func_annotation) - Printf(doc, " : '%s'", type); + Printf(doc, " : '%s'", type_str); // Write default value if (value && !calling) { String *pv = pyvalue(value, Getattr(p, "type")); - if (pv) + if (pv) { value = pv; - else { - lookup = Swig_symbol_clookup(value, 0); - if (lookup) { + } else { + Node *lookup = Swig_symbol_clookup(value, 0); + if (lookup) value = Getattr(lookup, "sym:name"); - } } - Printf(doc, " = %s", value); + Printf(doc, "=%s", value); } + Delete(type_str); } if (pdocs) Setattr(n, "feature:pdocs", pdocs); @@ -1430,7 +1413,7 @@ public: String *make_autodoc(Node *n, autodoc_t ad_type) { int extended = 0; - // If the function is overloaded then this funciton is called + // If the function is overloaded then this function is called // for the last one. Rewind to the first so the docstrings are // in order. while (Getattr(n, "sym:previousSibling")) @@ -1468,15 +1451,14 @@ public: if (!skipAuto) { String *symname = Getattr(n, "sym:name"); SwigType *type = Getattr(n, "type"); + String *type_str = NULL; if (type) { - if (Strcmp(type, "void") == 0) - type = NULL; - else { - type = SwigType_base(type); - Node *lookup = Swig_symbol_clookup(type, 0); - if (lookup) - type = Getattr(lookup, "sym:name"); + if (Strcmp(type, "void") == 0) { + type_str = NULL; + } else { + Node *nn = classLookup(type); + type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); } } @@ -1497,40 +1479,50 @@ public: case AUTODOC_CTOR: if (Strcmp(class_name, symname) == 0) { String *paramList = make_autodocParmList(n, showTypes); + Printf(doc, "__init__("); + if (showTypes) + Printf(doc, "%s ", getClassName()); if (Len(paramList)) - Printf(doc, "__init__(self, %s) -> %s", paramList, class_name); + Printf(doc, "self, %s) -> %s", paramList, class_name); else - Printf(doc, "__init__(self) -> %s", class_name); + Printf(doc, "self) -> %s", class_name); } else Printf(doc, "%s(%s) -> %s", symname, make_autodocParmList(n, showTypes), class_name); break; case AUTODOC_DTOR: - Append(doc, "__del__(self)"); + if (showTypes) + Printf(doc, "__del__(%s self)", getClassName()); + else + Printf(doc, "__del__(self)"); break; case AUTODOC_STATICFUNC: Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes)); - if (type) - Printf(doc, " -> %s", type); + if (type_str) + Printf(doc, " -> %s", type_str); break; case AUTODOC_FUNC: Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes)); - if (type) - Printf(doc, " -> %s", type); + if (type_str) + Printf(doc, " -> %s", type_str); break; case AUTODOC_METHOD: String *paramList = make_autodocParmList(n, showTypes); + Printf(doc, "%s(", symname); + if (showTypes) + Printf(doc, "%s ", class_name); if (Len(paramList)) - Printf(doc, "%s(self, %s)", symname, paramList); + Printf(doc, "self, %s)", paramList); else - Printf(doc, "%s(self)", symname); - if (type) - Printf(doc, " -> %s", type); + Printf(doc, "self)"); + if (type_str) + Printf(doc, " -> %s", type_str); break; } + Delete(type_str); } if (extended) { String *pdocs = Getattr(n, "feature:pdocs"); @@ -1935,7 +1927,7 @@ public: /* Create a shadow for this function (if enabled and not in a member function) */ if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) { - emitFunctionShadowHelper(n, f_shadow_stubs, symname, 0); + emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0); } DelWrapper(f); Delete(dispatch); @@ -3914,7 +3906,7 @@ public: // Can't use checkAttribute(n, "access", "public") because // "access" attr isn't set on %extend methods if (!checkAttribute(n, "access", "private") && strncmp(Char(symname), "operator ", 9) && !Getattr(class_members, symname)) { - String *fullname = Swig_name_member(NULL, class_name, symname); + String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname); String *wname = Swig_name_wrapper(fullname); Setattr(class_members, symname, n); int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2; @@ -3940,12 +3932,13 @@ public: if (!Getattr(n, "sym:nextSibling")) { if (shadow && !builtin) { int fproxy = fastproxy; + String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname); if (Strcmp(symname, "__repr__") == 0) { have_repr = 1; } if (Getattr(n, "feature:shadow")) { String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4); - String *pyaction = NewStringf("%s.%s", module, Swig_name_member(NSPACE_TODO, class_name, symname)); + String *pyaction = NewStringf("%s.%s", module, fullname); Replaceall(pycode, "$action", pyaction); Delete(pyaction); Printv(f_shadow, pycode, "\n", NIL); @@ -3958,7 +3951,7 @@ public: if (!have_addtofunc(n)) { if (!fastproxy || olddefs) { Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL); - Printv(f_shadow, " return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); + Printv(f_shadow, " return ", funcCall(fullname, callParms), "\n", NIL); } } else { Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL); @@ -3971,11 +3964,11 @@ public: } if (have_pythonappend(n)) { fproxy = 0; - Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); + Printv(f_shadow, tab8, "val = ", funcCall(fullname, callParms), "\n", NIL); Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n", NIL); Printv(f_shadow, tab8, "return val\n\n", NIL); } else { - Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n\n", NIL); + Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n\n", NIL); } } } @@ -3988,6 +3981,7 @@ public: } Append(shadow_list, symname); } + Delete(fullname); } } return SWIG_OK; @@ -4012,7 +4006,7 @@ public: if (builtin && in_class) { if ((GetFlagAttr(n, "feature:extend") || checkAttribute(n, "access", "public")) && !Getattr(class_members, symname)) { - String *fullname = Swig_name_member(NULL, class_name, symname); + String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname); String *wname = Swig_name_wrapper(fullname); Setattr(class_members, symname, n); int funpack = modernargs && fastunpack && !Getattr(n, "sym:overloaded");