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 dev
It will install the packages from the dev
dependency group!