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>
@ -1345,6 +1346,7 @@ public:
/* ------------------------------------------------------------
* funcCall()
*
* Emit shadow code to call a function in the extension
* module. Using proper argument and calling style for
* given node n.
@ -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;
@ -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,6 +1575,7 @@ public:
/* ------------------------------------------------------------
* have_docstring()
*
* Check if there is a docstring directive and it has text,
* or there is an autodoc flag set
* ------------------------------------------------------------ */
@ -1515,6 +1587,7 @@ 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.
@ -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,6 +1653,7 @@ public:
/* ------------------------------------------------------------
* cdocstring()
*
* Get the docstring text as it would appear in C-language
* source code.
* ------------------------------------------------------------ */
@ -1610,6 +1684,7 @@ public:
/* -----------------------------------------------------------------------------
* addMissingParameterNames()
*
* For functions that have not had nameless parameters set in the Language class.
*
* Inputs:
@ -1635,6 +1710,7 @@ public:
/* ------------------------------------------------------------
* make_autodocParmList()
*
* Generate the documentation for the function parameters
* Parameters:
* func_annotation: Function annotation support
@ -1743,6 +1819,7 @@ 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
@ -1888,6 +1965,7 @@ public:
/* ------------------------------------------------------------
* convertDoubleValue()
*
* Check if the given string looks like a decimal floating point constant
* and return it if it does, otherwise return NIL.
* ------------------------------------------------------------ */
@ -1931,6 +2009,7 @@ public:
/* ------------------------------------------------------------
* convertValue()
*
* Check if string v can be a Python value literal or a
* constant. Return NIL if it isn't.
* ------------------------------------------------------------ */
@ -2054,6 +2133,7 @@ public:
/* ------------------------------------------------------------
* is_representable_as_pyargs()
*
* Check if the function parameters default argument values
* can be represented in Python.
*
@ -2101,6 +2181,7 @@ 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.
@ -2127,6 +2208,7 @@ public:
/* ------------------------------------------------------------
* make_pyParmList()
*
* Generate parameter list for Python functions or methods,
* reuse make_autodocParmList() to do so.
* ------------------------------------------------------------ */
@ -2174,6 +2256,7 @@ public:
/* ------------------------------------------------------------
* have_pythonprepend()
*
* Check if there is a %pythonprepend directive and it has text
* ------------------------------------------------------------ */
@ -2184,6 +2267,7 @@ public:
/* ------------------------------------------------------------
* pythonprepend()
*
* Get the %pythonprepend code, stripping off {} if neccessary
* ------------------------------------------------------------ */
@ -2199,6 +2283,7 @@ public:
/* ------------------------------------------------------------
* have_pythonappend()
*
* Check if there is a %pythonappend directive and it has text
* ------------------------------------------------------------ */
@ -2211,6 +2296,7 @@ public:
/* ------------------------------------------------------------
* pythonappend()
*
* Get the %pythonappend code, stripping off {} if neccessary
* ------------------------------------------------------------ */
@ -2229,6 +2315,7 @@ public:
/* ------------------------------------------------------------
* have_addtofunc()
*
* Check if there is a %addtofunc directive and it has text
* ------------------------------------------------------------ */
@ -2239,6 +2326,7 @@ public:
/* ------------------------------------------------------------
* returnTypeAnnotation()
*
* Helper function for constructing the function annotation
* of the returning type, return a empty string for Python 2.x
* ------------------------------------------------------------ */
@ -2273,6 +2361,7 @@ public:
/* ------------------------------------------------------------
* emitFunctionShadowHelper()
*
* Refactoring some common code out of functionWrapper and
* dispatchFunction that writes the proxy code for non-member
* functions.
@ -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,6 +2393,7 @@ public:
/* ------------------------------------------------------------
* check_kwargs()
*
* check if using kwargs is allowed for this Node
* ------------------------------------------------------------ */
@ -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 {