I'm trying out uv to manage my Python project's dependencies and virtualenv, but I can't see how to install all my dependencies for local development, including the development dependencies.
In my pyproject.toml file, I have this kind of thing:
[project]
name = "my-project"
dependencies = [
"django",
]
[tool.uv]
dev-dependencies = [
"factory-boy",
]
[tool.uv.pip]
python-version = "3.10"
I can do the following to create a virtualenv and then generate a requirements.txt
lockfile, which does not contain dev-dependencies (which is OK, because that is for production):
uv venv --python 3.10
uv pip compile pyproject.toml -o requirements.txt
But how can I install all the dependencies in my virtualenv?
uv pip sync
will use the requirements.txt
.
There's also uv sync
, but I don't understand how that differs, and trying that generates an error:
error: Multiple top-level packages discovered in a flat-layout: ['conf', 'hines', 'docker', 'assets', 'node_modules'].
Any dependency (such as pytest) added to a project by running
uv add --dev pytest
will be added to the corresponding dev dependency group in pyproject.toml
.
pyproject.toml
[dependency-groups]
dev = [
"pytest"
]
Any such dependencies will be installed when running uv sync
(and are excluded when running uv sync --no-dev
). Such dependencies are local-only and will not be included in the project requirements of the published project.
When working with project dependencies, it is helpful to differentiate between
polars[pydantic]
syntax, but Pydantic is not installed unless explicitly specified. Still, these dependencies will be included as optional requirements when publishing to PyPI or other indexes;Unlike published (required or optional) dependencies, development dependencies will not be included when publishing a project. Especially, they are not included in the [project]
table (i.e., section) of the pyproject.toml
. Instead, they are added to the [dependency-groups]
table (see PEP 735). This table may contain arbitrary dependency groups, such as dev, test, and funky.
With uv, a dependency can be added to any given group in the [dependency-groups]
table by running
uv add --group GROUP DEPENDENCY
e.g.
uv add --group test pytest
This will create a corresponding list-entry in the [dependency-groups]
table of pyproject.toml
(if non-existent) and append the dependency.
[dependency-groups]
test = [
"pytest"
]
With uv, the dependencies from a given dependency group can be included when updating an environment by using the --group GROUP
option for uv sync
.
uv sync --group test
The aforementioned information is sufficient to use development dependencies with uv. However, uv also provides sensible defaults and gives privileged treatment to the dev dependency-group. Especially,
uv add --dev pytest
is syntactic sugar for
uv add --group dev pytest
and will make the same changes to pyproject.toml
. Moreover, all dependencies in the dev dependency-group will be installed by default, when running uv sync
. They can be explicitly excluded by running
uv sync --no-group dev
or
uv sync --no-dev
Moreover, the default groups can be changed to be something other than ["dev"]
by adjusting the default-groups
setting in the [tool.uv]
table.
[tool.uv]
default-groups = ["dev", "funky"]
Note. More information can be found in the documentation.
To expand on the other good answers by Phil:
With uv >= 0.4.27
we can use the new Python packaging feature dependency groups to make pyproject uv-agnostic:
[project]
name = "my-project"
dynamic = ["version"]
requires-python = ">=3.10"
dependencies = ["django"]
[dependency-groups]
dev = ["factory-boy"]
Also can make use of .python-version
to pin the project Python version, which be created manually or by uv python
:
uv python pin 3.10
Check version written to file:
cat .python-version
Output:
3.10
With the above configuration in place, a developer virtualenv can be created with:
uv sync
Finally, activate the venv:
source .venv/bin/activate
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With