Skip to content

Commit

Permalink
Merge branch 'mromberg-pkgdoc'
Browse files Browse the repository at this point in the history
* mromberg-pkgdoc:
  Python module loading documentation tweaks
  Add documentation about how foo.py finds/loads _foo for python.

[skip ci]
  • Loading branch information
wsfulton committed Jun 10, 2016
2 parents de56ef9 + d18b6e2 commit 82a9323
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Doc/Manual/Contents.html
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,12 @@ <h3><a href="Python.html#Python">36 SWIG and Python</a></h3>
<li><a href="Python.html#Python_absimport">Enforcing absolute import semantics</a>
<li><a href="Python.html#Python_importfrominit">Importing from __init__.py</a>
<li><a href="Python.html#Python_implicit_namespace_packages">Implicit Namespace Packages</a>
<li><a href="Python.html#Python_package_search">Searching for the wrapper module</a>
<ul>
<li><a href="Python.html#Python_package_search_both_package_modules">Both modules in the same package</a>
<li><a href="Python.html#Python_package_search_wrapper_split">Split modules</a>
<li><a href="Python.html#Python_package_search_both_global_modules">Both modules are global</a>
</ul>
</ul>
<li><a href="Python.html#Python_python3support">Python 3 Support</a>
<ul>
Expand Down
126 changes: 126 additions & 0 deletions Doc/Manual/Python.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ <H1><a name="Python">36 SWIG and Python</a></H1>
<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>
<ul>
<li><a href="#Python_package_search_both_package_modules">Both modules in the same package</a>
<li><a href="#Python_package_search_wrapper_split">Split modules</a>
<li><a href="#Python_package_search_both_global_modules">Both modules are global</a>
</ul>
</ul>
<li><a href="#Python_python3support">Python 3 Support</a>
<ul>
Expand Down Expand Up @@ -5521,6 +5527,23 @@ <H2><a name="Python_nn72">36.11 Python Packages</a></H2>
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). Implicit namespace 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>
that 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
Expand Down Expand Up @@ -5939,6 +5962,109 @@ <H3><a name="Python_implicit_namespace_packages">36.11.5 Implicit Namespace Pack
<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 an interface file, say foo.i, two Python modules are
created. There is a pure Python module module (foo.py) and C/C++ code which is
built and linked into a dynamically (or statically) loaded module _foo
(see the <a href="Python.html#Python_nn3">Preliminaries section</a> for details). So, the interface
file really defines two Python modules. How these two modules are loaded is
covered next.
</p>

<p>
The pure Python module needs to load the C/C++ module in order to link
to the wrapped C/C++ methods. To do this it must make some assumptions
about what package the C/C++ module may be located in. The approach the
pure Python module uses to find the C/C++ module is as follows:
</p>

<ol>
<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>
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>
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><a name="Python_package_search_both_package_modules">36.11.6.1 Both modules in the same package</a></H4>


<p>Both modules are in one package:</p>
<div class="diagram">
<pre>
/dir/package/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><a name="Python_package_search_wrapper_split">36.11.6.2 Split modules</a></H4>


<p>The pure python module is in a package and the C/C++ module is global:</p>
<div class="diagram">
<pre>
/dir/package/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><a name="Python_package_search_both_global_modules">36.11.6.3 Both modules are global</a></H4>


<p>Both modules are global:</p>
<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>


Expand Down

0 comments on commit 82a9323

Please sign in to comment.