Merge branch 'docstring-indentation'

* docstring-indentation:
  Improve python code indentation warning / error messages
  Function comment header formatting corrections
  Improve Python docstring indentation handling
This commit is contained in:
William S Fulton 2015-07-30 20:17:49 +01:00
commit 00a9b8d3af
9 changed files with 410 additions and 78 deletions

View file

@ -5,6 +5,41 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.7 (in progress)
===========================
2015-07-29: wsfulton
[Python] Improve indentation warning and error messages for code in the following directives:
%pythonprepend
%pythonappend
%pythoncode
%pythonbegin
%feature("shadow")
Old error example:
Error: Line indented less than expected (line 3 of pythoncode)
New error example:
Error: Line indented less than expected (line 3 of %pythoncode or %insert("python") block)
as no line should be indented less than the indentation in line 1
Old warning example:
Warning 740: Whitespace prefix doesn't match (line 2 of %pythoncode or %insert("python") block)
New warning example:
Warning 740: Whitespace indentation is inconsistent compared to earlier lines (line 3 of
%pythoncode or %insert("python") block)
2015-07-28: wsfulton
[Python] Fix #475. Improve docstring indentation handling.
SWIG-3.0.5 and earlier sometimes truncated text provided in the docstring feature.
This occurred when the indentation (whitespace) in the docstring was less in the
second or later lines when compared to the first line.
SWIG-3.0.6 gave a 'Line indented less than expected' error instead of truncating
the docstring text.
Now the indentation for the 'docstring' feature is smarter and is appropriately
adjusted so that no truncation occurs.
2015-07-22: wsfulton
Support for special variable expansion in typemap attributes. Example usage expansion
in the 'out' attribute (C# specific):

View file

@ -1 +1 @@
swig_pythoncode_bad.i:7: Error: Line indented less than expected (line 2 of pythoncode)
swig_pythoncode_bad.i:7: Error: Line indented less than expected (line 2 of %pythoncode or %insert("python") block) as no line should be indented less than the indentation in line 1

View file

@ -1 +1 @@
swig_pythoncode_bad2.i:13: Error: Line indented less than expected (line 3 of pythoncode)
swig_pythoncode_bad2.i:13: Error: Line indented less than expected (line 3 of %pythoncode or %insert("python") block) as no line should be indented less than the indentation in line 1

View file

@ -0,0 +1,7 @@
%module xxx
%pythoncode %{
def extra():
print "extra a" # indentation is 2 spaces then tab
print "extra b" # indentation is tab then 2 spaces
%}

View file

@ -0,0 +1 @@
swig_pythoncode_bad3.i:7: Warning 740: Whitespace indentation is inconsistent compared to earlier lines (line 3 of %pythoncode or %insert("python") block)

View file

@ -59,6 +59,7 @@ CPP_TEST_CASES += \
python_abstractbase \
python_append \
python_director \
python_docstring \
python_nondynamic \
python_overload_simple_cast \
python_pythoncode \

View file

@ -0,0 +1,100 @@
from python_docstring import *
import inspect
def check(got, expected):
expected_list = expected.split("\n")
got_list = got.split("\n")
if expected_list != got_list:
raise RuntimeError("\n" + "Expected: " + str(expected_list) + "\n" + "Got : " + str(got_list))
# When getting docstrings, use inspect.getdoc(x) instead of x.__doc__ otherwise the different options
# such as -O, -builtin, -classic produce different initial indentation.
check(inspect.getdoc(DocStrings.docstring1),
" line 1\n"
"line 2\n"
"\n"
"\n"
"\n"
"line 3"
)
check(inspect.getdoc(DocStrings.docstring2),
"line 1\n"
" line 2\n"
"\n"
"\n"
"\n"
" line 3"
)
check(inspect.getdoc(DocStrings.docstring3),
"line 1\n"
" line 2\n"
"\n"
"\n"
"\n"
" line 3"
)
check(inspect.getdoc(DocStrings.docstring4),
"line 1\n"
" line 2\n"
"\n"
"\n"
"\n"
" line 3"
)
check(inspect.getdoc(DocStrings.docstring5),
"line 1\n"
" line 2\n"
"\n"
"\n"
"\n"
" line 3"
)
check(inspect.getdoc(DocStrings.docstring6),
"line 1\n"
" line 2\n"
"\n"
"\n"
"\n"
" line 3"
)
check(inspect.getdoc(DocStrings.docstring7),
"line 1\n"
"line 2\n"
"line 3"
)
check(inspect.getdoc(DocStrings.docstringA),
"first line\n"
"second line"
)
check(inspect.getdoc(DocStrings.docstringB),
"first line\n"
"second line"
)
check(inspect.getdoc(DocStrings.docstringC),
"first line\n"
"second line"
)
# One line doc special case, use __doc__
check(DocStrings.docstringX.__doc__,
" one line docs"
)
check(inspect.getdoc(DocStrings.docstringX),
"one line docs"
)
check(inspect.getdoc(DocStrings.docstringY),
"one line docs"
)

View file

@ -0,0 +1,98 @@
%module python_docstring
// Test indentation when using the docstring feature.
// Checks tabs and spaces as input for indentation.
%feature("docstring") docstring1 %{
line 1
line 2
line 3
%}
%feature("docstring") docstring2 %{
line 1
line 2
line 3
%}
%feature("docstring") docstring3 %{
line 1
line 2
line 3
%}
%feature("docstring") docstring4 %{
line 1
line 2
line 3
%}
%feature("docstring") docstring5
%{ line 1
line 2
line 3
%}
%feature("docstring") docstring6
{
line 1
line 2
line 3
}
%feature("docstring") docstring7
{
line 1
line 2
line 3
}
%feature("docstring") docstringA
%{ first line
second line%}
%feature("docstring") docstringB
%{ first line
second line%}
%feature("docstring") docstringC
%{ first line
second line%}
%feature("docstring") docstringX " one line docs"
%feature("docstring") docstringY "one line docs"
%inline %{
struct DocStrings {
void docstring1() {}
void docstring2() {}
void docstring3() {}
void docstring4() {}
void docstring5() {}
void docstring6() {}
void docstring7() {}
void docstringA() {}
void docstringB() {}
void docstringC() {}
void docstringX() {}
void docstringY() {}
};
%}

View file

@ -12,6 +12,7 @@
* ----------------------------------------------------------------------------- */
#include "swigmod.h"
#include <limits.h>
#include "cparse.h"
#include <ctype.h>
#include <errno.h>
@ -1299,7 +1300,7 @@ public:
/* ------------------------------------------------------------
* import_name_string()
* ------------------------------------------------------------ */
* ------------------------------------------------------------ */
static String *import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) {
if (!relativeimport) {
@ -1345,9 +1346,10 @@ public:
/* ------------------------------------------------------------
* funcCall()
* Emit shadow code to call a function in the extension
* module. Using proper argument and calling style for
* given node n.
*
* Emit shadow code to call a function in the extension
* module. Using proper argument and calling style for
* given node n.
* ------------------------------------------------------------ */
String *funcCall(String *name, String *parms) {
String *str = NewString("");
@ -1356,12 +1358,15 @@ public:
return str;
}
/* ------------------------------------------------------------
* pythoncode() - Output python code into the shadow file
* indent_pythoncode()
*
* Format (indent) Python code.
* Remove leading whitespace from 'code' and re-indent using
* the indentation string in 'indent'.
* ------------------------------------------------------------ */
String *pythoncode(String *code, const_String_or_char_ptr indent, String * file, int line) {
String *indent_pythoncode(const String *code, const_String_or_char_ptr indent, String *file, int line, const char *directive_name) {
String *out = NewString("");
String *temp;
char *t;
@ -1383,7 +1388,7 @@ public:
// Line number within the pythoncode.
int py_line = 0;
String * initial = 0;
String *initial = 0;
Iterator si;
/* Get the initial indentation. Skip lines which only contain whitespace
@ -1401,7 +1406,7 @@ public:
const char *c = Char(si.item);
int i;
for (i = 0; isspace((unsigned char)c[i]); i++) {
// Scan forward until we find a non-space (which may be a nul byte).
// Scan forward until we find a non-space (which may be a null byte).
}
char ch = c[i];
if (ch && ch != '#') {
@ -1423,7 +1428,7 @@ public:
int i;
for (i = 0; isspace((unsigned char)c[i]); i++) {
// Scan forward until we find a non-space (which may be a nul byte).
// Scan forward until we find a non-space (which may be a null byte).
}
char ch = c[i];
if (!ch) {
@ -1448,7 +1453,7 @@ public:
if (i < Len(initial)) {
// There's non-whitespace in the initial prefix of this line.
Swig_error(file, line, "Line indented less than expected (line %d of pythoncode)\n", py_line);
Swig_error(file, line, "Line indented less than expected (line %d of %s) as no line should be indented less than the indentation in line 1\n", py_line, directive_name);
Printv(out, indent, c, "\n", NIL);
} else {
if (memcmp(c, Char(initial), Len(initial)) == 0) {
@ -1457,7 +1462,7 @@ public:
continue;
}
Swig_warning(WARN_PYTHON_INDENT_MISMATCH,
file, line, "Whitespace prefix doesn't match (line %d of pythoncode)\n", py_line);
file, line, "Whitespace indentation is inconsistent compared to earlier lines (line %d of %s)\n", py_line, directive_name);
// To avoid gratuitously breaking interface files which worked with
// SWIG <= 3.0.5, we remove a prefix of the same number of bytes for
// lines which start with different whitespace to the line we got
@ -1469,6 +1474,72 @@ public:
return out;
}
/* ------------------------------------------------------------
* indent_docstring()
*
* Format (indent) a Python docstring.
* Remove leading whitespace from 'code' and re-indent using
* the indentation string in 'indent'.
* ------------------------------------------------------------ */
String *indent_docstring(const String *code, const_String_or_char_ptr indent) {
String *out = NewString("");
String *temp;
char *t;
if (!indent)
indent = "";
temp = NewString(code);
t = Char(temp);
if (*t == '{') {
Delitem(temp, 0);
Delitem(temp, DOH_END);
}
/* Split the input text into lines */
List *clist = SplitLines(temp);
Delete(temp);
Iterator si;
int truncate_characters_count = INT_MAX;
for (si = First(clist); si.item; si = Next(si)) {
const char *c = Char(si.item);
int i;
for (i = 0; isspace((unsigned char)c[i]); i++) {
// Scan forward until we find a non-space (which may be a null byte).
}
char ch = c[i];
if (ch) {
// Found a line which isn't just whitespace
if (i < truncate_characters_count)
truncate_characters_count = i;
}
}
if (truncate_characters_count == INT_MAX)
truncate_characters_count = 0;
for (si = First(clist); si.item; si = Next(si)) {
const char *c = Char(si.item);
int i;
for (i = 0; isspace((unsigned char)c[i]); i++) {
// Scan forward until we find a non-space (which may be a null byte).
}
char ch = c[i];
if (!ch) {
// Line is just whitespace - emit an empty line.
Putc('\n', out);
continue;
}
Printv(out, indent, c + truncate_characters_count, "\n", NIL);
}
Delete(clist);
return out;
}
/* ------------------------------------------------------------
* autodoc level declarations
@ -1504,8 +1575,9 @@ public:
/* ------------------------------------------------------------
* have_docstring()
* Check if there is a docstring directive and it has text,
* or there is an autodoc flag set
*
* Check if there is a docstring directive and it has text,
* or there is an autodoc flag set
* ------------------------------------------------------------ */
bool have_docstring(Node *n) {
@ -1515,9 +1587,10 @@ public:
/* ------------------------------------------------------------
* 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.
*
* 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) {
@ -1552,21 +1625,21 @@ public:
if (have_auto && have_ds) { // Both autodoc and docstring are present
doc = NewString("");
Printv(doc, triple_double, "\n",
pythoncode(autodoc, indent, Getfile(n), Getline(n)), "\n",
pythoncode(str, indent, Getfile(n), Getline(n)), indent, triple_double, NIL);
indent_docstring(autodoc, indent), "\n",
indent_docstring(str, indent), indent, triple_double, NIL);
} else if (!have_auto && have_ds) { // only docstring
if (Strchr(str, '\n') == 0) {
doc = NewStringf("%s%s%s", triple_double, str, triple_double);
} else {
doc = NewString("");
Printv(doc, triple_double, "\n", pythoncode(str, indent, Getfile(n), Getline(n)), indent, triple_double, NIL);
Printv(doc, triple_double, "\n", indent_docstring(str, indent), indent, triple_double, NIL);
}
} else if (have_auto && !have_ds) { // only autodoc
if (Strchr(autodoc, '\n') == 0) {
doc = NewStringf("%s%s%s", triple_double, autodoc, triple_double);
} else {
doc = NewString("");
Printv(doc, triple_double, "\n", pythoncode(autodoc, indent, Getfile(n), Getline(n)), indent, triple_double, NIL);
Printv(doc, triple_double, "\n", indent_docstring(autodoc, indent), indent, triple_double, NIL);
}
} else
doc = NewString("");
@ -1580,8 +1653,9 @@ public:
/* ------------------------------------------------------------
* cdocstring()
* Get the docstring text as it would appear in C-language
* source code.
*
* Get the docstring text as it would appear in C-language
* source code.
* ------------------------------------------------------------ */
String *cdocstring(Node *n, autodoc_t ad_type)
@ -1610,7 +1684,8 @@ public:
/* -----------------------------------------------------------------------------
* addMissingParameterNames()
* For functions that have not had nameless parameters set in the Language class.
*
* For functions that have not had nameless parameters set in the Language class.
*
* Inputs:
* plist - entire parameter list
@ -1635,8 +1710,9 @@ public:
/* ------------------------------------------------------------
* make_autodocParmList()
* Generate the documentation for the function parameters
* Parameters:
*
* Generate the documentation for the function parameters
* Parameters:
* func_annotation: Function annotation support
* ------------------------------------------------------------ */
@ -1743,12 +1819,13 @@ public:
/* ------------------------------------------------------------
* 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.
*
* 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) {
@ -1887,9 +1964,10 @@ public:
}
/* ------------------------------------------------------------
* convertDoubleValue()
* Check if the given string looks like a decimal floating point constant
* and return it if it does, otherwise return NIL.
* convertDoubleValue()
*
* Check if the given string looks like a decimal floating point constant
* and return it if it does, otherwise return NIL.
* ------------------------------------------------------------ */
String *convertDoubleValue(String *v) {
const char *const s = Char(v);
@ -1931,8 +2009,9 @@ public:
/* ------------------------------------------------------------
* convertValue()
* Check if string v can be a Python value literal or a
* constant. Return NIL if it isn't.
*
* Check if string v can be a Python value literal or a
* constant. Return NIL if it isn't.
* ------------------------------------------------------------ */
String *convertValue(String *v, SwigType *type) {
const char *const s = Char(v);
@ -2054,12 +2133,13 @@ public:
/* ------------------------------------------------------------
* is_representable_as_pyargs()
* Check if the function parameters default argument values
* can be represented in Python.
*
* If this method returns false, the parameters will be translated
* to a generic "*args" which allows us to deal with default values
* at C++ code level where they can always be handled.
* Check if the function parameters default argument values
* can be represented in Python.
*
* If this method returns false, the parameters will be translated
* to a generic "*args" which allows us to deal with default values
* at C++ code level where they can always be handled.
* ------------------------------------------------------------ */
bool is_representable_as_pyargs(Node *n) {
ParmList *plist = CopyParmList(Getattr(n, "parms"));
@ -2101,9 +2181,10 @@ public:
/* ------------------------------------------------------------
* is_real_overloaded()
* Check if the function is overloaded, but not just have some
* siblings generated due to the original function have
* default arguments.
*
* Check if the function is overloaded, but not just have some
* siblings generated due to the original function have
* default arguments.
* ------------------------------------------------------------ */
bool is_real_overloaded(Node *n) {
Node *h = Getattr(n, "sym:overloaded");
@ -2127,8 +2208,9 @@ public:
/* ------------------------------------------------------------
* make_pyParmList()
* Generate parameter list for Python functions or methods,
* reuse make_autodocParmList() to do so.
*
* Generate parameter list for Python functions or methods,
* reuse make_autodocParmList() to do so.
* ------------------------------------------------------------ */
String *make_pyParmList(Node *n, bool in_class, bool is_calling, int kw) {
/* Get the original function for a defaultargs copy,
@ -2174,7 +2256,8 @@ public:
/* ------------------------------------------------------------
* have_pythonprepend()
* Check if there is a %pythonprepend directive and it has text
*
* Check if there is a %pythonprepend directive and it has text
* ------------------------------------------------------------ */
bool have_pythonprepend(Node *n) {
@ -2184,7 +2267,8 @@ public:
/* ------------------------------------------------------------
* pythonprepend()
* Get the %pythonprepend code, stripping off {} if neccessary
*
* Get the %pythonprepend code, stripping off {} if neccessary
* ------------------------------------------------------------ */
String *pythonprepend(Node *n) {
@ -2199,7 +2283,8 @@ public:
/* ------------------------------------------------------------
* have_pythonappend()
* Check if there is a %pythonappend directive and it has text
*
* Check if there is a %pythonappend directive and it has text
* ------------------------------------------------------------ */
bool have_pythonappend(Node *n) {
@ -2211,7 +2296,8 @@ public:
/* ------------------------------------------------------------
* pythonappend()
* Get the %pythonappend code, stripping off {} if neccessary
*
* Get the %pythonappend code, stripping off {} if neccessary
* ------------------------------------------------------------ */
String *pythonappend(Node *n) {
@ -2229,7 +2315,8 @@ public:
/* ------------------------------------------------------------
* have_addtofunc()
* Check if there is a %addtofunc directive and it has text
*
* Check if there is a %addtofunc directive and it has text
* ------------------------------------------------------------ */
bool have_addtofunc(Node *n) {
@ -2239,8 +2326,9 @@ public:
/* ------------------------------------------------------------
* returnTypeAnnotation()
* Helper function for constructing the function annotation
* of the returning type, return a empty string for Python 2.x
*
* Helper function for constructing the function annotation
* of the returning type, return a empty string for Python 2.x
* ------------------------------------------------------------ */
String *returnTypeAnnotation(Node *n) {
String *ret = 0;
@ -2273,9 +2361,10 @@ public:
/* ------------------------------------------------------------
* emitFunctionShadowHelper()
* Refactoring some common code out of functionWrapper and
* dispatchFunction that writes the proxy code for non-member
* functions.
*
* Refactoring some common code out of functionWrapper and
* dispatchFunction that writes the proxy code for non-member
* functions.
* ------------------------------------------------------------ */
void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) {
@ -2286,10 +2375,10 @@ public:
if (have_docstring(n))
Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_dest, pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_dest, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
if (have_pythonappend(n)) {
Printv(f_dest, tab4 "val = ", funcCall(name, callParms), "\n", NIL);
Printv(f_dest, pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_dest, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_dest, tab4 "return val\n", NIL);
} else {
Printv(f_dest, tab4 "return ", funcCall(name, callParms), "\n", NIL);
@ -2304,7 +2393,8 @@ public:
/* ------------------------------------------------------------
* check_kwargs()
* check if using kwargs is allowed for this Node
*
* check if using kwargs is allowed for this Node
* ------------------------------------------------------------ */
int check_kwargs(Node *n) const {
@ -4498,7 +4588,7 @@ public:
have_repr = 1;
}
if (Getattr(n, "feature:shadow")) {
String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n));
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
String *pyaction = NewStringf("%s.%s", module, fullname);
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
@ -4520,12 +4610,12 @@ public:
Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL);
if (have_pythonprepend(n)) {
fproxy = 0;
Printv(f_shadow, pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
}
if (have_pythonappend(n)) {
fproxy = 0;
Printv(f_shadow, tab8, "val = ", funcCall(fullname, callParms), "\n", NIL);
Printv(f_shadow, pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow, tab8, "return val\n\n", NIL);
} else {
Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n\n", NIL);
@ -4605,10 +4695,10 @@ public:
if (have_docstring(n))
Printv(f_shadow, tab8, docstring(n, AUTODOC_STATICFUNC, tab8), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow, pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
if (have_pythonappend(n)) {
Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL);
Printv(f_shadow, pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\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);
@ -4693,7 +4783,7 @@ public:
if (!have_constructor && handled_as_init) {
if (!builtin) {
if (Getattr(n, "feature:shadow")) {
String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n));
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(NSPACE_TODO, symname));
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
@ -4722,7 +4812,7 @@ public:
if (have_docstring(n))
Printv(f_shadow, tab8, docstring(n, AUTODOC_CTOR, tab8), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow, pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
Printv(f_shadow, pass_self, NIL);
if (fastinit) {
Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self, ", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), ")\n", NIL);
@ -4732,7 +4822,7 @@ public:
tab8, "try:\n", tab8, tab4, "self.this.append(this)\n", tab8, "except:\n", tab8, tab4, "self.this = this\n", NIL);
}
if (have_pythonappend(n))
Printv(f_shadow, pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n)), "\n\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n\n", NIL);
Delete(pass_self);
}
have_constructor = 1;
@ -4741,7 +4831,7 @@ public:
/* Hmmm. We seem to be creating a different constructor. We're just going to create a
function for it. */
if (Getattr(n, "feature:shadow")) {
String *pycode = pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n));
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n), "%feature(\"shadow\")");
String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(NSPACE_TODO, symname));
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
@ -4755,7 +4845,7 @@ public:
if (have_docstring(n))
Printv(f_shadow_stubs, tab4, docstring(n, AUTODOC_CTOR, tab4), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow_stubs, pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
String *subfunc = NULL;
/*
if (builtin)
@ -4768,7 +4858,7 @@ public:
Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
#endif
if (have_pythonappend(n))
Printv(f_shadow_stubs, pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow_stubs, tab4, "return val\n", NIL);
Delete(subfunc);
}
@ -4805,7 +4895,7 @@ public:
if (shadow) {
if (Getattr(n, "feature:shadow")) {
String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n));
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
String *pyaction = NewStringf("%s.%s", module, Swig_name_destroy(NSPACE_TODO, symname));
Replaceall(pycode, "$action", pyaction);
Delete(pyaction);
@ -4823,7 +4913,7 @@ public:
if (have_docstring(n))
Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL);
if (have_pythonprepend(n))
Printv(f_shadow, pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
#ifdef USE_THISOWN
Printv(f_shadow, tab8, "try:\n", NIL);
Printv(f_shadow, tab8, tab4, "if self.thisown:", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL);
@ -4831,7 +4921,7 @@ public:
#else
#endif
if (have_pythonappend(n))
Printv(f_shadow, pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n)), "\n", NIL);
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
Printv(f_shadow, tab8, "pass\n", NIL);
Printv(f_shadow, "\n", NIL);
}
@ -5011,12 +5101,12 @@ public:
if (!ImportMode && (Cmp(section, "python") == 0 || Cmp(section, "shadow") == 0)) {
if (shadow) {
String *pycode = pythoncode(code, shadow_indent, Getfile(n), Getline(n));
String *pycode = indent_pythoncode(code, shadow_indent, Getfile(n), Getline(n), "%pythoncode or %insert(\"python\") block");
Printv(f_shadow, pycode, NIL);
Delete(pycode);
}
} else if (!ImportMode && (Cmp(section, "pythonbegin") == 0)) {
String *pycode = pythoncode(code, "", Getfile(n), Getline(n));
String *pycode = indent_pythoncode(code, "", Getfile(n), Getline(n), "%pythonbegin or %insert(\"pythonbegin\") block");
Printv(f_shadow_begin, pycode, NIL);
Delete(pycode);
} else {