Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I install Python dev-dependencies using uv?

Tags:

python

uv

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'].
like image 451
Phil Gyford Avatar asked Sep 06 '25 03:09

Phil Gyford


2 Answers

TLDR.

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.


General Dependency Management

When working with project dependencies, it is helpful to differentiate between

  • published dependencies that are used when publishing to PyPI or other indexes, and when building a wheel package;
  • optional published dependencies that are required for an optional (extra) feature of the project. For example, Polars has a Pydantic extra that enables conversion from Pydantic models to Polar models. It can be installed with the 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;
  • development (local) dependencies are local-only and will not be included when publishing a project. Such dependencies are the concern of this question.

Development (local) dependencies

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.

Adding Dependencies to a Dependency Group

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"
]

Installing Dependencies from a Dependency Group

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

Tricks and Defaults

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.

like image 59
Hericks Avatar answered Sep 07 '25 19:09

Hericks


To expand on the other good answers by Phil:

Dependency Groups

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"]

Python Pinned

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

Dev venv

With the above configuration in place, a developer virtualenv can be created with:

uv sync

Finally, activate the venv:

source .venv/bin/activate
like image 30
Cas Avatar answered Sep 07 '25 21:09

Cas