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?