Add documentation about how foo.py finds/loads _foo for python.
This commit is contained in:
parent
7a26e33b2a
commit
7b1b2e177f
1 changed files with 112 additions and 0 deletions
|
|
@ -117,6 +117,7 @@
|
|||
<li><a href="#Python_absimport">Enforcing absolute import semantics</a>
|
||||
<li><a href="#Python_importfrominit">Importing from __init__.py</a>
|
||||
<li><a href="#Python_implicit_namespace_packages">Implicit Namespace Packages</a>
|
||||
<li><a href="#Python_package_search">Searching for the wrapper module</a></li>
|
||||
</ul>
|
||||
<li><a href="#Python_python3support">Python 3 Support</a>
|
||||
<ul>
|
||||
|
|
@ -5521,6 +5522,23 @@ They should be created by other means. Both files (module <tt>*.py</tt> and
|
|||
directories in order to obtain a desirable package/module hierarchy.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Python3 adds another option for packages with
|
||||
<a href="https://www.python.org/dev/peps/pep-0420/">PEP 0420</a> (implicit
|
||||
namespace packages). These new type of python packages no longer use
|
||||
__init__.py files. Swig generated python modules support implicit
|
||||
namespace packages. See
|
||||
<a href="#Python_implicit_namespace_packages">36.11.5 Implicit Namespace
|
||||
Packages</a> for more information.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you place a swig generated module into a python package then there
|
||||
are details concerning the way swig
|
||||
<a href="#Python_package_search">searches for the wrapper module</a>
|
||||
you may want to familiarize yourself with.
|
||||
</p>
|
||||
|
||||
<p>The way Python defines its modules and packages impacts SWIG users. Some
|
||||
users may need to use special features such as the <tt>package</tt> option in the
|
||||
<tt>%module</tt> directive or import related command line options. These are
|
||||
|
|
@ -5939,6 +5957,100 @@ zipimporter requires python-3.5.1 or newer to work with subpackages.
|
|||
<b>Compatibility Note:</b> Support for implicit namespace packages was added in SWIG-3.0.9.
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_package_search">36.11.6 Searching for the wrapper module</a>
|
||||
</H3>
|
||||
<p>
|
||||
When swig creates wrappers from the interface file foo.i two python modules are
|
||||
created. There is a pure python module module (foo.py) and C code which is
|
||||
built and linked into a dynamically (or statically) loaded python module _foo
|
||||
(see <a href="#Python_nn3">section 36.2</a> for details). So, the interface
|
||||
file really defines two python modules. How these two modules are loaded is
|
||||
covered here.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The pure python module needs to load the companion module in order to link
|
||||
the python to the wrapped C methods. To do this it must make some assumptions
|
||||
about what package the companion module may be located in. The method the
|
||||
python shadow file uses to find the other half is as follows:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li><p>foo.py tries to load _foo from the same package foo.py is
|
||||
located in. The package name is determined from the __name__
|
||||
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
|
||||
as a global module.</p>
|
||||
</li>
|
||||
<li><p>If the above import of _foo results in an ImportError
|
||||
being thrown, then foo.py makes a final attempt to load _foo
|
||||
as a global module.</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Here foo.py is the pure python module and _foo is the dynamically or statically
|
||||
loaded C module.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As an example suppose foo.i is compiled into foo.py and _foo.so. Assuming
|
||||
/dir is on PYTHONPATH, then the two modules can be installed and used in the
|
||||
following ways:
|
||||
</p>
|
||||
|
||||
<h4>Both halves in the same package</h4>
|
||||
<div class="diagram">
|
||||
<pre>
|
||||
/dir/pakage/foo.py
|
||||
/dir/package/__init__.py
|
||||
/dir/package/_foo.so
|
||||
</pre>
|
||||
</div>
|
||||
<p>And imported with</p>
|
||||
<div class="diagram">
|
||||
<pre>
|
||||
from package import foo
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<h4>Wrapper module is global</h4>
|
||||
<div class="diagram">
|
||||
<pre>
|
||||
/dir/pakage/foo.py
|
||||
/dir/package/__init__.py
|
||||
/dir/_foo.so
|
||||
</pre>
|
||||
</div>
|
||||
<p>And imported with</p>
|
||||
<div class="diagram">
|
||||
<pre>
|
||||
from package import foo
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<h4>Both modules are global</h4>
|
||||
<div class="diagram">
|
||||
<pre>
|
||||
/dir/foo.py
|
||||
/dir/_foo.so
|
||||
</pre>
|
||||
</div>
|
||||
<p>And imported with</p>
|
||||
<div class="diagram">
|
||||
<pre>
|
||||
import foo
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
If _foo is statically linked into an embedded python interpreter, then it may or
|
||||
may not be in a python package. This depends in the exact way the module was
|
||||
loaded statically. The above search order will still be used for statically
|
||||
loaded modules. So, one may place the module either globally or in a package
|
||||
as desired.
|
||||
</p>
|
||||
|
||||
<H2><a name="Python_python3support">36.12 Python 3 Support</a></H2>
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue