From 7b1b2e177f7f7cfe9498133cf920f0fc7177e3d7 Mon Sep 17 00:00:00 2001
From: Mike Romberg
@@ -5521,6 +5522,23 @@ They should be created by other means. Both files (module *.py and
directories in order to obtain a desirable package/module hierarchy.
+Python3 adds another option for packages with +PEP 0420 (implicit +namespace packages). These new type of python packages no longer use +__init__.py files. Swig generated python modules support implicit +namespace packages. See +36.11.5 Implicit Namespace +Packages for more information. +
+ ++If you place a swig generated module into a python package then there +are details concerning the way swig +searches for the wrapper module +you may want to familiarize yourself with. +
+The way Python defines its modules and packages impacts SWIG users. Some users may need to use special features such as the package option in the %module 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. Compatibility Note: Support for implicit namespace packages was added in SWIG-3.0.9.
++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 section 36.2 for details). So, the interface +file really defines two python modules. How these two modules are loaded is +covered here. +
+ ++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: +
+ +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.
+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.
++Here foo.py is the pure python module and _foo is the dynamically or statically +loaded C module. +
+ ++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: +
+ ++/dir/pakage/foo.py +/dir/package/__init__.py +/dir/package/_foo.so ++
And imported with
++from package import foo ++
+/dir/pakage/foo.py +/dir/package/__init__.py +/dir/_foo.so ++
And imported with
++from package import foo ++
+/dir/foo.py +/dir/_foo.so ++
And imported with
++import foo ++
+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. +
+Python3 adds another option for packages with PEP 0420 (implicit -namespace packages). These new type of python packages no longer use -__init__.py files. Swig generated python modules support implicit +namespace packages). Implicit namespace packages no longer use +__init__.py files. SWIG generated Python modules support implicit namespace packages. See 36.11.5 Implicit Namespace Packages for more information.
-If you place a swig generated module into a python package then there -are details concerning the way swig +If you place a SWIG generated module into a Python package then there +are details concerning the way SWIG searches for the wrapper module -you may want to familiarize yourself with. +that you may want to familiarize yourself with.
The way Python defines its modules and packages impacts SWIG users. Some @@ -5957,28 +5962,30 @@ zipimporter requires python-3.5.1 or newer to work with subpackages. Compatibility Note: Support for implicit namespace packages was added in SWIG-3.0.9.
--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 section 36.2 for details). So, the interface -file really defines two python modules. How these two modules are loaded is -covered here. +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 Preliminaries section for details). So, the interface +file really defines two Python modules. How these two modules are loaded is +covered next.
-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: +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:
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 +
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 __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.
-Here foo.py is the pure python module and _foo is the dynamically or statically -loaded C module. -
-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:
-Both modules are in one package:
-/dir/pakage/foo.py +/dir/package/foo.py /dir/package/__init__.py /dir/package/_foo.so@@ -6014,10 +6020,14 @@ from package import foo
The pure python module is in a package and the C/C++ module is global:
-/dir/pakage/foo.py +/dir/package/foo.py /dir/package/__init__.py /dir/_foo.so@@ -6029,7 +6039,11 @@ from package import foo
Both modules are global:
/dir/foo.py @@ -6044,8 +6058,8 @@ import foo
-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
+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.
From 2bb732008a87b31cd043b4476389a8260fb69e55 Mon Sep 17 00:00:00 2001
From: Mike Romberg
It is strongly recommended to use dynamically linked modules for the C +portion of your pair of python modules. See the section on +Static Linking. If for some reason you still need +to link the C module of the pair of python modules generated by swig into +your interpreter, then this section provides some details on how this impacts +the pure python modules ability to locate the other part of the pair. +
+ +When python is extended with C code the python interpreter needs to be +informed about details of the new C functions that have been linked into +the executable. The code to do this is created by swig and is automatically +called in the correct way when the module is dynamically loaded. However +when the code is not dynamically loaded (because it is statically linked) +Then the initialization method for the module created by swig is not +called automatically. And the python interpreter has no idea that the +new swig C module exists. +
+ +Before python3, one could simply call the init method created by swig +which would have normally been called when the shared object was dynamically +loaded. The specific name of this method is not given here because statically +linked modules are not encouraged with swig +(Static Linking). However one can find this +init function in the _wrap.c file generated by swig. +
+ +Assuming you have found the init function in the _wrap.c file and you +are still undeterred by what has been said so far, then there are two ways +to initialize the swig generated C module with the init method. Which way +you use depends on what version of python your module is being linked with. +Python2 and Python3 treat this init function differently. And they way +they treat it differently affects how the pure python module will be able to +locate the C module. +
+ +The details concerning this are covered completly in the documentation +for python itself. Links to the relavent sections follow: +
+ +There are two keys things to understand. The first of which is that in +python2 the init() function returns void. But in python3, the init() funcion +returns a PyObject * which points to the new module. Secondly when +you call the init() method manually, you are the python importer. So, you +determine which package the C module will be located in. +
+ +So, if you are using python3 it is important that you follow what is +described in the python documentation linked above. In particular, you can't +simply call the init() function generated by swig and cast the PyObject +pointer it returns over the side. If you do then python3 still will have no +idea that your C module exists and the pure python half of your wrapper will +not be able to find it. You need to register your module with the python +interpreter as descibed in the python docs. +
+ +With python2 things are somewhat more simple. In this case the init function +returns void. And calling it will register your new C module as a global +module. The pure python part of the swig wrapper will be able to find it +because it tries both the package the pure python module is part of and +globally. If you wish to not have the statically linked module be a global +module then you will either need to refer to the python documentation on how +to do this (remember you are now the python importer) or use dynamic linking. +
+It is strongly recommended to use dynamically linked modules for the C -portion of your pair of python modules. See the section on -Static Linking. If for some reason you still need -to link the C module of the pair of python modules generated by swig into +portion of your pair of Python modules. +If for some reason you still need +to link the C module of the pair of Python modules generated by SWIG into your interpreter, then this section provides some details on how this impacts -the pure python modules ability to locate the other part of the pair. +the pure Python modules ability to locate the other part of the pair. +Please also see the Static Linking section.
-When python is extended with C code the python interpreter needs to be +
When Python is extended with C code the Python interpreter needs to be informed about details of the new C functions that have been linked into -the executable. The code to do this is created by swig and is automatically +the executable. The code to do this is created by SWIG and is automatically called in the correct way when the module is dynamically loaded. However when the code is not dynamically loaded (because it is statically linked) -Then the initialization method for the module created by swig is not -called automatically. And the python interpreter has no idea that the -new swig C module exists. +Then the initialization method for the module created by SWIG is not +called automatically and the Python interpreter has no idea that the +new SWIG C module exists.
-Before python3, one could simply call the init method created by swig +
Before Python 3, one could simply call the init method created by SWIG which would have normally been called when the shared object was dynamically loaded. The specific name of this method is not given here because statically -linked modules are not encouraged with swig -(Static Linking). However one can find this -init function in the _wrap.c file generated by swig. +linked modules are not encouraged with SWIG +(Static Linking). However one can find this +init function in the C file generated by SWIG.
-Assuming you have found the init function in the _wrap.c file and you -are still undeterred by what has been said so far, then there are two ways -to initialize the swig generated C module with the init method. Which way -you use depends on what version of python your module is being linked with. -Python2 and Python3 treat this init function differently. And they way -they treat it differently affects how the pure python module will be able to -locate the C module. +
If you are really keen on static linking there are two ways +to initialize the SWIG generated C module with the init method. Which way +you use depends on what version of Python your module is being linked with. +Python 2 and Python 3 treat this init function differently. And the way +they treat it affects how the pure Python module will be able to +locate the C module.
The details concerning this are covered completly in the documentation -for python itself. Links to the relavent sections follow: +for Python itself. Links to the relavent sections follow:
There are two keys things to understand. The first of which is that in -python2 the init() function returns void. But in python3, the init() funcion -returns a PyObject * which points to the new module. Secondly when -you call the init() method manually, you are the python importer. So, you -determine which package the C module will be located in. +
There are two keys things to understand. The first is that in +Python 2 the init() function returns void. In Python 3 the init() function +returns a PyObject * which points to the new module. Secondly, when +you call the init() method manually, you are the Python importer. So, you +determine which package the C module will be located in.
-So, if you are using python3 it is important that you follow what is -described in the python documentation linked above. In particular, you can't -simply call the init() function generated by swig and cast the PyObject -pointer it returns over the side. If you do then python3 still will have no -idea that your C module exists and the pure python half of your wrapper will -not be able to find it. You need to register your module with the python -interpreter as descibed in the python docs. +
So, if you are using Python 3 it is important that you follow what is +described in the Python documentation linked above. In particular, you can't +simply call the init() function generated by SWIG and cast the PyObject +pointer it returns over the side. If you do then Python 3 will have no +idea that your C module exists and the pure Python half of your wrapper will +not be able to find it. You need to register your module with the Python +interpreter as described in the Python docs.
-With python2 things are somewhat more simple. In this case the init function -returns void. And calling it will register your new C module as a global -module. The pure python part of the swig wrapper will be able to find it -because it tries both the package the pure python module is part of and -globally. If you wish to not have the statically linked module be a global -module then you will either need to refer to the python documentation on how -to do this (remember you are now the python importer) or use dynamic linking. +
With Python 2 things are somewhat more simple. In this case the init function +returns void. Calling it will register your new C module as a global +module. The pure Python part of the SWIG wrapper will be able to find it +because it tries both the pure Python module it is part of and the global +module. If you wish not to have the statically linked module be a global +module then you will either need to refer to the Python documentation on how +to do this (remember you are now the Python importer) or use dynamic linking.
-Last update : SWIG-3.0.10 (in progress) +Last update : SWIG-3.0.10 (12 Jun 2016)
-Last update : SWIG-3.0.10 (12 Jun 2016) +Last update : SWIG-3.0.11 (in progress)