I\'d like to install some special sub-package from a package.
For example, I want to create package with pkg_a and pkg_b. But I want to allow the user to choose which he
If the projects are not installed from an index such as PyPI, it is not possible to take advantage of the install_requires
feature. Something like this could be done instead:
.
├── NmspcPing
│ ├── nmspc.ping
│ │ └── __init__.py
│ └── setup.py
├── NmspcPong
│ ├── nmspc.pong
│ │ └── __init__.py
│ └── setup.py
└── setup.py
NmspcPing/setup.py
(and similarly NmspcPong/setup.py
)
import setuptools
setuptools.setup(
name='NmspcPing',
version='1.2.3',
package_dir={'nmspc.ping': 'nmspc.ping'},
packages=['nmspc.ping'],
)
setup.py
import setuptools
setuptools.setup(
name='Nmspc',
version='1.2.3',
package_dir={
'nmspc.ping': 'NmspcPing/nmspc.ping',
'nmspc.pong': 'NmspcPong/nmspc.pong',
},
packages=['nmspc.ping', 'nmspc.pong'],
)
This allows to install from the root folder in any of the following combinations:
$ python3 -m pip install .
$ python3 -m pip install ./NmspcPing
$ python3 -m pip install ./NmspcPong
$ python3 -m pip install ./NmspcPing ./NmspcPong
A solution for your use case seems to be similar to the one I gave here: https://stackoverflow.com/a/58024830/11138259, as well as the one you linked in your question: Python install sub-package from package.
Here is an example...
The directory tree might look like this:
.
├── Nmspc
│ ├── nmspc
│ │ └── _nmspc
│ │ └── __init__.py
│ └── setup.py
├── NmspcPing
│ ├── nmspc
│ │ └── ping
│ │ └── __init__.py
│ └── setup.py
└── NmspcPong
├── nmspc
│ └── pong
│ └── __init__.py
└── setup.py
3 Python projects:
nmspc.ping
nmspc.pong
nmspc._nmspc
see below for details)They are all namespace packages. They are built using the instructions from the Python Packaging User Guide on "Packaging namespace packages, Native namespace packages". There is another example here.
The project Nmspc is basically empty, no actual code, but the important part is to add the other two NmspcPing and NmspcPong as installation requirements. Another thing to note, is that for convenience it is also a namespace package with nmspc._nmspc
being kind of hidden (the leading underscore is the naming convention for hidden things in Python).
NmspcPing/setup.py
(and similarly NmspcPong/setup.py
):
#!/usr/bin/env python3
import setuptools
setuptools.setup(
name='NmspcPing',
version='1.2.3',
packages=['nmspc.ping',],
)
Nmspc/setup.py
:
#!/usr/bin/env python3
import setuptools
setuptools.setup(
name='Nmspc',
version='1.2.3',
packages=['nmspc._nmspc',],
install_requires=['NmspcPing', 'NmspcPong',],
)
Assuming you are in the root directory, you can install these for development like this:
$ python3 -m pip install -e NmspcPing
$ python3 -m pip install -e NmspcPong
$ python3 -m pip install -e Nmspc
And then you should be able to use them like this:
$ python3 -c "import nmspc.ping; import nmspc.pong; import nmspc._nmspc;"
Update
This can be simplified:
.
├── NmspcPing
│ ├── nmspc
│ │ └── ping
│ │ └── __init__.py
│ └── setup.py
├── NmspcPong
│ ├── nmspc
│ │ └── pong
│ │ └── __init__.py
│ └── setup.py
└── setup.py
setup.py
#!/usr/bin/env python3
import setuptools
setuptools.setup(
name='Nmspc',
version='1.2.3',
install_requires=['NmspcPing', 'NmspcPong',],
)
Use it like this:
$ python3 -m pip install ./NmspcPing ./NmspcPong/ .
$ python3 -c "import nmspc.ping; import nmspc.pong;"