Add example to test the Python module being renamed to __init__.py

This examples tests the SWIG generated module being placed into a directory and
then renamed __init__.py to convert the module into a package. This ability
stopped working in swig-3.0.9. However, only Python 2.7 or 3.3 and later work. If
Python 3.2 support is needed, use moduleimport in %module to customise the import
code.

Issue #1282
This commit is contained in:
William S Fulton 2018-12-08 22:31:26 +00:00
commit 51dadaeacd
8 changed files with 101 additions and 0 deletions

View file

@ -8,6 +8,7 @@ import_packages_subdirs = \
from_init1 \
from_init2 \
from_init3 \
module_is_init \
relativeimport1 \
relativeimport2 \
relativeimport3 \

View file

@ -0,0 +1,15 @@
TOP = ../../..
LIBS =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
build:
cd pkg1 && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build
static:
cd pkg1 && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
cd pkg1 && $(MAKE) clean

View file

@ -0,0 +1,18 @@
This example tests renaming the generated SWIG pure Python module to __init__.py
to turn the module into a Python package.
Use 'python runme.py' to run the test.
Overview:
---------
SWIG generates a pure Python module foo.py from the input interface file foo.i.
The foo.py file is generated within the pkg1 directory and is then renamed __init__.py.
This results in everything in the SWIG generated module being available in the Python
pkg1 package.
This approach of turning the SWIG generated module into a package worked in versions
of SWIG up to swig-3.0.8, but stopped working from swig-3.0.9 until it was
re-instated in swig-4.0.0. However, Python 2.7 or 3.3 and later are needed to
work out of the box. Python 3.2 does not work as this version of Python does
not set __package__ in __init__.py.

View file

@ -0,0 +1,20 @@
TOP = ../../../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SWIGOPT =
LIBS =
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' python_cpp
mv foo.py __init__.py
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' python_cpp_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
rm -f __init__.py

View file

@ -0,0 +1,10 @@
int foofunction(int i) {
return i *= 10;
}
struct FooClass {
int foomethod(int i) {
return i += 5;
}
};

View file

@ -0,0 +1,5 @@
%module foo
%{
#include "./foo.hpp"
%}
%include "./foo.hpp"

View file

@ -0,0 +1,26 @@
import os.path
import sys
# Test import of a SWIG generated module renamed as the package's __init__.py
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - module renamed as __init__.py"
if sys.version_info >= (3, 0, 0) and sys.version_info < (3, 3, 0):
print " Not importing as Python version is >= 3.0 and < 3.3"
# Package detection does not work in these versions.
# Can be fixed by using this in the interface file:
# %module(moduleimport="from . import $module") foo # without -builtin
# %module(moduleimport="from .$module import *") foo # with -builtin
sys.exit(0)
import pkg1
print " Finished importing pkg1"
if pkg1.foofunction(123) != 1230:
raise RuntimeError("foofunction failed")
fc = pkg1.FooClass()
if fc.foomethod(1) != 6:
raise RuntimeError("foomethod failed")
print " Finished testing pkg1"