Python imports documentation edits

This commit is contained in:
William S Fulton 2013-12-24 14:39:25 +00:00
commit 91120c84f2

View file

@ -108,7 +108,7 @@
<ul> <ul>
<li><a href="#Python_modulepackage">%module(package="...") syntax</a> <li><a href="#Python_modulepackage">%module(package="...") syntax</a>
<li><a href="#Python_absrelimports">Absolute and relative imports</a></li> <li><a href="#Python_absrelimports">Absolute and relative imports</a></li>
<li><a href="Python_absimport">Enforcing absolute import semantics</a></li> <li><a href="#Python_absimport">Enforcing absolute import semantics</a></li>
<li><a href="#Python_importfrominit">Importing from __init__.py</a></li> <li><a href="#Python_importfrominit">Importing from __init__.py</a></li>
</ul> </ul>
<li><a href="#Python_python3support">Python 3 Support</a> <li><a href="#Python_python3support">Python 3 Support</a>
@ -5284,11 +5284,11 @@ code and may be grouped together to form a package. Packages may be nested,
that is they may contain subpackages. This leads to tree-like hierarchy, with that is they may contain subpackages. This leads to tree-like hierarchy, with
packages as intermediate nodes and modules as leaf nodes.</p> packages as intermediate nodes and modules as leaf nodes.</p>
<p>The hierarchy of python packages/modules follows the hierarchy of <p>The hierarchy of Python packages/modules follows the hierarchy of
<tt>*.py</tt> files found in source tree (or, more generally, in python path). <tt>*.py</tt> files found in a source tree (or, more generally, in the Python path).
Normally, the developer creates new module by placing a <tt>*.py</tt> file Normally, the developer creates new module by placing a <tt>*.py</tt> file
somewhere under python path; the module is then named after that <tt>*.py</tt> somewhere under Python path; the module is then named after that <tt>*.py</tt>
file. A package is created by placing <tt>__init__.py</tt> file within a file. A package is created by placing an <tt>__init__.py</tt> file within a
directory; the package is then named after that directory. For example, the directory; the package is then named after that directory. For example, the
following source tree:</p> following source tree:</p>
@ -5303,7 +5303,7 @@ pkg1/pkg2/mod3.py
</div> </div>
<p> <p>
defines the following python packages and modules: defines the following Python packages and modules:
</p> </p>
<div class="diagram"> <div class="diagram">
@ -5317,28 +5317,28 @@ pkg1.pkg2.mod3 # module
</div> </div>
<p> <p>
The purpose of <tt>__init__.py</tt> file is two-fold. First, existence of The purpose of an <tt>__init__.py</tt> file is two-fold. First, the existence of
<tt>__init__.py</tt> in a directory informs python interpreter that this <tt>__init__.py</tt> in a directory informs the Python interpreter that this
directory contains python package. Second, the code of <tt>__init__.py</tt> is directory contains a Python package. Second, the code in <tt>__init__.py</tt> is
loaded/executed automatically when the package is initialized (when it or its loaded/executed automatically when the package is initialized (when it or its
submodule/subpackage gets <tt>import</tt>'ed). By default, swig generates submodule/subpackage gets <tt>import</tt>'ed). By default, SWIG generates
proxy python code &ndash; one <tt>*.py</tt> file for each <tt>*.i</tt> proxy Python code &ndash; one <tt>*.py</tt> file for each <tt>*.i</tt>
interface. The <tt>__init__.py</tt> files, however, are not generated by swig. interface. The <tt>__init__.py</tt> files, however, are not generated by SWIG.
They should be created by other means. Both files (module <tt>*.py</tt> and They should be created by other means. Both files (module <tt>*.py</tt> and
<tt>__init__.py</tt>) should be installed in appropriate destination <tt>__init__.py</tt>) should be installed in appropriate destination
directories in order to obtain desirable package/module hierarchy. directories in order to obtain a desirable package/module hierarchy.
</p> </p>
<p>The way python defines its modules and packages impacts swig users. Some <p>The way Python defines its modules and packages impacts SWIG users. Some
users may need to use special features such as <tt>package</tt> option of 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 <tt>%module</tt> directive or import related command line options. These are
explained in the following sections.</p> explained in the following sections.</p>
<H3><a name="Python_modulepackage"></a>34.11.1 %module(package="...") syntax</H3> <H3><a name="Python_modulepackage"></a>34.11.1 Setting the Python package</H3>
<p> <p>
Using the <tt>package</tt> option of the <tt>%module</tt> directive allows you Using the <tt>package</tt> option in the <tt>%module</tt> directive allows you
to specify a Python package that the module will be living in when installed. to specify a Python package that the module will be in when installed.
</p> </p>
<div class="code"> <div class="code">
@ -5351,20 +5351,20 @@ to specify a Python package that the module will be living in when installed.
This is useful when the <tt>.i</tt> file is <tt>%import</tt>ed by This is useful when the <tt>.i</tt> file is <tt>%import</tt>ed by
another <tt>.i</tt> file. By default SWIG will assume that the another <tt>.i</tt> file. By default SWIG will assume that the
importer is able to find the importee with just the module name, but importer is able to find the importee with just the module name, but
if they live in separate Python packages then that won't work. if they live in separate Python packages then this won't work.
However if the importee specifies what its package is with the However if the importee specifies what its package is with the
<tt>%module</tt> option then the Python code generated for the <tt>%module</tt> option then the Python code generated for the
importer will use that package name when importing the other module importer will use that package name when importing the other module
and also in base class declarations, etc.. and in base class declarations, etc..
</p> </p>
<p>Swig assumes, that the <tt>package</tt> option provided to <tt>%module</tt> <p>SWIG assumes that the <tt>package</tt> option provided to <tt>%module</tt>
together with the <tt>module</tt> name (that is, <tt>wx.xrc</tt> in the above together with the <tt>module</tt> name (that is, <tt>wx.xrc</tt> in the above
example) forms a fully qualified (absolute) name of a module (in Python terms). example) forms a fully qualified (absolute) name of a module (in Python terms).
This is important especially for Python 3, where absolute imports are used by This is important especially for Python 3, where absolute imports are used by
default. It's up to you to place the generated module files (<tt>.py</tt>, default. It's up to you to place the generated module files (<tt>.py</tt>,
<tt>.so</tt>) in proper subdirectories. For example, if you have <tt>.so</tt>) in appropriate subdirectories. For example, if you have an
interface <tt>foo.i</tt> with: interface file <tt>foo.i</tt> with:
</p> </p>
<div class="code"> <div class="code">
@ -5374,7 +5374,7 @@ interface <tt>foo.i</tt> with:
</div> </div>
<p> <p>
then the resultant directory layout should be then the resulting directory layout should be
</p> </p>
<div class="diagram"> <div class="diagram">
@ -5382,8 +5382,8 @@ then the resultant directory layout should be
pkg1/ pkg1/
pkg1/__init__.py pkg1/__init__.py
pkg1/pkg2/__init__.py pkg1/pkg2/__init__.py
pkg1/pkg2/foo.py # (generated by swig) pkg1/pkg2/foo.py # (generated by SWIG)
pkg1/pkg2/_foo.so # (shared library from C/C++ code generated by SWIG) pkg1/pkg2/_foo.so # (shared library built from C/C++ code generated by SWIG)
</pre> </pre>
</div> </div>
@ -5409,9 +5409,9 @@ class M3: pass
</div> </div>
<p> <p>
We edit <tt>pkg1/mod2.py</tt> and want to import module of We edit <tt>pkg1/mod2.py</tt> and want to import module
<tt>pkg1/pkg2/pkg3.py</tt> in order to derive from class <tt>M3</tt>. We can <tt>pkg1/pkg2/pkg3.py</tt> in order to derive from class <tt>M3</tt>. We can
write appropriate python code in several ways, for example: write appropriate Python code in several ways, for example:
</p> </p>
<ol> <ol>
@ -5426,7 +5426,7 @@ class M2(pkg1.pkg2.mod3.M3): pass
</li> </li>
<li><p>Using "<tt>import &lt;&gt;</tt>" syntax with package name relative to <li><p>Using "<tt>import &lt;&gt;</tt>" syntax with package name relative to
<tt>pkg1</tt> (only in python 2.7 and earlier):</p> <tt>pkg1</tt> (only in Python 2.7 and earlier):</p>
<div class="targetlang"> <div class="targetlang">
<pre> <pre>
# pkg1/mod2.py # pkg1/mod2.py
@ -5437,7 +5437,7 @@ class M2(pkg2.mod3.M3): pass
</li> </li>
<li><p>Using "<tt>from &lt;&gt; import &lt;&gt;</tt>" syntax (relative import <li><p>Using "<tt>from &lt;&gt; import &lt;&gt;</tt>" syntax (relative import
syntax, only in python 2.5 and later):</p> syntax, only in Python 2.5 and later):</p>
<div class="targetlang"> <div class="targetlang">
<pre> <pre>
# pkg1/mod2.py # pkg1/mod2.py
@ -5449,7 +5449,7 @@ class M2(mod3.M3): pass
<li><p>Other variants, for example the following construction in order to <li><p>Other variants, for example the following construction in order to
have the <tt>pkg2.mod3.M3</tt> symbol available in <tt>mod2</tt> as have the <tt>pkg2.mod3.M3</tt> symbol available in <tt>mod2</tt> as
in point 2 above (but now under python 3):</p> in point 2 above (but now under Python 3):</p>
<div class="targetlang"> <div class="targetlang">
<pre> <pre>
# pkg1/mod2.py # pkg1/mod2.py
@ -5483,13 +5483,13 @@ class M2(pkg2.mod3.M3): pass
</pre> </pre>
</div> </div>
<p>By default, swig would generate <tt>mod2.py</tt> proxy file with <p>By default, SWIG would generate <tt>mod2.py</tt> proxy file with
<tt>import</tt> directive as in point 1. This may be changed with <tt>import</tt> directive as in point 1. This can be changed with the
<tt>-relativeimport</tt> CLI option. The <tt>-relativeimport</tt> instructs <tt>-relativeimport</tt> command line option. The <tt>-relativeimport</tt> instructs
swig to organize imports as in point 2 (for python 2.x) or as in point 4 (for SWIG to organize imports as in point 2 (for Python 2.x) or as in point 4 (for
python 3, that is when -py3 CLI option is enabled). In short, if you have Python 3, that is when the -py3 command line option is enabled). In short, if you have
<tt>mod2.i</tt> and <tt>mod3.i</tt> as above, then without <tt>mod2.i</tt> and <tt>mod3.i</tt> as above, then without
<tt>-relativeimport</tt> swig will write</p> <tt>-relativeimport</tt> SWIG will write</p>
<div class="targetlang"> <div class="targetlang">
<pre> <pre>
@ -5515,20 +5515,20 @@ import pkg1.pkg2.mod3
</pre> </pre>
</div> </div>
<p>when <tt>-py3</tt> option is used.</p> <p>when <tt>-py3</tt> is used.</p>
<p>You should avoid using relative imports and use absolute ones whenever <p>You should avoid using relative imports and use absolute ones whenever
possible. There are some cases, however, when relative imports may be possible. There are some cases, however, when relative imports may be
necessary. The first example is, when some (legacy) python code refers entities necessary. The first example is, when some (legacy) Python code refers entities
imported by proxy files generated by swig, and it assumes that the proxy file imported by proxy files generated by SWIG, and it assumes that the proxy file
uses relative imports. Second case is, when one puts import directives in uses relative imports. Second case is, when one puts import directives in
<tt>__init__.py</tt> to import symbols from submodules or subpackages and the <tt>__init__.py</tt> to import symbols from submodules or subpackages and the
submodule depends on other submodules (discussed later).</p> submodule depends on other submodules (discussed later).</p>
<H3><a name="Python_absimport"></a>34.11.3 Enforcing absolute import semantics</H3> <H3><a name="Python_absimport"></a>34.11.3 Enforcing absolute import semantics</H3>
<p>As you may know, there is incompatibility in import semantics (for the <p>As you may know, there is an incompatibility in import semantics (for the
<tt>import &lt;&gt;</tt> syntax) between python 2 and 3. In python 2.4 and <tt>import &lt;&gt;</tt> syntax) between Python 2 and 3. In Python 2.4 and
earlier it is not clear whether</p> earlier it is not clear whether</p>
<div class="targetlang"> <div class="targetlang">
@ -5537,10 +5537,10 @@ import foo
</pre> </pre>
</div> </div>
<p>refers to a top-level module or to another module inside the current <p>refers to a top-level module or to another module inside the current
package. In python 3 it always refers to a top-level module package. In Python 3 it always refers to a top-level module
(see <a href="http://www.python.org/dev/peps/pep-0328/">PEP 328</a>). (see <a href="http://www.python.org/dev/peps/pep-0328/">PEP 328</a>).
To instruct python 2.5 through 2.7 to use new semantics (that is <tt>import To instruct Python 2.5 through 2.7 to use new semantics (that is <tt>import
foo</tt> is interpreted as absolute import), one have to put the following foo</tt> is interpreted as absolute import), one has to put the following
line line
</p> </p>
@ -5550,26 +5550,26 @@ from __future__ import absolute_import
</pre> </pre>
</div> </div>
<p>at the very beginning of his proxy <tt>*.py</tt> file. In swig, it may be <p>at the very beginning of his proxy <tt>*.py</tt> file. In SWIG, it may be
accomplished with <tt>%pythonbegin</tt> directive.</p> accomplished with <tt>%pythonbegin</tt> directive.</p>
<H3><a name="Python_importfrominit"></a>34.11.4 Importing from __init__.py</H3> <H3><a name="Python_importfrominit"></a>34.11.4 Importing from __init__.py</H3>
<p>Imports in <tt>__init__.py</tt> are handy when you want to populate <p>Imports in <tt>__init__.py</tt> are handy when you want to populate a
package's namespace with names imported from other modules. In swig-based package's namespace with names imported from other modules. In SWIG based
projects this approach may also be used to split large piece of code into projects this approach may also be used to split large pieces of code into
smaller modules, compile them in parallel and then re-assemble all stuff at smaller modules, compile them in parallel and then re-assemble everything at another
python level by importing submodules' contents in <tt>__init__.py</tt>, for level by importing submodules' contents in <tt>__init__.py</tt>, for
example.</p> example.</p>
<p>Unfortunately import directives in <tt>__init__.py</tt> may cause troubles, <p>Unfortunately import directives in <tt>__init__.py</tt> may cause problems,
especially if they refer to package's submodules. This is caused by the way especially if they refer to a package's submodules. This is caused by the way
python initializes packages. If you spot problems with imports from Python initializes packages. If you spot problems with imports from
<tt>__init__.py</tt> try using <tt>-relativeimport</tt> option. Below we <tt>__init__.py</tt> try using <tt>-relativeimport</tt> option. Below we
explain in detail one issue, for which the <tt>-relativeimport</tt> workaround explain in detail one issue, for which the <tt>-relativeimport</tt> workaround
may be helpful.</p> may be helpful.</p>
<p>Consider the following example (python 3):</p> <p>Consider the following example (Python 3):</p>
<div class="diagram"> <div class="diagram">
<pre> <pre>
@ -5580,10 +5580,10 @@ pkg1/pkg2/bar.py # (imports foo.py)
</pre> </pre>
</div> </div>
<p>Let's the files' contents be:</p> <p>If the file contents are:</p>
<ul> <ul>
<li> <p>for <tt>pkg1/pkg2/__init__.py:</tt></p> <li> <p><tt>pkg1/pkg2/__init__.py:</tt></p>
<div class="targetlang"> <div class="targetlang">
<pre> <pre>
# pkg1/pkg2/__init__.py # pkg1/pkg2/__init__.py
@ -5592,7 +5592,7 @@ from .bar import Bar
</div> </div>
</li> </li>
<li> <p>for <tt>pkg1/pkg2/foo.py:</tt></p> <li> <p><tt>pkg1/pkg2/foo.py:</tt></p>
<div class="targetlang"> <div class="targetlang">
<pre> <pre>
# pkg1/pkg2/foo.py # pkg1/pkg2/foo.py
@ -5601,7 +5601,7 @@ class Foo: pass
</div> </div>
</li> </li>
<li> <p>for <tt>pkg1/pkg2/foo.py:</tt></p> <li> <p><tt>pkg1/pkg2/bar.py:</tt></p>
<div class="targetlang"> <div class="targetlang">
<pre> <pre>
# pkg1/pkg2/bar.py # pkg1/pkg2/bar.py
@ -5612,7 +5612,7 @@ class Bar(pkg1.pkg2.foo.Foo): pass
</li> </li>
</ul> </ul>
<p>Now one would simply do <tt>import pkg1.pkg2</tt>, but this usually fails:</p> <p>Now if one simply used <tt>import pkg1.pkg2</tt>, it will usually fail:</p>
<div class="diagram"> <div class="diagram">
<pre> <pre>
@ -5628,16 +5628,16 @@ AttributeError: 'module' object has no attribute 'pkg2'
</div> </div>
<p>Surprisingly, if we execute the <tt>import pkg1.pkg2</tt> directive for the <p>Surprisingly, if we execute the <tt>import pkg1.pkg2</tt> directive for the
second time, it succeeds. The reason seems to be following: when python spots second time, it succeeds. The reason seems to be following: when Python spots
the <tt>from .bar import Bar</tt> directive in <tt>pkg1/pkg2/__init__.py</tt> the <tt>from .bar import Bar</tt> directive in <tt>pkg1/pkg2/__init__.py</tt>
it starts loading <tt>pkg1/pkg2/bar.py</tt>. This module imports it starts loading <tt>pkg1/pkg2/bar.py</tt>. This module imports
<tt>pkg1.pkg2.foo</tt> in turn and tries to use <tt>pkg1.pkg2.foo.Foo</tt>, but <tt>pkg1.pkg2.foo</tt> in turn and tries to use <tt>pkg1.pkg2.foo.Foo</tt>, but
the package <tt>pkg1</tt> is not fully initialized yet (the initialization the package <tt>pkg1</tt> is not fully initialized yet (the initialization
procedure is actually in progress) and it seems like the effect of already seen procedure is actually in progress) and it seems like the effect of the already seen
directive <tt>import pkg1.pkg2.pkg3.foo</tt> is "delayed" or ignored. Exactly <tt>import pkg1.pkg2.pkg3.foo</tt> is "delayed" or ignored. Exactly the
same may happen to a proxy module generated by swig.</p> same may happen to a proxy module generated by SWIG.</p>
<p>It's observed, that a possible workaround for this case is to use relative <p>One workaround for this case is to use a relative
import in <tt>pkg1/pkg2/bar.py</tt>. If we change <tt>bar.py</tt> to be:</p> import in <tt>pkg1/pkg2/bar.py</tt>. If we change <tt>bar.py</tt> to be:</p>
<div class="targetlang"> <div class="targetlang">
@ -5657,9 +5657,9 @@ class Bar(pkg3.foo.Foo): pass
</pre> </pre>
</div> </div>
<p>then the example works again. With swig, you need to enable the <p>then the example works again. With SWIG, you need to enable the
<tt>-relativeimport</tt> option in order to have the above workaround in <tt>-relativeimport</tt> option in order to have the above workaround in
effect (note, that python 2 case also needs <tt>-relativeimport</tt> effect (note, that the Python 2 case also needs the <tt>-relativeimport</tt>
workaround).</p> workaround).</p>