I have a large project that I would like to split into separate, installable packages. The currently layout we have is:
├── MANIFEST.in
├── readme.md
├── package
| ├── __int__.py
│ ├── a
│ │ ├── __init__.py
│ │ └── a.py
│ ├── b
│ │ ├── __init__.py
│ │ └── b.py
│ └── c
│ ├── __init__.py
│ ├── resources
│ │ └── log.png
│ └── c.py
└── setup.py
In this case, we have package.c depends on package.b and package.b depends on package.a. There are additional dependencies where package.a uses 'toml', and package.b uses 'wxPython' and package.c uses 'numpy'.
Now, package.a is the most used package, and I'm trying to separate things out so users can install only package.a, and avoid the overhead of installing package.b and package.c unless they need the features provided by those packages.
Now, in the setup.py
at the top level, we have:
#!/usr/bin/env python3
from setuptools import setup, find_packages
VERSION = '1.0.0'
REQUIRED_PACKAGES = ['toml', 'wxPython', 'numpy']
setup(
name='user_package',
description="User utilities",
version=VERSION,
packages=find_packages(),
include_package_data=True,
author='User',
author_email='user@user.com',
install_requires=REQUIRED_PACKAGES
)
I'm trying to move this over to namespace packages. To do so, I've removed the package/__init__.py
and updated the setup.py
with:
from setuptools import setup, find_namespace_packages
VERSION = '1.0.0'
REQUIRED_PACKAGES = ['toml']
setup(
name='package-a',
description="User utilities",
version=VERSION,
packages=find_namespace_packages(include=['package.a']),
include_package_data=True,
author='User',
author_email='user@user.com',
install_requires=REQUIRED_PACKAGES
)
This packages up package.a separately and nicely. So I though I could call setup
more than once, one for each package, each with their own dependency list:
for i in ['a', 'b', 'c']:
setup(
name=f'package-{i}',
...
packages=find_namespace_packages(include=[f'package.{i}']),
...
install_requires=REQUIRED_PACKAGES[i] # Where REQUIRED_PACKAGES is a dict() of str:list
)
But this fails on subsequent calls to setup.
And I still can't figure out how to describe 'package.c' depending upon 'package.c', though I suspect if I add 'package-b' to the install_requires
list, it will do it.
Perhaps this is a misunderstanding on my part on how to generate the wheel and have separate packages available via PyPi.
So, I guess this boils down to two questions:
- Do I just generate a single wheel, upload it to our PyPi mirror and they will be separately installable? Or do I need to generate 3 separate wheels, one for each package, and upload each?
- How do I separate out the dependencies for each package, so that installing package.a does not pull in the dependencies for package.c?