diff --git a/docs/concepts/projects/dependencies.md b/docs/concepts/projects/dependencies.md index c718de57b988..6e976d3d3b2f 100644 --- a/docs/concepts/projects/dependencies.md +++ b/docs/concepts/projects/dependencies.md @@ -1,11 +1,14 @@ # Managing dependencies +## Dependency tables + Dependencies of the project are defined in several tables: -- [`project.dependencies`](./dependencies.md#project-dependencies): Published dependencies. -- [`project.optional-dependencies`](./dependencies.md#optional-dependencies): Published optional - dependencies, or "extras". -- [`dependency-groups`](./dependencies.md#dependency-groups): Local dependencies for development. +- [`project.dependencies`](#project-dependencies): Published dependencies. +- [`project.optional-dependencies`](#optional-dependencies): Published optional dependencies, or + "extras". +- [`dependency-groups`](#dependency-groups): Local dependencies for development. +- [`tool.uv.sources`](#dependency-sources): Alternative sources for dependencies during development. !!! note @@ -13,7 +16,8 @@ Dependencies of the project are defined in several tables: project isn't going to be published. `dependency-groups` are a recently standardized feature and may not be supported by all tools yet. -uv supports modifying the project's dependencies with `uv add` and `uv remove`. +uv supports modifying the project's dependencies with `uv add` and `uv remove`, but dependency +metadata can also be updated by editing the `pyproject.toml` directly. ## Adding dependencies @@ -23,18 +27,54 @@ To add a dependency: $ uv add httpx ``` -uv supports adding [editable dependencies](./dependencies.md#editable-dependencies), -[development dependencies](./dependencies.md#development-dependencies), -[optional dependencies](./dependencies.md#optional-dependencies), and alternative -[dependency sources](./dependencies.md#dependency-sources). See the -[dependency specification](./dependencies.md) documentation for more details. +An entry will be added in the `project.dependencies` table: + +```toml title="pyproject.toml" hl_lines="4" +[project] +name = "example" +version = "0.1.0" +dependencies = ["httpx>=0.27.2"] +``` + +The [`--dev`](#development-dependencies), [`--group`](#dependency-groups), or +[`--optional`](#optional-dependencies) flags can be used to add a dependencies to an alternative +table. + +The dependency will include a constraint, e.g., `>=0.27.2`, for the most recent, compatible version +of the package. An alternative constraint can be provided: + +```console +$ uv add 'httpx>=0.20' +``` + +When adding a dependency from a source other than a package registry, uv will add an entry in the +sources table. For example, when adding `httpx` from GitHub: + +```console +$ uv add "httpx @ git+https://github.com/encode/httpx" +``` + +The `pyproject.toml` will include a [Git source entry](#git): + +```toml title="pyproject.toml" hl_lines="8-9" +[project] +name = "example" +version = "0.1.0" +dependencies = [ + "httpx", +] + +[tool.uv.sources] +httpx = { git = "https://github.com/encode/httpx" } +``` -uv will raise an error if the dependency cannot be resolved, e.g.: +If a dependency cannot be used, uv will display an error.: ```console $ uv add 'httpx>9999' -error: Because only httpx<=9999 is available and example==0.1.0 depends on httpx>9999, we can conclude that example==0.1.0 cannot be used. -And because only example==0.1.0 is available and you require example, we can conclude that the requirements are unsatisfiable. + × No solution found when resolving dependencies: + ╰─▶ Because only httpx<=1.0.0b0 is available and your project depends on httpx>9999, + we can conclude that your project's requirements are unsatisfiable. ``` ## Removing dependencies @@ -45,9 +85,15 @@ To remove a dependency: $ uv remove httpx ``` -## Updating dependencies +The `--dev`, `--group`, or `--optional` flags can be used to remove a dependency from a specific +table. -To update an existing dependency, e.g., to add a lower bound to the `httpx` version: +If a [source](#dependency-sources) is defined for the removed dependency, and there are no other +references to the dependency, it will also be removed. + +## Changing dependencies + +To change an existing dependency, e.g., to use a different constraint for `httpx`: ```console $ uv add 'httpx>0.1.0' @@ -55,35 +101,28 @@ $ uv add 'httpx>0.1.0' !!! note - "Updating" a dependency refers to changing the constraints for the dependency in the - `pyproject.toml`. The locked version of the dependency will only change if necessary to - satisfy the new constraints. To force the package version to update to the latest within - the constraints, use `--upgrade-package `, e.g.: + In this example, we are changing the constraints for the dependency in the `pyproject.toml`. + The locked version of the dependency will only change if necessary to satisfy the new + constraints. To force the package version to update to the latest within the constraints, use `--upgrade-package `, e.g.: ```console $ uv add 'httpx>0.1.0' --upgrade-package httpx ``` - See the [lockfile](./sync.md#upgrading-locked-package-versions) section for more details on upgrading - package versions. - -Or, to change the bounds for `httpx`: - -```console -$ uv add 'httpx<0.2.0' -``` + See the [lockfile](./sync.md#upgrading-locked-package-versions) documentation for more details + on upgrading packages. -To add a dependency source, e.g., to use `httpx` from GitHub during development: +Requesting a different dependency source will update the `tool.uv.sources` table, e.g., to use +`httpx` from a local path during development: ```console -$ uv add git+https://github.com/encode/httpx +$ uv add "httpx @ ../httpx" ``` ## Platform-specific dependencies To ensure that a dependency is only installed on a specific platform or on specific Python versions, -use Python's standardized -[environment markers](https://peps.python.org/pep-0508/#environment-markers) syntax. +use [environment markers](https://peps.python.org/pep-0508/#environment-markers). For example, to install `jax` on Linux, but not on Windows or macOS: @@ -111,32 +150,9 @@ $ uv add 'numpy; python_version >= "3.11"' See Python's [environment marker](https://peps.python.org/pep-0508/#environment-markers) documentation for a complete enumeration of the available markers and operators. -## Dependency tables - -In uv, project dependencies are declared across two `pyproject.toml` tables: `project.dependencies` -and `tool.uv.sources`. - -`project.dependencies` defines the standards-compliant dependency metadata, propagated when -uploading to PyPI or building a wheel. - -`tool.uv.sources` enriches the dependency metadata with additional sources, incorporated during -development. A dependency source can be a Git repository, a URL, a local path, or an alternative -registry. - -`tool.uv.sources` enables uv to support common patterns like editable installations and relative -paths that are not supported by the `project.dependencies` standard. For example: - -```toml title="pyproject.toml" -[project] -name = "albatross" -version = "0.1.0" -dependencies = [ - "bird-feeder", -] +!!! tip -[tool.uv.sources] -bird-feeder = { path = "./packages/bird-feeder" } -``` + Dependency sources can also be [changed per-platform](#platform-specific-sources). ## Project dependencies @@ -169,45 +185,52 @@ dependencies = [ ] ``` -If the project only requires packages from standard package indexes, then `project.dependencies` is -sufficient. If the project depends on packages from Git, remote URLs, or local sources, -`tool.uv.sources` can be used to enrich the dependency metadata without ejecting from the -standards-compliant `project.dependencies` table. - ## Dependency sources -During development, a project may rely on a package that isn't available on PyPI. The following -additional sources are supported by uv: +The `tool.uv.sources` table extends the standard dependency tables with alternative dependency +sources, which are used during development. -- Index: A package resolved from a specific package index. -- Git: A Git repository. -- URL: A remote wheel or source distribution. -- Path: A local wheel, source distribution, or project directory. -- Workspace: A member of the current workspace. +Dependency sources add support common patterns that are not supported by the `project.dependencies` +standard, like editable installations and relative paths. For example, to install `foo` from a +directory relative to the project root: -Note that if a non-uv project uses a project with sources as a Git- or path-dependency, only -`project.dependencies` and `project.optional-dependencies` are respected. Any information provided -in the source table will need to be re-specified in a format specific to the other package manager. - -To instruct uv to ignore the `tool.uv.sources` table (e.g., to simulate resolving with the package's -published metadata), use the `--no-sources` flag: +```toml title="pyproject.toml" hl_lines="7" +[project] +name = "example" +version = "0.1.0" +dependencies = ["foo"] -```console -$ uv lock --no-sources +[tool.uv.sources] +foo = { path = "./packages/foo" } ``` -The use of `--no-sources` will also prevent uv from discovering any -[workspace members](#workspace-member) that could satisfy a given dependency. +The following dependency sources are supported by uv: + +- [Index](#index): A package resolved from a specific package index. +- [Git](#git): A Git repository. +- [URL](#url): A remote wheel or source distribution. +- [Path](#path): A local wheel, source distribution, or project directory. +- [Workspace](#workspace-member): A member of the current workspace. + +!!! important + + Sources are only respected by uv. If another tool is used, only the definitions in the standard + project tables will be used. If another tool is being used for development, any metadata + provided in the source table will need to be re-specified in the other tool's format. ### Index -To pin a Python package to a specific index, add a named index to the `pyproject.toml`: +To add Python package from a specific index, use the `--index` option: + +```console +$ uv add torch --index pytorch=https://download.pytorch.org/whl/cpu +``` + +uv will store the index in `[[tool.uv.index]]` and add a `[tool.uv.sources]` entry: ```toml title="pyproject.toml" [project] -dependencies = [ - "torch", -] +dependencies = ["torch"] [tool.uv.sources] torch = { index = "pytorch" } @@ -215,16 +238,32 @@ torch = { index = "pytorch" } [[tool.uv.index]] name = "pytorch" url = "https://download.pytorch.org/whl/cpu" -explicit = true ``` -The `explicit` flag is optional and indicates that the index should _only_ be used for packages that -explicitly specify it in `tool.uv.sources`. If `explicit` is not set, other packages may be resolved -from the index, if not found elsewhere. +!!! tip + + The above example will only work on x86-64 Linux, due to the specifics of the PyTorch index. + See the [PyTorch guide](../../guides/integration/pytorch.md) for more information about setting + up PyTorch. + +Using an `index` source _pins_ a package to the given index — it will not be downloaded from other +indexes. + +When defining an index, an `explicit` flag can be included to indicate that the index should _only_ +be used for packages that explicitly specify it in `tool.uv.sources`. If `explicit` is not set, +other packages may be resolved from the index, if not found elsewhere. + +```toml title="pyproject.toml" hl_lines="3" +[[tool.uv.index]] +name = "pytorch" +url = "https://download.pytorch.org/whl/cpu" +explicit = true +``` ### Git -To add a Git dependency source, prefix a Git-compatible URL to clone with `git+`. +To add a Git dependency source, prefix a Git-compatible URL (i.e., that you would use with +`git clone`) with `git+`. For example: @@ -232,65 +271,64 @@ For example: $ uv add git+https://github.com/encode/httpx ``` -Will result in a `pyproject.toml` with: - -```toml title="pyproject.toml" +```toml title="pyproject.toml" hl_lines="5" [project] -dependencies = [ - "httpx", -] +dependencies = ["httpx"] [tool.uv.sources] httpx = { git = "https://github.com/encode/httpx" } ``` -A revision (i.e., commit), tag, or branch may also be included: +Specific Git references can be requested, e.g., a tag: ```console $ uv add git+https://github.com/encode/httpx --tag 0.27.0 -$ uv add git+https://github.com/encode/httpx --branch master -$ uv add git+https://github.com/encode/httpx --rev 326b9431c761e1ef1e00b9f760d1f654c8db48c6 ``` -Git dependencies can also be manually added or edited in the `pyproject.toml` with the -`{ git = }` syntax. A target revision may be specified with one of: `rev` (i.e., commit), -`tag`, or `branch`. +```toml title="pyproject.toml" hl_lines="7" +[project] +dependencies = ["httpx"] -=== "tag" +[tool.uv.sources] +httpx = { + git = "https://github.com/encode/httpx", + tag = "0.27.0" +} +``` - ```toml title="pyproject.toml" - [project] - dependencies = [ - "httpx", - ] +Or, a branch: - [tool.uv.sources] - httpx = { git = "https://github.com/encode/httpx", tag = "0.27.0" } - ``` +```console +$ uv add git+https://github.com/encode/httpx --branch main +``` -=== "branch" +```toml title="pyproject.toml" hl_lines="7" +[project] +dependencies = ["httpx"] - ```toml title="pyproject.toml" - [project] - dependencies = [ - "httpx", - ] +[tool.uv.sources] +httpx = { + git = "https://github.com/encode/httpx", + branch = "main" +} +``` - [tool.uv.sources] - httpx = { git = "https://github.com/encode/httpx", branch = "main" } - ``` +Or, a revision (commit): -=== "rev" +```console +$ uv add git+https://github.com/encode/httpx --rev 326b9431c761e1ef1e00b9f760d1f654c8db48c6 +``` - ```toml title="pyproject.toml" - [project] - dependencies = [ - "httpx", - ] +```toml title="pyproject.toml" hl_lines="7" +[project] +dependencies = ["httpx"] - [tool.uv.sources] - httpx = { git = "https://github.com/encode/httpx", rev = "326b9431c761e1ef1e00b9f760d1f654c8db48c6" } - ``` +[tool.uv.sources] +httpx = { + git = "https://github.com/encode/httpx", + rev = "326b9431c761e1ef1e00b9f760d1f654c8db48c6" +} +``` A `subdirectory` may be specified if the package isn't in the repository root. @@ -308,11 +346,9 @@ $ uv add "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c33 Will result in a `pyproject.toml` with: -```toml title="pyproject.toml" +```toml title="pyproject.toml" hl_lines="5" [project] -dependencies = [ - "httpx", -] +dependencies = ["httpx"] [tool.uv.sources] httpx = { url = "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz" } @@ -339,9 +375,7 @@ Will result in a `pyproject.toml` with: ```toml title="pyproject.toml" [project] -dependencies = [ - "foo", -] +dependencies = ["foo"] [tool.uv.sources] foo = { path = "/example/foo-0.1.0-py3-none-any.whl" } @@ -380,16 +414,14 @@ details on workspaces. ```toml title="pyproject.toml" [project] -dependencies = [ - "mollymawk ==0.1.0" -] +dependencies = ["foo==0.1.0"] [tool.uv.sources] -mollymawk = { workspace = true } +foo = { workspace = true } [tool.uv.workspace] members = [ - "packages/mollymawk" + "packages/foo" ] ``` @@ -401,14 +433,16 @@ environment markers for the source. For example, to pull `httpx` from GitHub, but only on macOS, use the following: -```toml title="pyproject.toml" +```toml title="pyproject.toml" hl_lines="8" [project] -dependencies = [ - "httpx", -] +dependencies = ["httpx"] [tool.uv.sources] -httpx = { git = "https://github.com/encode/httpx", tag = "0.27.2", marker = "sys_platform == 'darwin'" } +httpx = { + git = "https://github.com/encode/httpx", + tag = "0.27.2", + marker = "sys_platform == 'darwin'" +} ``` By specifying the marker on the source, uv will still include `httpx` on all platforms, but will @@ -422,23 +456,29 @@ environment markers. For example, to pull in different `httpx` commits on macOS vs. Linux: -```toml title="pyproject.toml" +```toml title="pyproject.toml" hl_lines="8-9 13-14" [project] -dependencies = [ - "httpx", -] +dependencies = ["httpx"] [tool.uv.sources] httpx = [ - { git = "https://github.com/encode/httpx", tag = "0.27.2", marker = "sys_platform == 'darwin'" }, - { git = "https://github.com/encode/httpx", tag = "0.24.1", marker = "sys_platform == 'linux'" }, + { + git = "https://github.com/encode/httpx", + tag = "0.27.2", + marker = "sys_platform == 'darwin'" + }, + { + git = "https://github.com/encode/httpx", + tag = "0.24.1", + marker = "sys_platform == 'linux'" + }, ] ``` -This strategy even extends to pulling packages from different indexes based on environment markers. -For example, to pull `torch` from different PyTorch indexes based on the platform: +This strategy extends to using different indexes based on environment markers. For example, to +install `torch` from different PyTorch indexes based on the platform: -```toml title="pyproject.toml" +```toml title="pyproject.toml" hl_lines="6-7" [project] dependencies = ["torch"] @@ -457,6 +497,18 @@ name = "torch-gpu" url = "https://download.pytorch.org/whl/cu124" ``` +### Disabling sources + +To instruct uv to ignore the `tool.uv.sources` table (e.g., to simulate resolving with the package's +published metadata), use the `--no-sources` flag: + +```console +$ uv lock --no-sources +``` + +The use of `--no-sources` will also prevent uv from discovering any +[workspace members](#workspace-member) that could satisfy a given dependency. + ## Optional dependencies It is common for projects that are published as libraries to make some features optional to reduce