I have a library with a deeply nested module hierarchy, with a structure such as
src/
my_library/
__init__.py
my_module/
__init__.py
my_submodule.py
Such that for example one might be able to write from my_library.my_module.my_submodule import Foo
etc.
I have a function which walks the file tree, discovering all of python modules and converting them into Extension
objects which are passed into cythonize
, effectively cythonizing the whole module. Inspecting the before they are built, they look (in dictionary form) something like:
(Pdb) pp vars(e)
{'define_macros': [],
'depends': [],
'export_symbols': [],
'extra_compile_args': [],
'extra_link_args': [],
'extra_objects': [],
'include_dirs': [],
'language': None,
'libraries': [],
'library_dirs': [],
'name': 'my_library.my_module.my_submodule',
'optional': None,
'runtime_library_dirs': [],
'sources': ['src/my_library/my_module/my_submodule.c'],
'swig_opts': [],
'undef_macros': []}
The list of extensions is then passed into the ext_modules
argument of setuptools.setup()
. Invoking setup.py install
results in a bunch of compilations as expected, which is great. However, files are written to a directory structure mirroring their location prior to being compiled, so for example it ends up with something like
lib/python3.4/site-packages/
my_library.cpython-34m.so
my_library/
my_module.cpython-34m.so
my_module/
my_submodule.cpython-34m.so
Because of this nested structure, I am only able to import the top-level object when the installed-to directory is in my PYTHONPATH
:
>>> import my_library
>>> my_library.foo()
'foo'
>>> import my_library.my_module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'my_library.my_module'
It seems that since the generated files are written to subdirectories rather than directly to the site-packages
folder, the python interpreter is unable to discover them. I don't know much about python extensions, but looking around I didn't see a way to get python to put them in a flat structure rather than nested, nor do I know if there's a way to get python to discover .so
files written to subdirectories -- perhaps by adding __init__.py
files?