Required dependencies¶
If you’ve used Python for a while, you have probably seen requirements.txt files. These are commonly used with tools like pip, which treats the file as a list of necessary dependencies. Since PEP 621, it is possible to define your dependencies directly in pyproject.toml. For example, to require NumPy:
1 2 3 4[project] dependencies = [ "numpy" ]
You can add additional constraints here, such as a minimum version:
1 2 3 4[project] dependencies = [ "numpy>=2" ]
Or specify packages that are only required for certain versions of Python:
1 2 3 4[project] dependencies = [ "numpy<2;python_version<\"3.12\"" ]
Optional dependencies¶
Sometimes, you don’t need a dependency for all of your package’s features. For example, you might have some plotting routines that need matplotlib. The pyproject.toml specification defines an optional-dependencies table:
1 2[project.optional-dependencies] plot = ["matplotlib"]
Users can then request these extra dependencies when installing your package:
pip install arrow-to-knee[plot]Dependency groups¶
When you start using Python packages to help develop your package, such as the ruff code formatter, you will want to define that these packages are a required development tool. Historically, people have used project.optional-dependencies for this, so you’ll often see something like the following:
pip install arrow-to-knee[dev]Recently, Python gained the ability to define dependency groups. They are defined very similarly to Optional dependencies:
[dependency-groups]
dev = ["pytest", "requests"]These are not installed when a user installs your package, but they are understood by tools like pip. For example, if you execute the following in the same directory as pyproject.toml:
pip install --group devIt will install the packages from the dev dependency group!