I have a package with a pyproject.toml
that has a core package & an optional GUI package with its own extra dependencies. This is the project structure:
.
└── my_project/
├── src/
│ └── my_package/
│ ├── core/
│ │ └── __init__.py
│ ├── gui/
│ │ └── __init__.py
│ └── __init__.py
├── poetry.lock
└── pyproject.toml
PEP 771 specifies how extras can be installed using square brackets. I have found plenty of resources on how to install extras, but frustratingly none on how to define them in your own project.
How do I set up my project so that a user installing with poetry add my_package
installs just the core
package, but poetry add my_package[gui]
installs both core
and gui
?
Extras don't work like that, they only apply to your packages dependencies. If you put the code in same package it will get bundled in when the package is built. Extras only apply to the dependencies of your package. In your case regardless of whether the user specifies [gui]
or not they will get the gui code bundled into the package. what you can do is use extras to prevent all the gui dependencies from being installed when the user isn't using the gui.
To make the error pretty clear for the user i've put something like this in optional modules __init__.py
try:
import some_gui_depedency ...
except ModuleNotFoundError:
raise Exception("Gui dependencies not installed, use `poetry add <package> -e gui` to use Gui
generally python code is tiny so it doesn't really matter that your shipping code that won't work, its usually the dependencies that have lots of binaries etc. thats really what makes things take a while to install.
If your trying to hide the gui code from the user (maybe for commercial reasons?) you will need to make them seperate packages.