Merge branch 'ahnolds-autodoc'
* ahnolds-autodoc: Apparently nicely lining things up violates pep8, so don't try Don't use bool in the generated files for C compatability Properly handle destructors as methods for autodoc and fix some stray newlines Fixing a bug where the cached doxygen docstring could be deleted while still in use, causing swig to segfault Fixing docstrings for variables and static functions for consistency Fixes so that fastproxy and autodoc work correctly with both low-level C API and high-level Python Shadow API Updating the changelog Also check documentation on the low-level API Fix a bug where anonymous arguments were misnumbered when used in constructors Fixing python docstring handling for -fastproxy Conflicts: CHANGES.current
This commit is contained in:
commit
1e2190e6b8
6 changed files with 409 additions and 121 deletions
|
|
@ -7,6 +7,20 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.0.0 (in progress)
|
Version 4.0.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2019-02-02: ahnolds
|
||||||
|
[Python] Documentation enhancements for Python:
|
||||||
|
|
||||||
|
#728 Fixed the handling of autodoc when using -fastproxy.
|
||||||
|
|
||||||
|
#1367 Added documentation to wrapped member variables using the
|
||||||
|
property(... doc="...") construct.
|
||||||
|
|
||||||
|
Only show a single documentation entry for functions with default arguments when
|
||||||
|
using autodoc.
|
||||||
|
|
||||||
|
Fixed a bug where a cached doxygen docstring could be deleted while still in use,
|
||||||
|
causing swig to segfault.
|
||||||
|
|
||||||
2019-01-31: olly
|
2019-01-31: olly
|
||||||
SWIG now requires a target language to be specified instead of
|
SWIG now requires a target language to be specified instead of
|
||||||
defaulting to wrapping for Tcl. Specifying swig --help without
|
defaulting to wrapping for Tcl. Specifying swig --help without
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,10 @@
|
||||||
%feature("autodoc","1") D::D(int a, int b, Hola h); // names + types
|
%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","2") E::E(int a, int b, Hola h); // extended
|
||||||
%feature("autodoc","3") F::F(int a, int b, Hola h); // extended + types
|
%feature("autodoc","3") F::F(int a, int b, Hola h); // extended + types
|
||||||
|
%feature("autodoc","0") C::~C(); // names
|
||||||
|
%feature("autodoc","1") D::~D(); // names + types
|
||||||
|
%feature("autodoc","2") E::~E(); // extended
|
||||||
|
%feature("autodoc","3") F::~F(); // extended + types
|
||||||
|
|
||||||
%inline {
|
%inline {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,19 @@
|
||||||
from autodoc import *
|
from autodoc import *
|
||||||
|
import _autodoc
|
||||||
import comment_verifier
|
import comment_verifier
|
||||||
import inspect
|
import inspect
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def check(got, expected, expected_builtin=None, skip=False):
|
def check(got, expected, expected_builtin=None, skip=False):
|
||||||
if not skip:
|
if is_python_builtin() and skip:
|
||||||
|
# Only skip for builtins
|
||||||
|
pass
|
||||||
|
else:
|
||||||
expect = expected
|
expect = expected
|
||||||
if is_python_builtin() and expected_builtin != None:
|
if is_python_builtin() and expected_builtin != None:
|
||||||
expect = expected_builtin
|
expect = expected_builtin
|
||||||
comment_verifier.check(got, expect)
|
comment_verifier.check(got, expect)
|
||||||
|
|
||||||
def is_fastproxy():
|
|
||||||
fastproxy = True
|
|
||||||
try:
|
|
||||||
from autodoc import _swig_new_instance_method
|
|
||||||
except ImportError:
|
|
||||||
fastproxy = False
|
|
||||||
return fastproxy
|
|
||||||
|
|
||||||
if is_fastproxy():
|
|
||||||
# Detect when -fastproxy is specified and skip test as it changes the function names making it
|
|
||||||
# hard to test... skip until the number of options are reduced in SWIG-3.1 and autodoc is improved
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# skip builtin check - the autodoc is missing, but it probably should not be
|
# skip builtin check - the autodoc is missing, but it probably should not be
|
||||||
skip = True
|
skip = True
|
||||||
|
|
||||||
|
|
@ -48,11 +39,9 @@ check(inspect.getdoc(A.func3),
|
||||||
"hello: int tuple[2]")
|
"hello: int tuple[2]")
|
||||||
|
|
||||||
check(inspect.getdoc(A.func0default),
|
check(inspect.getdoc(A.func0default),
|
||||||
"func0default(self, e, arg3, hello, f=2) -> int\n"
|
"func0default(self, e, arg3, hello, f=2) -> int")
|
||||||
"func0default(self, e, arg3, hello) -> int")
|
|
||||||
check(inspect.getdoc(A.func1default),
|
check(inspect.getdoc(A.func1default),
|
||||||
"func1default(A self, A e, short arg3, Tuple hello, double f=2) -> int\n"
|
"func1default(A self, A e, short arg3, Tuple hello, double f=2) -> int")
|
||||||
"func1default(A self, A e, short arg3, Tuple hello) -> int")
|
|
||||||
check(inspect.getdoc(A.func2default),
|
check(inspect.getdoc(A.func2default),
|
||||||
"func2default(self, e, arg3, hello, f=2) -> int\n"
|
"func2default(self, e, arg3, hello, f=2) -> int\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
@ -61,15 +50,7 @@ check(inspect.getdoc(A.func2default),
|
||||||
"e: A *\n"
|
"e: A *\n"
|
||||||
"arg3: short\n"
|
"arg3: short\n"
|
||||||
"hello: int tuple[2]\n"
|
"hello: int tuple[2]\n"
|
||||||
"f: double\n"
|
"f: double")
|
||||||
"\n"
|
|
||||||
"func2default(self, e, arg3, hello) -> int\n"
|
|
||||||
"\n"
|
|
||||||
"Parameters\n"
|
|
||||||
"----------\n"
|
|
||||||
"e: A *\n"
|
|
||||||
"arg3: short\n"
|
|
||||||
"hello: int tuple[2]")
|
|
||||||
check(inspect.getdoc(A.func3default),
|
check(inspect.getdoc(A.func3default),
|
||||||
"func3default(A self, A e, short arg3, Tuple hello, double f=2) -> int\n"
|
"func3default(A self, A e, short arg3, Tuple hello, double f=2) -> int\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
@ -78,22 +59,20 @@ check(inspect.getdoc(A.func3default),
|
||||||
"e: A *\n"
|
"e: A *\n"
|
||||||
"arg3: short\n"
|
"arg3: short\n"
|
||||||
"hello: int tuple[2]\n"
|
"hello: int tuple[2]\n"
|
||||||
"f: double\n"
|
"f: double")
|
||||||
"\n"
|
|
||||||
"func3default(A self, A e, short arg3, Tuple hello) -> int\n"
|
|
||||||
"\n"
|
|
||||||
"Parameters\n"
|
|
||||||
"----------\n"
|
|
||||||
"e: A *\n"
|
|
||||||
"arg3: short\n"
|
|
||||||
"hello: int tuple[2]")
|
|
||||||
|
|
||||||
check(inspect.getdoc(A.func0static),
|
check(inspect.getdoc(A.func0static),
|
||||||
"func0static(e, arg2, hello, f=2) -> int\n"
|
"func0static(e, arg2, hello, f=2) -> int")
|
||||||
"func0static(e, arg2, hello) -> int")
|
check(inspect.getdoc(_autodoc.A_func0static),
|
||||||
|
"A_func0static(e, arg2, hello, f=2) -> int")
|
||||||
|
check(inspect.getdoc(A_func0static),
|
||||||
|
"A_func0static(e, arg2, hello, f=2) -> int")
|
||||||
check(inspect.getdoc(A.func1static),
|
check(inspect.getdoc(A.func1static),
|
||||||
"func1static(A e, short arg2, Tuple hello, double f=2) -> int\n"
|
"func1static(A e, short arg2, Tuple hello, double f=2) -> int")
|
||||||
"func1static(A e, short arg2, Tuple hello) -> int")
|
check(inspect.getdoc(_autodoc.A_func1static),
|
||||||
|
"A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
|
||||||
|
check(inspect.getdoc(A_func1static),
|
||||||
|
"A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
|
||||||
check(inspect.getdoc(A.func2static),
|
check(inspect.getdoc(A.func2static),
|
||||||
"func2static(e, arg2, hello, f=2) -> int\n"
|
"func2static(e, arg2, hello, f=2) -> int\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
@ -102,15 +81,25 @@ check(inspect.getdoc(A.func2static),
|
||||||
"e: A *\n"
|
"e: A *\n"
|
||||||
"arg2: short\n"
|
"arg2: short\n"
|
||||||
"hello: int tuple[2]\n"
|
"hello: int tuple[2]\n"
|
||||||
"f: double\n"
|
"f: double")
|
||||||
"\n"
|
check(inspect.getdoc(_autodoc.A_func2static),
|
||||||
"func2static(e, arg2, hello) -> int\n"
|
"A_func2static(e, arg2, hello, f=2) -> int\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Parameters\n"
|
"Parameters\n"
|
||||||
"----------\n"
|
"----------\n"
|
||||||
"e: A *\n"
|
"e: A *\n"
|
||||||
"arg2: short\n"
|
"arg2: short\n"
|
||||||
"hello: int tuple[2]")
|
"hello: int tuple[2]\n"
|
||||||
|
"f: double")
|
||||||
|
check(inspect.getdoc(A_func2static),
|
||||||
|
"A_func2static(e, arg2, hello, f=2) -> int\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"e: A *\n"
|
||||||
|
"arg2: short\n"
|
||||||
|
"hello: int tuple[2]\n"
|
||||||
|
"f: double")
|
||||||
check(inspect.getdoc(A.func3static),
|
check(inspect.getdoc(A.func3static),
|
||||||
"func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
|
"func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
@ -119,42 +108,128 @@ check(inspect.getdoc(A.func3static),
|
||||||
"e: A *\n"
|
"e: A *\n"
|
||||||
"arg2: short\n"
|
"arg2: short\n"
|
||||||
"hello: int tuple[2]\n"
|
"hello: int tuple[2]\n"
|
||||||
"f: double\n"
|
"f: double")
|
||||||
"\n"
|
check(inspect.getdoc(_autodoc.A_func3static),
|
||||||
"func3static(A e, short arg2, Tuple hello) -> int\n"
|
"A_func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Parameters\n"
|
"Parameters\n"
|
||||||
"----------\n"
|
"----------\n"
|
||||||
"e: A *\n"
|
"e: A *\n"
|
||||||
"arg2: short\n"
|
"arg2: short\n"
|
||||||
"hello: int tuple[2]")
|
"hello: int tuple[2]\n"
|
||||||
|
"f: double")
|
||||||
|
check(inspect.getdoc(A_func3static),
|
||||||
|
"A_func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"e: A *\n"
|
||||||
|
"arg2: short\n"
|
||||||
|
"hello: int tuple[2]\n"
|
||||||
|
"f: double")
|
||||||
|
|
||||||
if sys.version_info[0:2] > (2, 4):
|
check(inspect.getdoc(A.variable_a),
|
||||||
# Python 2.4 does not seem to work
|
"variable_a"
|
||||||
check(inspect.getdoc(A.variable_a),
|
)
|
||||||
"A_variable_a_get(self) -> int",
|
check(inspect.getdoc(A.variable_b),
|
||||||
"A.variable_a"
|
"variable_b : int"
|
||||||
)
|
)
|
||||||
check(inspect.getdoc(A.variable_b),
|
check(inspect.getdoc(A.variable_c),
|
||||||
"A_variable_b_get(A self) -> int",
|
"variable_c"
|
||||||
"A.variable_b"
|
)
|
||||||
)
|
check(inspect.getdoc(A.variable_d),
|
||||||
check(inspect.getdoc(A.variable_c),
|
"variable_d : int"
|
||||||
"A_variable_c_get(self) -> int\n"
|
)
|
||||||
|
|
||||||
|
# Check the low-level functions (not present when using -builtin except for the static ones)
|
||||||
|
if not is_python_builtin():
|
||||||
|
check(inspect.getdoc(_autodoc.A_funk), "just a string.")
|
||||||
|
check(inspect.getdoc(_autodoc.A_func0),
|
||||||
|
"A_func0(self, arg2, hello) -> int")
|
||||||
|
check(inspect.getdoc(_autodoc.A_func1),
|
||||||
|
"A_func1(A self, short arg2, Tuple hello) -> int")
|
||||||
|
check(inspect.getdoc(_autodoc.A_func2),
|
||||||
|
"A_func2(self, arg2, hello) -> int\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Parameters\n"
|
"Parameters\n"
|
||||||
"----------\n"
|
"----------\n"
|
||||||
"self: A *",
|
"arg2: short\n"
|
||||||
"A.variable_c"
|
"hello: int tuple[2]")
|
||||||
)
|
check(inspect.getdoc(_autodoc.A_func3),
|
||||||
check(inspect.getdoc(A.variable_d),
|
"A_func3(A self, short arg2, Tuple hello) -> int\n"
|
||||||
"A_variable_d_get(A self) -> int\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"Parameters\n"
|
"Parameters\n"
|
||||||
"----------\n"
|
"----------\n"
|
||||||
"self: A *",
|
"arg2: short\n"
|
||||||
"A.variable_d"
|
"hello: int tuple[2]")
|
||||||
)
|
check(inspect.getdoc(_autodoc.A_func0default),
|
||||||
|
"A_func0default(self, e, arg3, hello, f=2) -> int")
|
||||||
|
check(inspect.getdoc(_autodoc.A_func1default),
|
||||||
|
"A_func1default(A self, A e, short arg3, Tuple hello, double f=2) -> int")
|
||||||
|
check(inspect.getdoc(_autodoc.A_func2default),
|
||||||
|
"A_func2default(self, e, arg3, hello, f=2) -> int\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"e: A *\n"
|
||||||
|
"arg3: short\n"
|
||||||
|
"hello: int tuple[2]\n"
|
||||||
|
"f: double")
|
||||||
|
check(inspect.getdoc(_autodoc.A_func3default),
|
||||||
|
"A_func3default(A self, A e, short arg3, Tuple hello, double f=2) -> int\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"e: A *\n"
|
||||||
|
"arg3: short\n"
|
||||||
|
"hello: int tuple[2]\n"
|
||||||
|
"f: double")
|
||||||
|
check(inspect.getdoc(_autodoc.A_variable_a_set), "A_variable_a_set(self, variable_a)")
|
||||||
|
check(inspect.getdoc(_autodoc.A_variable_a_get), "A_variable_a_get(self) -> int" )
|
||||||
|
check(inspect.getdoc(_autodoc.A_variable_b_set), "A_variable_b_set(A self, int variable_b)")
|
||||||
|
check(inspect.getdoc(_autodoc.A_variable_b_get), "A_variable_b_get(A self) -> int")
|
||||||
|
check(inspect.getdoc(_autodoc.A_variable_c_set),
|
||||||
|
"A_variable_c_set(self, variable_c)\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"variable_c: int"
|
||||||
|
)
|
||||||
|
check(inspect.getdoc(_autodoc.A_variable_c_get), "A_variable_c_get(self) -> int")
|
||||||
|
check(inspect.getdoc(_autodoc.A_variable_d_set),
|
||||||
|
"A_variable_d_set(A self, int variable_d)\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"variable_d: int"
|
||||||
|
)
|
||||||
|
check(inspect.getdoc(_autodoc.A_variable_d_get), "A_variable_d_get(A self) -> int")
|
||||||
|
check(inspect.getdoc(_autodoc.new_C), "new_C(a, b, h) -> C")
|
||||||
|
check(inspect.getdoc(_autodoc.delete_C), "delete_C(self)")
|
||||||
|
check(inspect.getdoc(_autodoc.new_D), "new_D(int a, int b, Hola h) -> D")
|
||||||
|
check(inspect.getdoc(_autodoc.delete_D), "delete_D(D self)")
|
||||||
|
check(inspect.getdoc(_autodoc.new_E),
|
||||||
|
"new_E(a, b, h) -> E\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"a: special comment for parameter a\n"
|
||||||
|
"b: another special comment for parameter b\n"
|
||||||
|
"h: enum Hola"
|
||||||
|
)
|
||||||
|
check(inspect.getdoc(_autodoc.delete_E), "delete_E(self)")
|
||||||
|
check(inspect.getdoc(_autodoc.new_F),
|
||||||
|
"new_F(int a, int b, Hola h) -> F\n"
|
||||||
|
"\n"
|
||||||
|
"Parameters\n"
|
||||||
|
"----------\n"
|
||||||
|
"a: special comment for parameter a\n"
|
||||||
|
"b: another special comment for parameter b\n"
|
||||||
|
"h: enum Hola"
|
||||||
|
)
|
||||||
|
check(inspect.getdoc(_autodoc.delete_F), "delete_F(F self)")
|
||||||
|
check(inspect.getdoc(_autodoc.B_funk), "B_funk(B self, int c, int d) -> int")
|
||||||
|
check(inspect.getdoc(_autodoc.TInteger_inout), "TInteger_inout(TInteger self, TInteger t) -> TInteger")
|
||||||
|
|
||||||
check(inspect.getdoc(B),
|
check(inspect.getdoc(B),
|
||||||
"Proxy of C++ B class.",
|
"Proxy of C++ B class.",
|
||||||
|
|
@ -164,8 +239,6 @@ check(inspect.getdoc(C.__init__), "__init__(self, a, b, h) -> C", None, skip)
|
||||||
check(inspect.getdoc(D.__init__),
|
check(inspect.getdoc(D.__init__),
|
||||||
"__init__(D self, int a, int b, Hola h) -> D", None, skip)
|
"__init__(D self, int a, int b, Hola h) -> D", None, skip)
|
||||||
check(inspect.getdoc(E.__init__),
|
check(inspect.getdoc(E.__init__),
|
||||||
"__init__(self, a, b, h) -> E\n"
|
|
||||||
"\n"
|
|
||||||
"__init__(self, a, b, h) -> E\n"
|
"__init__(self, a, b, h) -> E\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Parameters\n"
|
"Parameters\n"
|
||||||
|
|
@ -175,8 +248,6 @@ check(inspect.getdoc(E.__init__),
|
||||||
"h: enum Hola", None, skip
|
"h: enum Hola", None, skip
|
||||||
)
|
)
|
||||||
check(inspect.getdoc(F.__init__),
|
check(inspect.getdoc(F.__init__),
|
||||||
"__init__(F self, int a, int b, Hola h) -> F\n"
|
|
||||||
"\n"
|
|
||||||
"__init__(F self, int a, int b, Hola h) -> F\n"
|
"__init__(F self, int a, int b, Hola h) -> F\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Parameters\n"
|
"Parameters\n"
|
||||||
|
|
@ -190,8 +261,7 @@ check(inspect.getdoc(B.funk),
|
||||||
"funk(B self, int c, int d) -> int")
|
"funk(B self, int c, int d) -> int")
|
||||||
check(inspect.getdoc(funk), "funk(A e, short arg2, int c, int d) -> int")
|
check(inspect.getdoc(funk), "funk(A e, short arg2, int c, int d) -> int")
|
||||||
check(inspect.getdoc(funkdefaults),
|
check(inspect.getdoc(funkdefaults),
|
||||||
"funkdefaults(A e, short arg2, int c, int d, double f=2) -> int\n"
|
"funkdefaults(A e, short arg2, int c, int d, double f=2) -> int")
|
||||||
"funkdefaults(A e, short arg2, int c, int d) -> int")
|
|
||||||
|
|
||||||
check(inspect.getdoc(func_input), "func_input(int * INPUT) -> int")
|
check(inspect.getdoc(func_input), "func_input(int * INPUT) -> int")
|
||||||
check(inspect.getdoc(func_output), "func_output() -> int")
|
check(inspect.getdoc(func_output), "func_output() -> int")
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,11 @@ typedef struct swig_const_info {
|
||||||
swig_type_info **ptype;
|
swig_type_info **ptype;
|
||||||
} swig_const_info;
|
} swig_const_info;
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Function to find the method definition with the correct docstring for the
|
||||||
|
* proxy module as opposed to the low-level API
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
PyMethodDef* getProxyDoc(const char* name);
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Wrapper of PyInstanceMethod_New() used in Python 3
|
* Wrapper of PyInstanceMethod_New() used in Python 3
|
||||||
|
|
@ -31,6 +36,17 @@ typedef struct swig_const_info {
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
|
SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
|
||||||
{
|
{
|
||||||
|
if (PyCFunction_Check(func)) {
|
||||||
|
/* Unpack the existing PyCFunction */
|
||||||
|
PyMethodDef* ml = ((PyCFunctionObject*) func)->m_ml;
|
||||||
|
PyObject* self = ((PyCFunctionObject*) func)->m_self;
|
||||||
|
PyObject* module = ((PyCFunctionObject*) func)->m_module;
|
||||||
|
/* Use the copy with the modified docstring if available */
|
||||||
|
ml = getProxyDoc(ml->ml_name);
|
||||||
|
if (ml != NULL) {
|
||||||
|
func = PyCFunction_NewEx(ml, self, module);
|
||||||
|
}
|
||||||
|
}
|
||||||
#if PY_VERSION_HEX >= 0x03000000
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
return PyInstanceMethod_New(func);
|
return PyInstanceMethod_New(func);
|
||||||
#else
|
#else
|
||||||
|
|
@ -38,6 +54,26 @@ SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self),
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Wrapper of PyStaticMethod_New()
|
||||||
|
* It is exported to the generated module, used for -fastproxy
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
SWIGRUNTIME PyObject* SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
|
||||||
|
{
|
||||||
|
if (PyCFunction_Check(func)) {
|
||||||
|
/* Unpack the existing PyCFunction */
|
||||||
|
PyMethodDef* ml = ((PyCFunctionObject*) func)->m_ml;
|
||||||
|
PyObject* self = ((PyCFunctionObject*) func)->m_self;
|
||||||
|
PyObject* module = ((PyCFunctionObject*) func)->m_module;
|
||||||
|
/* Use the copy with the modified docstring if available */
|
||||||
|
ml = getProxyDoc(ml->ml_name);
|
||||||
|
if (ml != NULL) {
|
||||||
|
func = PyCFunction_NewEx(ml, self, module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PyStaticMethod_New(func);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1081,6 +1081,8 @@ int Language::functionHandler(Node *n) {
|
||||||
globalfunctionHandler(n);
|
globalfunctionHandler(n);
|
||||||
InClass = oldInClass;
|
InClass = oldInClass;
|
||||||
} else {
|
} else {
|
||||||
|
// This is a member function, set a flag so the documentation type is correct
|
||||||
|
SetFlag(n, "memberfunction");
|
||||||
Node *explicit_n = 0;
|
Node *explicit_n = 0;
|
||||||
if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
|
if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
|
||||||
bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
|
bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
|
||||||
|
|
@ -1270,6 +1272,9 @@ int Language::memberfunctionHandler(Node *n) {
|
||||||
int flags = Getattr(n, "template") ? extendmember | SmartPointer : Extend | SmartPointer | DirectorExtraCall;
|
int flags = Getattr(n, "template") ? extendmember | SmartPointer : Extend | SmartPointer | DirectorExtraCall;
|
||||||
Swig_MethodToFunction(n, NSpace, ClassType, flags, director_type, is_member_director(CurrentClass, n));
|
Swig_MethodToFunction(n, NSpace, ClassType, flags, director_type, is_member_director(CurrentClass, n));
|
||||||
Setattr(n, "sym:name", fname);
|
Setattr(n, "sym:name", fname);
|
||||||
|
/* Explicitly save low-level and high-level documentation names */
|
||||||
|
Setattr(n, "doc:low:name", fname);
|
||||||
|
Setattr(n, "doc:high:name", symname);
|
||||||
|
|
||||||
functionWrapper(n);
|
functionWrapper(n);
|
||||||
|
|
||||||
|
|
@ -1330,6 +1335,9 @@ int Language::staticmemberfunctionHandler(Node *n) {
|
||||||
|
|
||||||
Setattr(n, "name", cname);
|
Setattr(n, "name", cname);
|
||||||
Setattr(n, "sym:name", mrename);
|
Setattr(n, "sym:name", mrename);
|
||||||
|
/* Explicitly save low-level and high-level documentation names */
|
||||||
|
Setattr(n, "doc:low:name", mrename);
|
||||||
|
Setattr(n, "doc:high:name", symname);
|
||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
String *cbname = NewStringf(cb, symname);
|
String *cbname = NewStringf(cb, symname);
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ static String *builtin_default_unref = 0;
|
||||||
static String *builtin_closures_code = 0;
|
static String *builtin_closures_code = 0;
|
||||||
|
|
||||||
static String *methods;
|
static String *methods;
|
||||||
|
static String *methods_proxydocs;
|
||||||
static String *class_name;
|
static String *class_name;
|
||||||
static String *shadow_indent = 0;
|
static String *shadow_indent = 0;
|
||||||
static int in_class = 0;
|
static int in_class = 0;
|
||||||
|
|
@ -100,7 +101,8 @@ enum autodoc_t {
|
||||||
AUTODOC_STATICFUNC,
|
AUTODOC_STATICFUNC,
|
||||||
AUTODOC_FUNC,
|
AUTODOC_FUNC,
|
||||||
AUTODOC_METHOD,
|
AUTODOC_METHOD,
|
||||||
AUTODOC_CONST
|
AUTODOC_CONST,
|
||||||
|
AUTODOC_VAR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -571,6 +573,7 @@ public:
|
||||||
|
|
||||||
const_code = NewString("");
|
const_code = NewString("");
|
||||||
methods = NewString("");
|
methods = NewString("");
|
||||||
|
methods_proxydocs = NewString("");
|
||||||
|
|
||||||
Swig_banner(f_begin);
|
Swig_banner(f_begin);
|
||||||
|
|
||||||
|
|
@ -701,6 +704,7 @@ public:
|
||||||
if (!builtin && fastproxy) {
|
if (!builtin && fastproxy) {
|
||||||
Printf(f_shadow, "\n");
|
Printf(f_shadow, "\n");
|
||||||
Printf(f_shadow, "_swig_new_instance_method = %s.SWIG_PyInstanceMethod_New\n", module);
|
Printf(f_shadow, "_swig_new_instance_method = %s.SWIG_PyInstanceMethod_New\n", module);
|
||||||
|
Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -800,9 +804,11 @@ public:
|
||||||
Printf(f_wrappers, "#endif\n");
|
Printf(f_wrappers, "#endif\n");
|
||||||
Append(const_code, "static swig_const_info swig_const_table[] = {\n");
|
Append(const_code, "static swig_const_info swig_const_table[] = {\n");
|
||||||
Append(methods, "static PyMethodDef SwigMethods[] = {\n");
|
Append(methods, "static PyMethodDef SwigMethods[] = {\n");
|
||||||
|
Append(methods_proxydocs, "static PyMethodDef SwigMethods_proxydocs[] = {\n");
|
||||||
|
|
||||||
/* the method exported for replacement of new.instancemethod in Python 3 */
|
/* the method exported for replacement of new.instancemethod in Python 3 */
|
||||||
add_pyinstancemethod_new();
|
add_pyinstancemethod_new();
|
||||||
|
add_pystaticmethod_new();
|
||||||
|
|
||||||
if (builtin) {
|
if (builtin) {
|
||||||
SwigType *s = NewString("SwigPyObject");
|
SwigType *s = NewString("SwigPyObject");
|
||||||
|
|
@ -824,6 +830,30 @@ public:
|
||||||
Append(methods, "\t { NULL, NULL, 0, NULL }\n");
|
Append(methods, "\t { NULL, NULL, 0, NULL }\n");
|
||||||
Append(methods, "};\n");
|
Append(methods, "};\n");
|
||||||
Printf(f_wrappers, "%s\n", methods);
|
Printf(f_wrappers, "%s\n", methods);
|
||||||
|
Append(methods_proxydocs, "\t { NULL, NULL, 0, NULL }\n");
|
||||||
|
Append(methods_proxydocs, "};\n");
|
||||||
|
Printf(f_wrappers, "%s\n", methods_proxydocs);
|
||||||
|
|
||||||
|
/* Need to define the function to find the proxy documentation after the proxy docs themselves */
|
||||||
|
Printv(f_wrappers, "PyMethodDef* getProxyDoc(const char* name)\n",
|
||||||
|
"{\n",
|
||||||
|
" /* Find the function in the modified method table */\n",
|
||||||
|
" size_t offset = 0;\n",
|
||||||
|
" int found = 0;\n",
|
||||||
|
" while (SwigMethods_proxydocs[offset].ml_meth != NULL) {\n",
|
||||||
|
" if (strcmp(SwigMethods_proxydocs[offset].ml_name, name) == 0) {\n",
|
||||||
|
" found = 1;\n",
|
||||||
|
" break;\n",
|
||||||
|
" }\n",
|
||||||
|
" offset++;\n",
|
||||||
|
" }\n",
|
||||||
|
" /* Use the copy with the modified docstring if available */\n",
|
||||||
|
" if (found == 1) {\n",
|
||||||
|
" return &SwigMethods_proxydocs[offset];\n",
|
||||||
|
" } else {\n",
|
||||||
|
" return NULL;\n",
|
||||||
|
" }\n",
|
||||||
|
"}\n", NIL);
|
||||||
|
|
||||||
if (builtin) {
|
if (builtin) {
|
||||||
Dump(f_builtins, f_wrappers);
|
Dump(f_builtins, f_wrappers);
|
||||||
|
|
@ -925,11 +955,35 @@ public:
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
int add_pyinstancemethod_new() {
|
int add_pyinstancemethod_new() {
|
||||||
String *name = NewString("SWIG_PyInstanceMethod_New");
|
String *name = NewString("SWIG_PyInstanceMethod_New");
|
||||||
Printf(methods, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
|
String *line = NewString("");
|
||||||
|
Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
|
||||||
|
Append(methods, line);
|
||||||
|
if (fastproxy) {
|
||||||
|
Append(methods_proxydocs, line);
|
||||||
|
}
|
||||||
|
Delete(line);
|
||||||
Delete(name);
|
Delete(name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------
|
||||||
|
* Emit the wrapper for PyStaticMethod_New to MethodDef array.
|
||||||
|
* This wrapper is used to ensure the correct documentation is
|
||||||
|
* generated for static methods when using -fastproxy
|
||||||
|
* ------------------------------------------------------------ */
|
||||||
|
int add_pystaticmethod_new() {
|
||||||
|
if (fastproxy) {
|
||||||
|
String *name = NewString("SWIG_PyStaticMethod_New");
|
||||||
|
String *line = NewString("");
|
||||||
|
Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
|
||||||
|
Append(methods, line);
|
||||||
|
Append(methods_proxydocs, line);
|
||||||
|
Delete(line);
|
||||||
|
Delete(name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------
|
/* ------------------------------------------------------------
|
||||||
* subpkg_tail()
|
* subpkg_tail()
|
||||||
*
|
*
|
||||||
|
|
@ -1477,7 +1531,7 @@ public:
|
||||||
* may be empty if there is no docstring).
|
* may be empty if there is no docstring).
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "") {
|
String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) {
|
||||||
String *docstr = Getattr(n, "feature:docstring");
|
String *docstr = Getattr(n, "feature:docstring");
|
||||||
if (docstr && Len(docstr)) {
|
if (docstr && Len(docstr)) {
|
||||||
docstr = Copy(docstr);
|
docstr = Copy(docstr);
|
||||||
|
|
@ -1489,7 +1543,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
|
if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
|
||||||
String *autodoc = make_autodoc(n, ad_type);
|
String *autodoc = make_autodoc(n, ad_type, low_level);
|
||||||
if (autodoc && Len(autodoc) > 0) {
|
if (autodoc && Len(autodoc) > 0) {
|
||||||
if (docstr && Len(docstr)) {
|
if (docstr && Len(docstr)) {
|
||||||
Append(autodoc, "\n");
|
Append(autodoc, "\n");
|
||||||
|
|
@ -1517,6 +1571,11 @@ public:
|
||||||
// depends on the comment which is not going to change, so we can
|
// depends on the comment which is not going to change, so we can
|
||||||
// safely cache it.
|
// safely cache it.
|
||||||
Setattr(n, "python:docstring", Copy(docstr));
|
Setattr(n, "python:docstring", Copy(docstr));
|
||||||
|
} else {
|
||||||
|
// Must copy here since if the docstring is multi-line, the String*
|
||||||
|
// here will get Deleted below, which is bad if it is a pointer to
|
||||||
|
// the cached object!
|
||||||
|
docstr = Copy(docstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1552,8 +1611,8 @@ public:
|
||||||
* set then it will build a combined docstring.
|
* set then it will build a combined docstring.
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
String *docstring(Node *n, autodoc_t ad_type, const String *indent) {
|
String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool low_level = false) {
|
||||||
String *docstr = build_combined_docstring(n, ad_type, indent);
|
String *docstr = build_combined_docstring(n, ad_type, indent, low_level);
|
||||||
if (!Len(docstr))
|
if (!Len(docstr))
|
||||||
return docstr;
|
return docstr;
|
||||||
|
|
||||||
|
|
@ -1582,9 +1641,9 @@ public:
|
||||||
* source code (but without quotes around it).
|
* source code (but without quotes around it).
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
String *cdocstring(Node *n, autodoc_t ad_type)
|
String *cdocstring(Node *n, autodoc_t ad_type, bool low_level = false)
|
||||||
{
|
{
|
||||||
String *ds = build_combined_docstring(n, ad_type);
|
String *ds = build_combined_docstring(n, ad_type, "", low_level);
|
||||||
Replaceall(ds, "\\", "\\\\");
|
Replaceall(ds, "\\", "\\\\");
|
||||||
Replaceall(ds, "\"", "\\\"");
|
Replaceall(ds, "\"", "\\\"");
|
||||||
Replaceall(ds, "\n", "\\n\"\n\t\t\"");
|
Replaceall(ds, "\n", "\\n\"\n\t\t\"");
|
||||||
|
|
@ -1598,14 +1657,14 @@ public:
|
||||||
*
|
*
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* plist - entire parameter list
|
* plist - entire parameter list
|
||||||
* arg_offset - argument number for first parameter
|
* arg_num - the number to start from when naming arguments
|
||||||
* Side effects:
|
* Side effects:
|
||||||
* The "lname" attribute in each parameter in plist will be contain a parameter name
|
* The "lname" attribute in each parameter in plist will be contain a parameter name
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void addMissingParameterNames(Node *n, ParmList *plist, int arg_offset) {
|
void addMissingParameterNames(Node *n, ParmList *plist, int arg_num) {
|
||||||
Parm *p = plist;
|
Parm *p = plist;
|
||||||
int i = arg_offset;
|
int i = arg_num;
|
||||||
while (p) {
|
while (p) {
|
||||||
if (!Getattr(p, "lname")) {
|
if (!Getattr(p, "lname")) {
|
||||||
String *name = makeParameterName(n, p, i);
|
String *name = makeParameterName(n, p, i);
|
||||||
|
|
@ -1622,10 +1681,11 @@ public:
|
||||||
*
|
*
|
||||||
* Generate the documentation for the function parameters
|
* Generate the documentation for the function parameters
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* arg_num: The number to start assigning unnamed arguments from
|
||||||
* func_annotation: Function annotation support
|
* func_annotation: Function annotation support
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
String *make_autodocParmList(Node *n, bool showTypes, bool calling = false, bool func_annotation = false) {
|
String *make_autodocParmList(Node *n, bool showTypes, int arg_num = 1, bool calling = false, bool func_annotation = false) {
|
||||||
|
|
||||||
String *doc = NewString("");
|
String *doc = NewString("");
|
||||||
String *pdocs = 0;
|
String *pdocs = 0;
|
||||||
|
|
@ -1633,15 +1693,6 @@ public:
|
||||||
Parm *p;
|
Parm *p;
|
||||||
Parm *pnext;
|
Parm *pnext;
|
||||||
|
|
||||||
|
|
||||||
// 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)
|
if (calling)
|
||||||
func_annotation = false;
|
func_annotation = false;
|
||||||
|
|
||||||
|
|
@ -1654,8 +1705,7 @@ public:
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p = plist; p; p = pnext, arg_num++) {
|
for (p = plist; p; p = pnext) {
|
||||||
|
|
||||||
String *tm = Getattr(p, "tmap:in");
|
String *tm = Getattr(p, "tmap:in");
|
||||||
if (tm) {
|
if (tm) {
|
||||||
pnext = Getattr(p, "tmap:in:next");
|
pnext = Getattr(p, "tmap:in:next");
|
||||||
|
|
@ -1676,12 +1726,21 @@ public:
|
||||||
value = Getattr(p, "tmap:doc:value");
|
value = Getattr(p, "tmap:doc:value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip the "self" argument - it is added to the parameter list automatically
|
||||||
|
// and shouldn't be included in the Parameters block
|
||||||
|
if (Getattr(p, "self")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Note: the generated name should be consistent with that in kwnames[]
|
// Note: the generated name should be consistent with that in kwnames[]
|
||||||
String *made_name = 0;
|
String *made_name = 0;
|
||||||
if (!name) {
|
if (!name) {
|
||||||
name = made_name = makeParameterName(n, p, arg_num);
|
name = made_name = makeParameterName(n, p, arg_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increment the argument number once we are sure this is a real argument to count
|
||||||
|
arg_num++;
|
||||||
|
|
||||||
type = type ? type : Getattr(p, "type");
|
type = type ? type : Getattr(p, "type");
|
||||||
value = value ? value : Getattr(p, "value");
|
value = value ? value : Getattr(p, "value");
|
||||||
|
|
||||||
|
|
@ -1749,8 +1808,9 @@ public:
|
||||||
* and use it directly.
|
* and use it directly.
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
String *make_autodoc(Node *n, autodoc_t ad_type) {
|
String *make_autodoc(Node *n, autodoc_t ad_type, bool low_level = false) {
|
||||||
int extended = 0;
|
int extended = 0;
|
||||||
|
bool first_func = true;
|
||||||
// If the function is overloaded then this function is called
|
// If the function is overloaded then this function is called
|
||||||
// for the last one. Rewind to the first so the docstrings are
|
// for the last one. Rewind to the first so the docstrings are
|
||||||
// in order.
|
// in order.
|
||||||
|
|
@ -1787,10 +1847,24 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipAuto) {
|
if (!skipAuto) {
|
||||||
String *symname = Getattr(n, "sym:name");
|
/* Check if a documentation name was given for either the low-level C API or high-level Python shadow API */
|
||||||
|
String *symname = Getattr(n, low_level? "doc:low:name" : "doc:high:name");
|
||||||
|
if (!symname) {
|
||||||
|
symname = Getattr(n, "sym:name");
|
||||||
|
}
|
||||||
|
|
||||||
SwigType *type = Getattr(n, "type");
|
SwigType *type = Getattr(n, "type");
|
||||||
String *type_str = NULL;
|
String *type_str = NULL;
|
||||||
|
|
||||||
|
// If the function has default arguments, then that documentation covers this version too
|
||||||
|
if (Getattr(n, "defaultargs") != NULL) {
|
||||||
|
n = Getattr(n, "sym:nextSibling");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! first_func)
|
||||||
|
Append(doc, "\n");
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
if (Strcmp(type, "void") == 0) {
|
if (Strcmp(type, "void") == 0) {
|
||||||
type_str = NULL;
|
type_str = NULL;
|
||||||
|
|
@ -1800,6 +1874,21 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Treat the low-level C API functions for getting/setting variables as methods for documentation purposes */
|
||||||
|
String *kind = Getattr(n, "kind");
|
||||||
|
if (kind && Strcmp(kind, "variable") == 0) {
|
||||||
|
if (ad_type == AUTODOC_FUNC) {
|
||||||
|
ad_type = AUTODOC_METHOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Treat destructors as methods for documentation purposes */
|
||||||
|
String *nodeType = Getattr(n, "nodeType");
|
||||||
|
if (nodeType && Strcmp(nodeType, "destructor") == 0) {
|
||||||
|
if (ad_type == AUTODOC_FUNC) {
|
||||||
|
ad_type = AUTODOC_METHOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (ad_type) {
|
switch (ad_type) {
|
||||||
case AUTODOC_CLASS:
|
case AUTODOC_CLASS:
|
||||||
{
|
{
|
||||||
|
|
@ -1823,7 +1912,7 @@ public:
|
||||||
break;
|
break;
|
||||||
case AUTODOC_CTOR:
|
case AUTODOC_CTOR:
|
||||||
if (Strcmp(class_name, symname) == 0) {
|
if (Strcmp(class_name, symname) == 0) {
|
||||||
String *paramList = make_autodocParmList(n, showTypes);
|
String *paramList = make_autodocParmList(n, showTypes, 2);
|
||||||
Printf(doc, "__init__(");
|
Printf(doc, "__init__(");
|
||||||
if (showTypes)
|
if (showTypes)
|
||||||
Printf(doc, "%s ", class_name);
|
Printf(doc, "%s ", class_name);
|
||||||
|
|
@ -1856,7 +1945,7 @@ public:
|
||||||
|
|
||||||
case AUTODOC_METHOD:
|
case AUTODOC_METHOD:
|
||||||
{
|
{
|
||||||
String *paramList = make_autodocParmList(n, showTypes);
|
String *paramList = make_autodocParmList(n, showTypes, 2);
|
||||||
Printf(doc, "%s(", symname);
|
Printf(doc, "%s(", symname);
|
||||||
if (showTypes)
|
if (showTypes)
|
||||||
Printf(doc, "%s ", class_name);
|
Printf(doc, "%s ", class_name);
|
||||||
|
|
@ -1873,19 +1962,36 @@ public:
|
||||||
// There is no autodoc support for constants currently, this enum
|
// There is no autodoc support for constants currently, this enum
|
||||||
// element only exists to allow calling docstring() with it.
|
// element only exists to allow calling docstring() with it.
|
||||||
return NULL;
|
return NULL;
|
||||||
|
case AUTODOC_VAR:
|
||||||
|
// Variables can also be documented (e.g. through the property() function in python)
|
||||||
|
Printf(doc, "%s", symname);
|
||||||
|
if (showTypes) {
|
||||||
|
String *type = Getattr(n, "tmap:doc:type");
|
||||||
|
if (! type)
|
||||||
|
type = Getattr(n, "membervariableHandler:type");
|
||||||
|
if (! type)
|
||||||
|
type = Getattr(n, "type");
|
||||||
|
Printf(doc, " : %s", type);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Delete(type_str);
|
Delete(type_str);
|
||||||
}
|
|
||||||
if (extended) {
|
// Special case: wrapper functions to get a variable should have no parameters.
|
||||||
String *pdocs = Getattr(n, "feature:pdocs");
|
// Because the node is re-used for the setter and getter, the feature:pdocs field will
|
||||||
if (pdocs) {
|
// exist for the getter function, so explicitly avoid printing parameters in this case.
|
||||||
Printv(doc, "\n", pdocs, NULL);
|
bool variable_getter = kind && Strcmp(kind, "variable") == 0 && Getattr(n, "memberget");
|
||||||
|
if (extended && ad_type != AUTODOC_VAR && !variable_getter) {
|
||||||
|
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
|
// if it's overloaded then get the next decl and loop around again
|
||||||
n = Getattr(n, "sym:nextSibling");
|
n = Getattr(n, "sym:nextSibling");
|
||||||
if (n)
|
if (n)
|
||||||
Append(doc, "\n");
|
first_func = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
|
|
@ -2132,7 +2238,7 @@ public:
|
||||||
* Generate parameter list for Python functions or methods,
|
* Generate parameter list for Python functions or methods,
|
||||||
* reuse make_autodocParmList() to do so.
|
* reuse make_autodocParmList() to do so.
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
String *make_pyParmList(Node *n, bool in_class, bool is_calling, int kw) {
|
String *make_pyParmList(Node *n, bool in_class, bool is_calling, int kw, bool has_self_for_count = false) {
|
||||||
/* Get the original function for a defaultargs copy,
|
/* Get the original function for a defaultargs copy,
|
||||||
* see default_arguments() in parser.y. */
|
* see default_arguments() in parser.y. */
|
||||||
Node *nn = Getattr(n, "defaultargs");
|
Node *nn = Getattr(n, "defaultargs");
|
||||||
|
|
@ -2165,7 +2271,7 @@ public:
|
||||||
|
|
||||||
bool funcanno = py3 ? true : false;
|
bool funcanno = py3 ? true : false;
|
||||||
String *params = NewString("");
|
String *params = NewString("");
|
||||||
String *_params = make_autodocParmList(n, false, is_calling, funcanno);
|
String *_params = make_autodocParmList(n, false, ((in_class || has_self_for_count)? 2 : 1), is_calling, funcanno);
|
||||||
|
|
||||||
if (in_class) {
|
if (in_class) {
|
||||||
Printf(params, "self");
|
Printf(params, "self");
|
||||||
|
|
@ -2244,7 +2350,7 @@ public:
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
bool have_addtofunc(Node *n) {
|
bool have_addtofunc(Node *n) {
|
||||||
return have_pythonappend(n) || have_pythonprepend(n) || have_docstring(n);
|
return have_pythonappend(n) || have_pythonprepend(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2302,7 +2408,7 @@ public:
|
||||||
/* Make a wrapper function to insert the code into */
|
/* Make a wrapper function to insert the code into */
|
||||||
Printv(f_dest, "\n", "def ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
|
Printv(f_dest, "\n", "def ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
|
||||||
if (have_docstring(n))
|
if (have_docstring(n))
|
||||||
Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4), "\n", NIL);
|
Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4, true), "\n", NIL);
|
||||||
if (have_pythonprepend(n))
|
if (have_pythonprepend(n))
|
||||||
Printv(f_dest, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
|
Printv(f_dest, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
|
||||||
if (have_pythonappend(n)) {
|
if (have_pythonappend(n)) {
|
||||||
|
|
@ -2340,38 +2446,62 @@ public:
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
void add_method(String *name, String *function, int kw, Node *n = 0, int funpack = 0, int num_required = -1, int num_arguments = -1) {
|
void add_method(String *name, String *function, int kw, Node *n = 0, int funpack = 0, int num_required = -1, int num_arguments = -1) {
|
||||||
|
String * meth_str = NewString("");
|
||||||
if (!kw) {
|
if (!kw) {
|
||||||
if (n && funpack) {
|
if (n && funpack) {
|
||||||
if (num_required == 0 && num_arguments == 0) {
|
if (num_required == 0 && num_arguments == 0) {
|
||||||
Printf(methods, "\t { \"%s\", %s, METH_NOARGS, ", name, function);
|
Printf(meth_str, "\t { \"%s\", %s, METH_NOARGS, ", name, function);
|
||||||
} else if (num_required == 1 && num_arguments == 1) {
|
} else if (num_required == 1 && num_arguments == 1) {
|
||||||
Printf(methods, "\t { \"%s\", %s, METH_O, ", name, function);
|
Printf(meth_str, "\t { \"%s\", %s, METH_O, ", name, function);
|
||||||
} else {
|
} else {
|
||||||
Printf(methods, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
|
Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Printf(methods, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
|
Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Cast via void(*)(void) to suppress GCC -Wcast-function-type warning.
|
// Cast via void(*)(void) to suppress GCC -Wcast-function-type warning.
|
||||||
// Python should always call the function correctly, but the Python C API
|
// Python should always call the function correctly, but the Python C API
|
||||||
// requires us to store it in function pointer of a different type.
|
// requires us to store it in function pointer of a different type.
|
||||||
Printf(methods, "\t { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, ", name, function);
|
Printf(meth_str, "\t { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, ", name, function);
|
||||||
}
|
}
|
||||||
|
Append(methods, meth_str);
|
||||||
|
if (fastproxy) {
|
||||||
|
Append(methods_proxydocs, meth_str);
|
||||||
|
}
|
||||||
|
Delete(meth_str);
|
||||||
|
|
||||||
if (!n) {
|
if (!n) {
|
||||||
Append(methods, "NULL");
|
Append(methods, "NULL");
|
||||||
|
if (fastproxy) {
|
||||||
|
Append(methods_proxydocs, "NULL");
|
||||||
|
}
|
||||||
} else if (have_docstring(n)) {
|
} else if (have_docstring(n)) {
|
||||||
String *ds = cdocstring(n, AUTODOC_FUNC);
|
/* Use the low-level docstring here since this is the docstring that will be used for the C API */
|
||||||
|
String *ds = cdocstring(n, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC, true);
|
||||||
Printf(methods, "\"%s\"", ds);
|
Printf(methods, "\"%s\"", ds);
|
||||||
|
if (fastproxy) {
|
||||||
|
/* In the fastproxy case, we must also record the high-level docstring for use in the Python shadow API */
|
||||||
|
ds = cdocstring(n, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC);
|
||||||
|
Printf(methods_proxydocs, "\"%s\"", ds);
|
||||||
|
}
|
||||||
Delete(ds);
|
Delete(ds);
|
||||||
} else if (Getattr(n, "feature:callback")) {
|
} else if (Getattr(n, "feature:callback")) {
|
||||||
Printf(methods, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
|
Printf(methods, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
|
||||||
|
if (fastproxy) {
|
||||||
|
Printf(methods_proxydocs, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Append(methods, "NULL");
|
Append(methods, "NULL");
|
||||||
|
if (fastproxy) {
|
||||||
|
Append(methods_proxydocs, "NULL");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Append(methods, "},\n");
|
Append(methods, "},\n");
|
||||||
|
if (fastproxy) {
|
||||||
|
Append(methods_proxydocs, "},\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------
|
/* ------------------------------------------------------------
|
||||||
|
|
@ -3187,6 +3317,10 @@ public:
|
||||||
Delete(h);
|
Delete(h);
|
||||||
}
|
}
|
||||||
Setattr(h, "getter", "SwigPyObject_get___dict__");
|
Setattr(h, "getter", "SwigPyObject_get___dict__");
|
||||||
|
if (! Getattr(h, "doc")) {
|
||||||
|
Setattr(n, "doc:high:name", Getattr(n, "name"));
|
||||||
|
Setattr(h, "doc", cdocstring(n, AUTODOC_VAR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builtin_getter) {
|
if (builtin_getter) {
|
||||||
|
|
@ -3201,6 +3335,10 @@ public:
|
||||||
}
|
}
|
||||||
Setattr(h, "getter", wrapper_name);
|
Setattr(h, "getter", wrapper_name);
|
||||||
Delattr(n, "memberget");
|
Delattr(n, "memberget");
|
||||||
|
if (! Getattr(h, "doc")) {
|
||||||
|
Setattr(n, "doc:high:name", Getattr(n, "name"));
|
||||||
|
Setattr(h, "doc", cdocstring(n, AUTODOC_VAR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (builtin_setter) {
|
if (builtin_setter) {
|
||||||
String *memname = Getattr(n, "membervariableHandler:sym:name");
|
String *memname = Getattr(n, "membervariableHandler:sym:name");
|
||||||
|
|
@ -3214,6 +3352,10 @@ public:
|
||||||
}
|
}
|
||||||
Setattr(h, "setter", wrapper_name);
|
Setattr(h, "setter", wrapper_name);
|
||||||
Delattr(n, "memberset");
|
Delattr(n, "memberset");
|
||||||
|
if (! Getattr(h, "doc")) {
|
||||||
|
Setattr(n, "doc:high:name", Getattr(n, "name"));
|
||||||
|
Setattr(h, "doc", cdocstring(n, AUTODOC_VAR));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_class && builtin) {
|
if (in_class && builtin) {
|
||||||
|
|
@ -3888,9 +4030,15 @@ public:
|
||||||
const char *setter_closure = setter ? funpack ? "SwigPyBuiltin_FunpackSetterClosure" : "SwigPyBuiltin_SetterClosure" : "0";
|
const char *setter_closure = setter ? funpack ? "SwigPyBuiltin_FunpackSetterClosure" : "SwigPyBuiltin_SetterClosure" : "0";
|
||||||
String *gspair = NewStringf("%s_%s_getset", symname, memname);
|
String *gspair = NewStringf("%s_%s_getset", symname, memname);
|
||||||
Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0");
|
Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0");
|
||||||
|
String *doc;
|
||||||
|
if (Getattr(mgetset, "doc")) {
|
||||||
|
doc = Getattr(mgetset, "doc");
|
||||||
|
} else {
|
||||||
|
doc = NewStringf("%s.%s", name, memname);
|
||||||
|
}
|
||||||
String *entry =
|
String *entry =
|
||||||
NewStringf("{ (char *)\"%s\", (getter)%s, (setter)%s, (char *)\"%s.%s\", (void *)&%s }\n", memname, getter_closure,
|
NewStringf("{ (char *)\"%s\", (getter)%s, (setter)%s, (char *)\"%s\", (void *)&%s }\n", memname, getter_closure,
|
||||||
setter_closure, name, memname, gspair);
|
setter_closure, doc, gspair);
|
||||||
if (GetFlag(mgetset, "static")) {
|
if (GetFlag(mgetset, "static")) {
|
||||||
Printf(f, "static PyGetSetDef %s_def = %s;\n", gspair, entry);
|
Printf(f, "static PyGetSetDef %s_def = %s;\n", gspair, entry);
|
||||||
Printf(f_init, "static_getset = SwigPyStaticVar_new_getset(metatype, &%s_def);\n", gspair);
|
Printf(f_init, "static_getset = SwigPyStaticVar_new_getset(metatype, &%s_def);\n", gspair);
|
||||||
|
|
@ -4559,6 +4707,8 @@ public:
|
||||||
if (!have_addtofunc(n)) {
|
if (!have_addtofunc(n)) {
|
||||||
if (!fastproxy || olddefs) {
|
if (!fastproxy || olddefs) {
|
||||||
Printv(f_shadow, "\n", 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_METHOD, tab8), "\n", NIL);
|
||||||
Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n", NIL);
|
Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n", NIL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4642,6 +4792,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
|
String *staticfunc_name = NewString(fastproxy ? "_swig_new_static_method" : "staticmethod");
|
||||||
bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
|
bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
|
||||||
if (!fast || olddefs) {
|
if (!fast || olddefs) {
|
||||||
int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
|
int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
|
||||||
|
|
@ -4664,9 +4815,10 @@ public:
|
||||||
|
|
||||||
// Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first.
|
// Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first.
|
||||||
if (fast) {
|
if (fast) {
|
||||||
Printv(f_shadow, tab4, symname, " = staticmethod(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname),
|
Printv(f_shadow, tab4, symname, " = ", staticfunc_name, "(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname),
|
||||||
")\n", NIL);
|
")\n", NIL);
|
||||||
}
|
}
|
||||||
|
Delete(staticfunc_name);
|
||||||
}
|
}
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -4743,7 +4895,7 @@ public:
|
||||||
|
|
||||||
String *parms = make_pyParmList(n, true, false, allow_kwargs);
|
String *parms = make_pyParmList(n, true, false, allow_kwargs);
|
||||||
/* Pass 'self' only if using director */
|
/* Pass 'self' only if using director */
|
||||||
String *callParms = make_pyParmList(n, false, true, allow_kwargs);
|
String *callParms = make_pyParmList(n, false, true, allow_kwargs, true);
|
||||||
|
|
||||||
if (use_director) {
|
if (use_director) {
|
||||||
Insert(callParms, 0, "_self, ");
|
Insert(callParms, 0, "_self, ");
|
||||||
|
|
@ -4881,6 +5033,8 @@ public:
|
||||||
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
|
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
|
||||||
if (assignable)
|
if (assignable)
|
||||||
Printv(f_shadow, ", ", module, ".", setname, NIL);
|
Printv(f_shadow, ", ", module, ".", setname, NIL);
|
||||||
|
if (have_docstring(n))
|
||||||
|
Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
|
||||||
Printv(f_shadow, ")\n", NIL);
|
Printv(f_shadow, ")\n", NIL);
|
||||||
Delete(mname);
|
Delete(mname);
|
||||||
Delete(setname);
|
Delete(setname);
|
||||||
|
|
@ -4946,6 +5100,8 @@ public:
|
||||||
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
|
Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
|
||||||
if (assignable)
|
if (assignable)
|
||||||
Printv(f_shadow, ", ", module, ".", setname, NIL);
|
Printv(f_shadow, ", ", module, ".", setname, NIL);
|
||||||
|
if (have_docstring(n))
|
||||||
|
Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
|
||||||
Printv(f_shadow, ")\n", NIL);
|
Printv(f_shadow, ")\n", NIL);
|
||||||
}
|
}
|
||||||
String *getter = Getattr(n, "pybuiltin:getter");
|
String *getter = Getattr(n, "pybuiltin:getter");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue