Skip to content

Installing Python Development Dependencies with uv

Managing both production and development dependencies is essential for Python development workflows. When using uv (Astral's fast Python package installer), development dependencies require special handling through dependency groups.

Problem Statement

When managing a Python project with uv, developers encounter these challenges:

  1. Production dependencies installed via uv pip compile or uv pip sync don't include dev dependencies
  2. The [tool.uv] section in pyproject.toml doesn't automatically install development dependencies
  3. Running direct commands like uv sync might fail with layout errors:
    error: Multiple top-level packages discovered in a flat-layout

Solution Overview

The optimal approach combines these techniques:

  1. Use **dependency groups (PEP 735)** for dev dependencies
  2. Install using uv sync which handles dependency groups automatically
  3. Fix flat-layout errors with setuptools configuration
  4. Pin Python versions for consistent environments

1. Configuring Dependency Groups

Replace tool.uv.dev-dependencies with dependency-groups in your pyproject.toml:

toml
[project]
name = "my-project"
dependencies = [
  "django",
]

[build-system]
requires = ["setuptools", "uv"]
build-backend = "setuptools.build_meta"

# Modern dependency groups (uv >= 0.4.0)
[dependency-groups]
dev = [
  "factory-boy",
  "pytest"
]

[tool.setuptools]  # Prevents flat-layout errors
py-modules = []

PRO TIP

Run uv add --dev factory-boy to automatically add dependencies to the dev group and update pyproject.toml

2. Installing All Dependencies

Install both production and development dependencies with:

bash
# Create virtual environment
uv venv

# Install all dependencies (including dev group)
uv sync

3. Resolving Common Errors

Problem: Multiple top-level packages discovered in a flat-layout
Solution: Add setuptools configuration to pyproject.toml:

toml
[tool.setuptools]
py-modules = []  # Explicitly declare no top-level modules

4. Pinning Python Version

For consistent environments:

bash
uv python pin 3.10  # Creates .python-version file

Key Workflow Commands

CommandPurpose
uv add --dev packageAdd to dev dependency group
uv syncInstall all dependencies (default includes 'dev')
uv sync --no-devInstall only production dependencies
uv python pin 3.10Pin project Python version

Advanced Configuration

Customize default groups in pyproject.toml:

toml
[tool.uv]
default-groups = ["dev", "test"]  # Install these groups by default

Understanding Dependency Types

TypeLocationPublishedInstall Command
Production[project].dependenciesYesuv sync
Optional (Extras)[project.optional-dependencies]Yesuv sync --with extra_name
Development[dependency-groups]Nouv sync (default)

WARNING

Avoid the obsolete tool.uv.dev-dependencies approach - it's been replaced by dependency groups

Complete Setup Example

  1. Initialize your project:
bash
uv init
uv venv
  1. Add dependencies:
bash
uv add django           # Production dependency
uv add --dev pytest     # Dev dependency
  1. Install everything:
bash
uv sync
source .venv/bin/activate

Conclusion

  1. Use [dependency-groups] for development dependencies
  2. Install all dependencies with uv sync
  3. Fix layout errors with [tool.setuptools]
  4. Manage dependencies through uv add --dev

This workflow keeps development dependencies separate from production while ensuring a consistent installation process.