Merge github.com:swig/swig
# Conflicts: # CHANGES.current
This commit is contained in:
commit
402d55da52
4 changed files with 87 additions and 59 deletions
|
|
@ -7,11 +7,36 @@ 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)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
2018-11-24: adr26
|
2018-11-29: adr26
|
||||||
[Python] #1360 Leak of SWIG var link object
|
[Python] #1360 Leak of SWIG var link object
|
||||||
|
|
||||||
Fix reference counting on _SWIG_globals to allow var link to be freed on module unload.
|
Fix reference counting on _SWIG_globals to allow var link to be freed on module unload.
|
||||||
|
|
||||||
|
2018-11-28: wsfulton
|
||||||
|
[Python] When using -builtin, the two step C-extension module import is now
|
||||||
|
one step and the wrapped API is only available once and not in an underlying
|
||||||
|
module attribute like it is without -builtin. To understand this, consider a
|
||||||
|
module named 'example' (using: %module example). The C-extension is compiled into
|
||||||
|
a Python module called '_example' and a pure Python module provides the actual
|
||||||
|
API from the module called 'example'. It was previously possible to additionally
|
||||||
|
access the API from the module attribute 'example._example'. The latter was an
|
||||||
|
implementation detail and is no longer available. It shouldn't have been used, but
|
||||||
|
if necessary it can be resurrected using the moduleimport attribute described in the
|
||||||
|
Python chapter of the documentation. If both modules are provided in a Python
|
||||||
|
package, try:
|
||||||
|
|
||||||
|
%module(moduleimport="from . import _example\nfrom ._example import *") example
|
||||||
|
or more generically:
|
||||||
|
%module(moduleimport="from . import $module\nfrom .$module import *") example
|
||||||
|
|
||||||
|
and if both are provided as global modules, try:
|
||||||
|
|
||||||
|
%module(moduleimport="import _example\nfrom _example import *") example
|
||||||
|
or more generically:
|
||||||
|
%module(moduleimport="import $module\nfrom $module import *") example
|
||||||
|
|
||||||
|
The module import code shown will appear in the example.py file.
|
||||||
|
|
||||||
2018-11-24: vadz
|
2018-11-24: vadz
|
||||||
#1358 Fix handling of abstract base classes nested inside templates
|
#1358 Fix handling of abstract base classes nested inside templates
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6137,7 +6137,8 @@ pure Python module uses to find the C/C++ module is as follows:
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li><p>The pure Python module, foo.py, tries to load the C/C++ module, _foo, from the same package foo.py is
|
<li><p>The pure Python module, foo.py, tries to load the C/C++ module, _foo, from the same package foo.py is
|
||||||
located in. The package name is determined from the <tt>__name__</tt>
|
located in. The package name is determined from the <tt>__package__</tt>
|
||||||
|
attribute if available, see <a href="https://www.python.org/dev/peps/pep-0366/">PEP 366</a>, otherwise it is derived from the <tt>__name__</tt>
|
||||||
attribute given to foo.py by the Python loader that imported
|
attribute given to foo.py by the Python loader that imported
|
||||||
foo.py. If foo.py is not in a package then _foo is loaded
|
foo.py. If foo.py is not in a package then _foo is loaded
|
||||||
as a global module.</p>
|
as a global module.</p>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
%include "example.h"
|
%include "example.h"
|
||||||
|
|
||||||
/* An output method that turns a complex into a short string */
|
/* An output method that turns a complex into a short string */
|
||||||
|
%feature("python:slot", "tp_str", functype="reprfunc") Complex::__str__; // For -builtin option to use __str__ in the tp_str slot
|
||||||
%extend Complex {
|
%extend Complex {
|
||||||
char *__str__() {
|
char *__str__() {
|
||||||
static char temp[512];
|
static char temp[512];
|
||||||
|
|
|
||||||
|
|
@ -693,37 +693,39 @@ public:
|
||||||
mod_docstring = NULL;
|
mod_docstring = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Import the C-extension module. This should be a relative import,
|
if (!builtin) {
|
||||||
* since the shadow module may also have been imported by a relative
|
/* Import the C-extension module. This should be a relative import,
|
||||||
* import, and there is thus no guarantee that the C-extension is on
|
* since the shadow module may also have been imported by a relative
|
||||||
* sys.path. Relative imports must be explicitly specified from 2.6.0
|
* import, and there is thus no guarantee that the C-extension is on
|
||||||
* onwards (implicit relative imports raised a DeprecationWarning in 2.6,
|
* sys.path. Relative imports must be explicitly specified from 2.6.0
|
||||||
* and fail in 2.7 onwards).
|
* onwards (implicit relative imports raised a DeprecationWarning in 2.6,
|
||||||
*
|
* and fail in 2.7 onwards).
|
||||||
* First determine the shadow wrappers package based on the __name__ it
|
*
|
||||||
* was given by the importer that loaded it. Then construct a name for
|
* First check for __package__ which is available from 2.6 onwards, see PEP366.
|
||||||
* the module based on the package name and the module name (we know the
|
* Next determine the shadow wrappers package based on the __name__ it
|
||||||
* module name). Use importlib to try and load it. If an attempt to
|
* was given by the importer that loaded it. Then construct a name for
|
||||||
* load the module with importlib fails with an ImportError then fallback
|
* the module based on the package name and the module name (we know the
|
||||||
* and try and load just the module name from the global namespace.
|
* module name). Use importlib to try and load it. If an attempt to
|
||||||
*/
|
* load the module with importlib fails with an ImportError then fallback
|
||||||
Printv(default_import_code, "def swig_import_helper():\n", NULL);
|
* and try and load just the module name from the global namespace.
|
||||||
Printv(default_import_code, tab4, "import importlib\n", NULL);
|
*/
|
||||||
Printv(default_import_code, tab4, "pkg = __package__ if __package__ else __name__.rpartition('.')[0]\n", NULL);
|
Printv(default_import_code, "def swig_import_helper():\n", NULL);
|
||||||
Printf(default_import_code, tab4 "mname = '.'.join((pkg, '%s')).lstrip('.')\n", module);
|
Printv(default_import_code, tab4, "import importlib\n", NULL);
|
||||||
Printv(default_import_code, tab4, "try:\n", NULL);
|
Printv(default_import_code, tab4, "pkg = __package__ if __package__ else __name__.rpartition('.')[0]\n", NULL);
|
||||||
Printv(default_import_code, tab8, "return importlib.import_module(mname)\n", NULL);
|
Printf(default_import_code, tab4 "mname = '.'.join((pkg, '%s')).lstrip('.')\n", module);
|
||||||
Printv(default_import_code, tab4, "except ImportError:\n", NULL);
|
Printv(default_import_code, tab4, "try:\n", NULL);
|
||||||
Printf(default_import_code, tab8 "return importlib.import_module('%s')\n", module);
|
Printv(default_import_code, tab8, "return importlib.import_module(mname)\n", NULL);
|
||||||
Printf(default_import_code, "%s = swig_import_helper()\n", module);
|
Printv(default_import_code, tab4, "except ImportError:\n", NULL);
|
||||||
Printv(default_import_code, "del swig_import_helper\n", NULL);
|
Printf(default_import_code, tab8 "return importlib.import_module('%s')\n", module);
|
||||||
|
Printf(default_import_code, "%s = swig_import_helper()\n", module);
|
||||||
if (builtin) {
|
Printv(default_import_code, "del swig_import_helper\n", NULL);
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* Pull in all the attributes from the C module.
|
* Pull in all the attributes from the C module.
|
||||||
*
|
*
|
||||||
* An alternative approach to doing this if/else chain was
|
* An alternative approach to doing this if/else chain was
|
||||||
* proposed by Michael Thon. Someone braver than I may try it out.
|
* proposed by Michael Thon at https://github.com/swig/swig/issues/691.
|
||||||
|
* Someone braver than I may try it out.
|
||||||
* I fear some current swig user may depend on some side effect
|
* I fear some current swig user may depend on some side effect
|
||||||
* of from _foo import *
|
* of from _foo import *
|
||||||
*
|
*
|
||||||
|
|
@ -2599,6 +2601,7 @@ public:
|
||||||
builtin_self = false;
|
builtin_self = false;
|
||||||
else
|
else
|
||||||
builtin_ctor = true;
|
builtin_ctor = true;
|
||||||
|
Delete(mrename);
|
||||||
}
|
}
|
||||||
bool director_class = (getCurrentClass() && Swig_directorclass(getCurrentClass()));
|
bool director_class = (getCurrentClass() && Swig_directorclass(getCurrentClass()));
|
||||||
bool add_self = builtin_self && (!builtin_ctor || director_class);
|
bool add_self = builtin_self && (!builtin_ctor || director_class);
|
||||||
|
|
@ -4737,11 +4740,12 @@ public:
|
||||||
Delete(cname);
|
Delete(cname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String *subfunc = Swig_name_construct(NSPACE_TODO, symname);
|
||||||
if (!have_constructor && handled_as_init) {
|
if (!have_constructor && handled_as_init) {
|
||||||
if (!builtin) {
|
if (!builtin) {
|
||||||
if (Getattr(n, "feature:shadow")) {
|
if (Getattr(n, "feature:shadow")) {
|
||||||
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")");
|
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));
|
String *pyaction = NewStringf("%s.%s", module, subfunc);
|
||||||
Replaceall(pycode, "$action", pyaction);
|
Replaceall(pycode, "$action", pyaction);
|
||||||
Delete(pyaction);
|
Delete(pyaction);
|
||||||
Printv(f_shadow, pycode, "\n", NIL);
|
Printv(f_shadow, pycode, "\n", NIL);
|
||||||
|
|
@ -4771,7 +4775,7 @@ public:
|
||||||
if (have_pythonprepend(n))
|
if (have_pythonprepend(n))
|
||||||
Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\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);
|
Printv(f_shadow, pass_self, NIL);
|
||||||
Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self, ", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), ")\n", NIL);
|
Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self, ", funcCall(subfunc, callParms), ")\n", NIL);
|
||||||
if (have_pythonappend(n))
|
if (have_pythonappend(n))
|
||||||
Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\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);
|
Delete(pass_self);
|
||||||
|
|
@ -4781,39 +4785,36 @@ public:
|
||||||
} else {
|
} else {
|
||||||
/* Hmmm. We seem to be creating a different constructor. We're just going to create a
|
/* Hmmm. We seem to be creating a different constructor. We're just going to create a
|
||||||
function for it. */
|
function for it. */
|
||||||
if (Getattr(n, "feature:shadow")) {
|
if (!builtin) {
|
||||||
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n), "%feature(\"shadow\")");
|
if (Getattr(n, "feature:shadow")) {
|
||||||
String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(NSPACE_TODO, symname));
|
String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n), "%feature(\"shadow\")");
|
||||||
Replaceall(pycode, "$action", pyaction);
|
String *pyaction = NewStringf("%s.%s", module, subfunc);
|
||||||
Delete(pyaction);
|
Replaceall(pycode, "$action", pyaction);
|
||||||
Printv(f_shadow_stubs, pycode, "\n", NIL);
|
Delete(pyaction);
|
||||||
Delete(pycode);
|
Printv(f_shadow_stubs, pycode, "\n", NIL);
|
||||||
} else {
|
Delete(pycode);
|
||||||
String *parms = make_pyParmList(n, false, false, allow_kwargs);
|
} else {
|
||||||
String *callParms = make_pyParmList(n, false, true, allow_kwargs);
|
String *parms = make_pyParmList(n, false, false, allow_kwargs);
|
||||||
|
String *callParms = make_pyParmList(n, false, true, allow_kwargs);
|
||||||
|
|
||||||
Printv(f_shadow_stubs, "\ndef ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
|
Printv(f_shadow_stubs, "\ndef ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL);
|
||||||
if (have_docstring(n))
|
if (have_docstring(n))
|
||||||
Printv(f_shadow_stubs, tab4, docstring(n, AUTODOC_CTOR, tab4), "\n", NIL);
|
Printv(f_shadow_stubs, tab4, docstring(n, AUTODOC_CTOR, tab4), "\n", NIL);
|
||||||
if (have_pythonprepend(n))
|
if (have_pythonprepend(n))
|
||||||
Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
|
Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
|
||||||
String *subfunc = NULL;
|
Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
|
||||||
/*
|
|
||||||
if (builtin)
|
|
||||||
subfunc = Copy(Getattr(getCurrentClass(), "sym:name"));
|
|
||||||
else
|
|
||||||
*/
|
|
||||||
subfunc = Swig_name_construct(NSPACE_TODO, symname);
|
|
||||||
Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
|
|
||||||
#ifdef USE_THISOWN
|
#ifdef USE_THISOWN
|
||||||
Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
|
Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
|
||||||
#endif
|
#endif
|
||||||
if (have_pythonappend(n))
|
if (have_pythonappend(n))
|
||||||
Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\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);
|
Printv(f_shadow_stubs, tab4, "return val\n", NIL);
|
||||||
Delete(subfunc);
|
}
|
||||||
|
} else {
|
||||||
|
Printf(f_shadow_stubs, "%s = %s\n", symname, subfunc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Delete(subfunc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue