Reputation: 1363
I have a python package that I can use standalone just fine. When I install it to site-packages with pip, though, I lose the ability to import submodules.
My package looks like this:
mypackage
mypackage
__init__.py
mymodule.py
moduledir
__init__.py
mysubmodule.py
setup.py
If I have the package on my pythonpath, I can use it just fine. But then when I use pip to install it to site-packages, I can't import submodules.
from mypackage import mymodule # works fine
from mypackage.moduledir import mysubmodule # ModuleNotFoundError: No module named when installed to site-packages, works fine when on pythonpath
What's going on here? How do I change it so that I can import submodules?
Also, I'm sure this is answered somewhere, but I can't find it for the life of me on google or SO. I apologize if its trivial and I'm just googling the wrong terms.
Edit: Here is my setup.py as requested.
from setuptools import setup
setup(name='mypackage',
version='0.1',
description='mypackage',
url='https://gitlab.com/ericksonla/mypackage',
author='ericksonla',
author_email='ericksonla@ericksonla.com',
license='',
packages=['mypackage'],
install_requires=[],
zip_safe=False)
Upvotes: 2
Views: 1751
Reputation: 146
I'm glad to see you found a setuptools
solution that works for you. An alternative within setuptools
that I recently learned about is the setuptools.find_packages()
function. With the correct arguments, setuptools.find_packages()
can discover and add an arbitrary number of submodules of your package, which folks may find useful for packages that grow in size and add submodules.
If you were to use this method in this example, your setup.py
file might look like:
# setup.py
from setuptools import setup, find_packages
setup(name='mypackage',
version='0.1',
description='mypackage',
url='https://gitlab.com/ericksonla/mypackage',
author='ericksonla',
author_email='ericksonla@ericksonla.com',
license='',
packages=find_packages(),
install_requires=[],
zip_safe=False)
That flexibility comes with some caveats for more complicated use-cases, however.
For example, your current package structure gives your source code module the same name as the package itself (the code for mypackage
is stored in directory mypackage
). If you were to use a different directory structure, such as
mypackage
src
mypackage
__init__.py
mymodule.py
moduledir
__init__.py
mysubmodule.py
tests
mytest.py
setup.py
where the source code is in the src
subdirectory, I think you would need to specify the "where" argument of find_packages
in your setup.py
file and add the package_dir
argument to tell setuptools.setup()
that it should map the contents of src
to your package name, not to a src
submodule:
# setup.py
from setuptools import setup, find_packages
setup(name='mypackage',
version='0.1',
description='mypackage',
url='https://gitlab.com/ericksonla/mypackage',
author='ericksonla',
author_email='ericksonla@ericksonla.com',
license='',
packages=find_packages('src'),
package_dir={'': 'src'}
install_requires=[],
zip_safe=False)
Upvotes: 1
Reputation: 1363
I needed to add the submodules to the packages list in setup.py
:
# setup.py
from setuptools import setup
setup(name='mypackage',
version='0.1',
description='mypackage',
url='https://gitlab.com/ericksonla/mypackage',
author='ericksonla',
author_email='ericksonla@ericksonla.com',
license='',
packages=[
'mypackage',
'mypackage.moduledir'],
install_requires=[],
zip_safe=False)
I'm still not quite sure why I need to import one level down, but not any further.
Upvotes: 2