Simpler Python -builtin import

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.
This commit is contained in:
William S Fulton 2018-11-28 23:36:13 +00:00
commit 6b5da094b2
2 changed files with 53 additions and 27 deletions

View file

@ -7,6 +7,31 @@ 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-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

View file

@ -693,6 +693,7 @@ public:
mod_docstring = NULL; mod_docstring = NULL;
} }
if (!builtin) {
/* Import the C-extension module. This should be a relative import, /* Import the C-extension module. This should be a relative import,
* since the shadow module may also have been imported by a relative * since the shadow module may also have been imported by a relative
* import, and there is thus no guarantee that the C-extension is on * import, and there is thus no guarantee that the C-extension is on
@ -717,13 +718,13 @@ public:
Printf(default_import_code, tab8 "return importlib.import_module('%s')\n", module); Printf(default_import_code, tab8 "return importlib.import_module('%s')\n", module);
Printf(default_import_code, "%s = swig_import_helper()\n", module); Printf(default_import_code, "%s = swig_import_helper()\n", module);
Printv(default_import_code, "del swig_import_helper\n", NULL); Printv(default_import_code, "del swig_import_helper\n", NULL);
} else {
if (builtin) {
/* /*
* 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 *
* *