mirror of https://github.com/astral-sh/uv
Reorganize the project concept documentation (#9121)
- Adds a collapsible section for the project concept - Splits the project concept document into several child documents. - Moves the workspace and dependencies documents to under the project section - Adds a mkdocs plugin for redirects, so links to the moved documents still work I attempted to make the minimum required changes to the contents of the documents here. There is a lot of room for improvement on the content of each new child document. For review purposes, I want to do that work separately. I'd prefer if the review focused on this structure and idea rather than the content of the files. I expect to do this to other documentation pages that would otherwise be very nested. The project concept landing page and nav (collapsed by default) looks like this now: <img width="1507" alt="Screenshot 2024-11-14 at 11 28 45 AM" src="https://github.com/user-attachments/assets/88288b09-8463-49d4-84ba-ee27144b62a5">
This commit is contained in:
parent
45eeae61ff
commit
ca9aaf1c48
|
|
@ -82,8 +82,8 @@ pub(crate) fn main(args: &Args) -> Result<()> {
|
|||
const REPLACEMENTS: &[(&str, &str)] = &[
|
||||
// Use the fully-resolved URL rather than the relative Markdown path.
|
||||
(
|
||||
"(../concepts/dependencies.md)",
|
||||
"(https://docs.astral.sh/uv/concepts/dependencies/)",
|
||||
"(../concepts/projects/dependencies.md)",
|
||||
"(https://docs.astral.sh/uv/concepts/projects/dependencies/)",
|
||||
),
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ impl EnvVars {
|
|||
pub const UV_TOOL_BIN_DIR: &'static str = "UV_TOOL_BIN_DIR";
|
||||
|
||||
/// Specifies the path to the directory to use for a project virtual environment.
|
||||
/// See the [project documentation](../concepts/projects.md#configuring-the-project-environment-path)
|
||||
/// See the [project documentation](../concepts/projects/config.md#project-environment-path)
|
||||
/// for more details.
|
||||
pub const UV_PROJECT_ENVIRONMENT: &'static str = "UV_PROJECT_ENVIRONMENT";
|
||||
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ pub struct ToolUv {
|
|||
/// during development. A dependency source can be a Git repository, a URL, a local path, or an
|
||||
/// alternative registry.
|
||||
///
|
||||
/// See [Dependencies](../concepts/dependencies.md) for more.
|
||||
/// See [Dependencies](../concepts/projects/dependencies.md) for more.
|
||||
#[option(
|
||||
default = "{}",
|
||||
value_type = "dict",
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
Read the concept documents to learn more about uv's features:
|
||||
|
||||
- [Projects](./projects.md)
|
||||
- [Dependencies](./dependencies.md)
|
||||
- [Workspaces](./workspaces.md)
|
||||
- [Projects](./projects/index.md)
|
||||
- [Tools](./tools.md)
|
||||
- [Python versions](./python-versions.md)
|
||||
- [Resolution](./resolution.md)
|
||||
|
|
|
|||
|
|
@ -1,920 +0,0 @@
|
|||
# Projects
|
||||
|
||||
Python projects help manage Python applications spanning multiple files.
|
||||
|
||||
!!! tip
|
||||
|
||||
Looking for an introduction to creating a project with uv? See the [projects guide](../guides/projects.md) first.
|
||||
|
||||
## Project metadata
|
||||
|
||||
Python project metadata is defined in a `pyproject.toml` file.
|
||||
|
||||
!!! tip
|
||||
|
||||
`uv init` can be used to create a new project. See [Creating projects](#creating-projects) for
|
||||
details.
|
||||
|
||||
A minimal project definition includes a name, version, and description:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "example"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
```
|
||||
|
||||
It's recommended, but not required, to include a Python version requirement in the `[project]`
|
||||
section:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
requires-python = ">=3.12"
|
||||
```
|
||||
|
||||
Including a Python version requirement defines the Python syntax that is allowed in the project and
|
||||
affects selection of dependency versions (they must support the same Python version range).
|
||||
|
||||
The `pyproject.toml` also lists dependencies of the project in the `project.dependencies` and
|
||||
`project.optional-dependencies` fields. uv supports modifying the project's dependencies from the
|
||||
command line with `uv add` and `uv remove`. uv also supports extending the standard dependency
|
||||
definitions with [package sources](./dependencies.md) in `tool.uv.sources`.
|
||||
|
||||
!!! tip
|
||||
|
||||
See the official [`pyproject.toml` guide](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/) for more details on getting started with a `pyproject.toml`.
|
||||
|
||||
## Defining entry points
|
||||
|
||||
uv uses the standard `[project.scripts]` table to define entry points for the project.
|
||||
|
||||
For example, to declare a command called `hello` that invokes the `hello` function in the
|
||||
`example_package_app` module:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project.scripts]
|
||||
hello = "example_package_app:hello"
|
||||
```
|
||||
|
||||
!!! important
|
||||
|
||||
Using `[project.scripts]` requires a [build system](#build-systems) to be defined.
|
||||
|
||||
## Build systems
|
||||
|
||||
Projects _may_ define a `[build-system]` in the `pyproject.toml`. The build system defines how the
|
||||
project should be packaged and installed.
|
||||
|
||||
uv uses the presence of a build system to determine if a project contains a package that should be
|
||||
installed in the project virtual environment. If a build system is not defined, uv will not attempt
|
||||
to build or install the project itself, just its dependencies. If a build system is defined, uv will
|
||||
build and install the project into the project environment. By default, projects are installed in
|
||||
[editable mode](https://setuptools.pypa.io/en/latest/userguide/development_mode.html) so changes to
|
||||
the source code are reflected immediately, without re-installation.
|
||||
|
||||
### Configuring project packaging
|
||||
|
||||
uv also allows manually declaring if a project should be packaged using the
|
||||
[`tool.uv.package`](../reference/settings.md#package) setting.
|
||||
|
||||
Setting `tool.uv.package = true` will force a project to be built and installed into the project
|
||||
environment. If no build system is defined, uv will use the setuptools legacy backend.
|
||||
|
||||
Setting `tool.uv.package = false` will force a project package _not_ to be built and installed into
|
||||
the project environment. uv will ignore a declared build system when interacting with the project.
|
||||
|
||||
## Creating projects
|
||||
|
||||
uv supports creating a project with `uv init`.
|
||||
|
||||
uv will create a project in the working directory, or, in a target directory by providing a name,
|
||||
e.g., `uv init foo`. If there's already a project in the target directory, i.e., there's a
|
||||
`pyproject.toml`, uv will exit with an error.
|
||||
|
||||
When creating projects, uv distinguishes between two types: [**applications**](#applications) and
|
||||
[**libraries**](#libraries).
|
||||
|
||||
By default, uv will create a project for an application. The `--lib` flag can be used to create a
|
||||
project for a library instead.
|
||||
|
||||
### Applications
|
||||
|
||||
Application projects are suitable for web servers, scripts, and command-line interfaces.
|
||||
|
||||
Applications are the default target for `uv init`, but can also be specified with the `--app` flag:
|
||||
|
||||
```console
|
||||
$ uv init --app example-app
|
||||
$ tree example-app
|
||||
example-app
|
||||
├── .python-version
|
||||
├── README.md
|
||||
├── hello.py
|
||||
└── pyproject.toml
|
||||
```
|
||||
|
||||
When creating an application, uv will generate a minimal `pyproject.toml`. A build system is not
|
||||
defined and the source code is in the top-level directory, e.g., `hello.py`. The project does not
|
||||
contain a package that will be built and installed into the project environment.
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "example-app"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = []
|
||||
```
|
||||
|
||||
The created script defines a `main` function with some standard boilerplate:
|
||||
|
||||
```python title="hello.py"
|
||||
def main():
|
||||
print("Hello from example-app!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
And can be executed with `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run hello.py
|
||||
Hello from example-project!
|
||||
```
|
||||
|
||||
### Libraries
|
||||
|
||||
A library is a project that is intended to be built and distributed as a Python package, for
|
||||
example, by uploading it to PyPI. A library provides functions and objects for other projects to
|
||||
consume.
|
||||
|
||||
Libraries can be created by using the `--lib` flag:
|
||||
|
||||
```console
|
||||
$ uv init --lib example-lib
|
||||
$ tree example-lib
|
||||
example-lib
|
||||
├── .python-version
|
||||
├── README.md
|
||||
├── pyproject.toml
|
||||
└── src
|
||||
└── example_lib
|
||||
├── py.typed
|
||||
└── __init__.py
|
||||
```
|
||||
|
||||
When creating a library, uv defines a build system and places the source code in a `src` directory.
|
||||
These changes ensure that the library is isolated from any `python` invocations in the project root
|
||||
and that distributed library code is well separated from the rest of the project source code. The
|
||||
project includes a package at `src/example_lib` that will be built and installed into the project
|
||||
environment.
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "example-lib"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = []
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
uv does not provide a build backend yet. `hatchling` is used by default, but there are other
|
||||
options. You may need to use the [hatch build](https://hatch.pypa.io/1.9/config/build/) options
|
||||
to configure `hatchling` for your project structure.
|
||||
|
||||
Progress towards a uv build backend can be tracked in [astral-sh/uv#3957](https://github.com/astral-sh/uv/issues/3957).
|
||||
|
||||
The created module defines a simple API function:
|
||||
|
||||
```python title="__init__.py"
|
||||
def hello() -> str:
|
||||
return "Hello from example-lib!"
|
||||
```
|
||||
|
||||
And you can import and execute it using `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run --directory example-lib python -c "import example_lib; print(example_lib.hello())"
|
||||
Hello from example-lib!
|
||||
```
|
||||
|
||||
You can select a different build backend template by using `--build-backend` with `hatchling`,
|
||||
`flit-core`, `pdm-backend`, `setuptools`, `maturin`, or `scikit-build-core`.
|
||||
|
||||
```console
|
||||
$ uv init --lib --build-backend maturin example-lib
|
||||
$ tree example-lib
|
||||
example-lib
|
||||
├── .python-version
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── pyproject.toml
|
||||
└── src
|
||||
├── lib.rs
|
||||
└── example_lib
|
||||
├── py.typed
|
||||
├── __init__.py
|
||||
└── _core.pyi
|
||||
```
|
||||
|
||||
And you can import and execute it using `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run --directory example-lib python -c "import example_lib; print(example_lib.hello())"
|
||||
Hello from example-lib!
|
||||
```
|
||||
|
||||
!!! tip
|
||||
|
||||
Changes to `lib.rs` or `main.cpp` will require running `--reinstall` when using binary build
|
||||
backends such as `maturin` and `scikit-build-core`.
|
||||
|
||||
### Packaged applications
|
||||
|
||||
The `--package` flag can be passed to `uv init` to create a distributable application, e.g., if you
|
||||
want to publish a command-line interface via PyPI. uv will define a build backend for the project,
|
||||
include a `[project.scripts]` entrypoint, and install the project package into the project
|
||||
environment.
|
||||
|
||||
The project structure looks the same as a library:
|
||||
|
||||
```console
|
||||
$ uv init --app --package example-packaged-app
|
||||
$ tree example-packaged-app
|
||||
example-packaged-app
|
||||
├── .python-version
|
||||
├── README.md
|
||||
├── pyproject.toml
|
||||
└── src
|
||||
└── example_packaged_app
|
||||
└── __init__.py
|
||||
```
|
||||
|
||||
But the module defines a CLI function:
|
||||
|
||||
```python title="__init__.py"
|
||||
def main() -> None:
|
||||
print("Hello from example-packaged-app!")
|
||||
```
|
||||
|
||||
And the `pyproject.toml` includes a script entrypoint:
|
||||
|
||||
```toml title="pyproject.toml" hl_lines="9 10"
|
||||
[project]
|
||||
name = "example-packaged-app"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = []
|
||||
|
||||
[project.scripts]
|
||||
example-packaged-app = "example_packaged_app:main"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
```
|
||||
|
||||
Which can be executed with `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run --directory example-packaged-app example-packaged-app
|
||||
Hello from example-packaged-app!
|
||||
```
|
||||
|
||||
!!! tip
|
||||
|
||||
An existing application can be redefined as a distributable package by adding a build system.
|
||||
However, this may require changes to the project directory structure, depending on the build
|
||||
backend.
|
||||
|
||||
In addition, you can further customize the build backend of a packaged application by specifying
|
||||
`--build-backend` including binary build backends such as `maturin`.
|
||||
|
||||
```console
|
||||
$ uv init --app --package --build-backend maturin example-packaged-app
|
||||
$ tree example-packaged-app
|
||||
example-packaged-app
|
||||
├── .python-version
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── pyproject.toml
|
||||
└── src
|
||||
├── lib.rs
|
||||
└── example_packaged_app
|
||||
├── __init__.py
|
||||
└── _core.pyi
|
||||
```
|
||||
|
||||
Which can also be executed with `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run --directory example-packaged-app example-packaged-app
|
||||
Hello from example-packaged-app!
|
||||
```
|
||||
|
||||
## Project environments
|
||||
|
||||
When working on a project with uv, uv will create a virtual environment as needed. While some uv
|
||||
commands will create a temporary environment (e.g., `uv run --isolated`), uv also manages a
|
||||
persistent environment with the project and its dependencies in a `.venv` directory next to the
|
||||
`pyproject.toml`. It is stored inside the project to make it easy for editors to find — they need
|
||||
the environment to give code completions and type hints. It is not recommended to include the
|
||||
`.venv` directory in version control; it is automatically excluded from `git` with an internal
|
||||
`.gitignore` file.
|
||||
|
||||
To run a command in the project environment, use `uv run`. Alternatively the project environment can
|
||||
be activated as normal for a virtual environment.
|
||||
|
||||
When `uv run` is invoked, it will create the project environment if it does not exist yet or ensure
|
||||
it is up-to-date if it exists. The project environment can also be explicitly created with
|
||||
`uv sync`.
|
||||
|
||||
It is _not_ recommended to modify the project environment manually, e.g., with `uv pip install`. For
|
||||
project dependencies, use `uv add` to add a package to the environment. For one-off requirements,
|
||||
use [`uvx`](../guides/tools.md) or
|
||||
[`uv run --with`](#running-commands-with-additional-dependencies).
|
||||
|
||||
!!! tip
|
||||
|
||||
If you don't want uv to manage the project environment, set [`managed = false`](../reference/settings.md#managed)
|
||||
to disable automatic locking and syncing of the project. For example:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[tool.uv]
|
||||
managed = false
|
||||
```
|
||||
|
||||
By default, the project will be installed in editable mode, such that changes to the source code are
|
||||
immediately reflected in the environment. `uv sync` and `uv run` both accept a `--no-editable` flag,
|
||||
which instructs uv to install the project in non-editable mode. `--no-editable` is intended for
|
||||
deployment use-cases, such as building a Docker container, in which the project should be included
|
||||
in the deployed environment without a dependency on the originating source code.
|
||||
|
||||
### Configuring the project environment path
|
||||
|
||||
The `UV_PROJECT_ENVIRONMENT` environment variable can be used to configure the project virtual
|
||||
environment path (`.venv` by default).
|
||||
|
||||
If a relative path is provided, it will be resolved relative to the workspace root. If an absolute
|
||||
path is provided, it will be used as-is, i.e. a child directory will not be created for the
|
||||
environment. If an environment is not present at the provided path, uv will create it.
|
||||
|
||||
This option can be used to write to the system Python environment, though it is not recommended.
|
||||
`uv sync` will remove extraneous packages from the environment by default and, as such, may leave
|
||||
the system in a broken state.
|
||||
|
||||
!!! important
|
||||
|
||||
If an absolute path is provided and the setting is used across multiple projects, the
|
||||
environment will be overwritten by invocations in each project. This setting is only recommended
|
||||
for use for a single project in CI or Docker images.
|
||||
|
||||
!!! note
|
||||
|
||||
uv does not read the `VIRTUAL_ENV` environment variable during project operations. A warning
|
||||
will be displayed if `VIRTUAL_ENV` is set to a different path than the project's environment.
|
||||
|
||||
## Project lockfile
|
||||
|
||||
uv creates a `uv.lock` file next to the `pyproject.toml`.
|
||||
|
||||
`uv.lock` is a _universal_ or _cross-platform_ lockfile that captures the packages that would be
|
||||
installed across all possible Python markers such as operating system, architecture, and Python
|
||||
version.
|
||||
|
||||
Unlike the `pyproject.toml`, which is used to specify the broad requirements of your project, the
|
||||
lockfile contains the exact resolved versions that are installed in the project environment. This
|
||||
file should be checked into version control, allowing for consistent and reproducible installations
|
||||
across machines.
|
||||
|
||||
A lockfile ensures that developers working on the project are using a consistent set of package
|
||||
versions. Additionally, it ensures when deploying the project as an application that the exact set
|
||||
of used package versions is known.
|
||||
|
||||
The lockfile is created and updated during uv invocations that use the project environment, i.e.,
|
||||
`uv sync` and `uv run`. The lockfile may also be explicitly updated using `uv lock`.
|
||||
|
||||
`uv.lock` is a human-readable TOML file but is managed by uv and should not be edited manually.
|
||||
There is no Python standard for lockfiles at this time, so the format of this file is specific to uv
|
||||
and not usable by other tools.
|
||||
|
||||
!!! tip
|
||||
|
||||
If you need to integrate uv with other tools or workflows, you can export `uv.lock` to `requirements.txt` format
|
||||
with `uv export --format requirements-txt`. The generated `requirements.txt` file can then be installed via
|
||||
`uv pip install`, or with other tools like `pip`.
|
||||
|
||||
In general, we recommend against using both a `uv.lock` and a `requirements.txt` file. If you find yourself
|
||||
exporting a `uv.lock` file, consider opening an issue to discuss your use case.
|
||||
|
||||
### Checking if the lockfile is up-to-date
|
||||
|
||||
To avoid updating the lockfile during `uv sync` and `uv run` invocations, use the `--frozen` flag.
|
||||
|
||||
To avoid updating the environment during `uv run` invocations, use the `--no-sync` flag.
|
||||
|
||||
To assert the lockfile matches the project metadata, use the `--locked` flag. If the lockfile is not
|
||||
up-to-date, an error will be raised instead of updating the lockfile.
|
||||
|
||||
### Upgrading locked package versions
|
||||
|
||||
By default, uv will prefer the locked versions of packages when running `uv sync` and `uv lock`.
|
||||
Package versions will only change if the project's dependency constraints exclude the previous,
|
||||
locked version.
|
||||
|
||||
To upgrade all packages:
|
||||
|
||||
```console
|
||||
$ uv lock --upgrade
|
||||
```
|
||||
|
||||
To upgrade a single package to the latest version, while retaining the locked versions of all other
|
||||
packages:
|
||||
|
||||
```console
|
||||
$ uv lock --upgrade-package <package>
|
||||
```
|
||||
|
||||
To upgrade a single package to a specific version:
|
||||
|
||||
```console
|
||||
$ uv lock --upgrade-package <package>==<version>
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
In all cases, upgrades are limited to the project's dependency constraints. For example, if the
|
||||
project defines an upper bound for a package then an upgrade will not go beyond that version.
|
||||
|
||||
### Limited resolution environments
|
||||
|
||||
If your project supports a more limited set of platforms or Python versions, you can constrain the
|
||||
set of solved platforms via the `environments` setting, which accepts a list of PEP 508 environment
|
||||
markers. For example, to constrain the lockfile to macOS and Linux, and exclude Windows:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[tool.uv]
|
||||
environments = [
|
||||
"sys_platform == 'darwin'",
|
||||
"sys_platform == 'linux'",
|
||||
]
|
||||
```
|
||||
|
||||
Entries in the `environments` setting must be disjoint (i.e., they must not overlap). For example,
|
||||
`sys_platform == 'darwin'` and `sys_platform == 'linux'` are disjoint, but
|
||||
`sys_platform == 'darwin'` and `python_version >= '3.9'` are not, since both could be true at the
|
||||
same time.
|
||||
|
||||
### Optional dependencies
|
||||
|
||||
uv requires that all optional dependencies ("extras") declared by the project are compatible with
|
||||
each other and resolves all optional dependencies together when creating the lockfile.
|
||||
|
||||
If optional dependencies declared in one extra are not compatible with those in another extra, uv
|
||||
will fail to resolve the requirements of the project with an error.
|
||||
|
||||
To work around this, uv supports declaring conflicting extras. For example, consider two sets of
|
||||
optional dependencies that conflict with one another:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project.optional-dependencies]
|
||||
extra1 = ["numpy==2.1.2"]
|
||||
extra2 = ["numpy==2.0.0"]
|
||||
```
|
||||
|
||||
If you run `uv lock` with the above dependencies, resolution will fail:
|
||||
|
||||
```console
|
||||
$ uv lock
|
||||
x No solution found when resolving dependencies:
|
||||
`-> Because myproject[extra2] depends on numpy==2.0.0 and myproject[extra1] depends on numpy==2.1.2, we can conclude that myproject[extra1] and
|
||||
myproject[extra2] are incompatible.
|
||||
And because your project requires myproject[extra1] and myproject[extra2], we can conclude that your projects's requirements are unsatisfiable.
|
||||
```
|
||||
|
||||
But if you specify that `extra1` and `extra2` are conflicting, uv will resolve them separately.
|
||||
Specify conflicts in the `tool.uv` section:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[tool.uv]
|
||||
conflicts = [
|
||||
[
|
||||
{ extra = "extra1" },
|
||||
{ extra = "extra2" },
|
||||
],
|
||||
]
|
||||
```
|
||||
|
||||
Now, running `uv lock` will succeed. Note though, that now you cannot install both `extra1` and
|
||||
`extra2` at the same time:
|
||||
|
||||
```console
|
||||
$ uv sync --extra extra1 --extra extra2
|
||||
Resolved 3 packages in 14ms
|
||||
error: extra `extra1`, extra `extra2` are incompatible with the declared conflicts: {`myproject[extra1]`, `myproject[extra2]`}
|
||||
```
|
||||
|
||||
This error occurs because installing both `extra1` and `extra2` would result in installing two
|
||||
different versions of a package into the same environment.
|
||||
|
||||
The above strategy for dealing with conflicting extras also works with dependency groups:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[dependency-groups]
|
||||
group1 = ["numpy==2.1.2"]
|
||||
group2 = ["numpy==2.0.0"]
|
||||
|
||||
[tool.uv]
|
||||
conflicts = [
|
||||
[
|
||||
{ group = "group1" },
|
||||
{ group = "group2" },
|
||||
],
|
||||
]
|
||||
```
|
||||
|
||||
The only difference with conflicting extras is that you need to use `group` instead of `extra`.
|
||||
|
||||
## Managing dependencies
|
||||
|
||||
uv is capable of adding, updating, and removing dependencies using the CLI.
|
||||
|
||||
To add a dependency:
|
||||
|
||||
```console
|
||||
$ 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.
|
||||
|
||||
uv will raise an error if the dependency cannot be resolved, e.g.:
|
||||
|
||||
```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.
|
||||
```
|
||||
|
||||
To remove a dependency:
|
||||
|
||||
```console
|
||||
$ uv remove httpx
|
||||
```
|
||||
|
||||
To update an existing dependency, e.g., to add a lower bound to the `httpx` version:
|
||||
|
||||
```console
|
||||
$ 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 <name>`, e.g.:
|
||||
|
||||
```console
|
||||
$ uv add 'httpx>0.1.0' --upgrade-package httpx
|
||||
```
|
||||
|
||||
See the [lockfile](#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'
|
||||
```
|
||||
|
||||
To add a dependency source, e.g., to use `httpx` from GitHub during development:
|
||||
|
||||
```console
|
||||
$ uv add git+https://github.com/encode/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.
|
||||
|
||||
For example, to install `jax` on Linux, but not on Windows or macOS:
|
||||
|
||||
```console
|
||||
$ uv add 'jax; sys_platform == "linux"'
|
||||
```
|
||||
|
||||
The resulting `pyproject.toml` will then include the environment marker in the dependency
|
||||
definition:
|
||||
|
||||
```toml title="pyproject.toml" hl_lines="6"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = ["jax; sys_platform == 'linux'"]
|
||||
```
|
||||
|
||||
Similarly, to include `numpy` on Python 3.11 and later:
|
||||
|
||||
```console
|
||||
$ 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.
|
||||
|
||||
## Running commands
|
||||
|
||||
When working on a project, it is installed into virtual environment at `.venv`. This environment is
|
||||
isolated from the current shell by default, so invocations that require the project, e.g.,
|
||||
`python -c "import example"`, will fail. Instead, use `uv run` to run commands in the project
|
||||
environment:
|
||||
|
||||
```console
|
||||
$ uv run python -c "import example"
|
||||
```
|
||||
|
||||
When using `run`, uv will ensure that the project environment is up-to-date before running the given
|
||||
command.
|
||||
|
||||
The given command can be provided by the project environment or exist outside of it, e.g.:
|
||||
|
||||
```console
|
||||
$ # Presuming the project provides `example-cli`
|
||||
$ uv run example-cli foo
|
||||
|
||||
$ # Running a `bash` script that requires the project to be available
|
||||
$ uv run bash scripts/foo.sh
|
||||
```
|
||||
|
||||
### Running commands with additional dependencies
|
||||
|
||||
Additional dependencies or different versions of dependencies can be requested per invocation.
|
||||
|
||||
The `--with` option is used to include a dependency for the invocation, e.g., to request a different
|
||||
version of `httpx`:
|
||||
|
||||
```console
|
||||
$ uv run --with httpx==0.26.0 python -c "import httpx; print(httpx.__version__)"
|
||||
0.26.0
|
||||
$ uv run --with httpx==0.25.0 python -c "import httpx; print(httpx.__version__)"
|
||||
0.25.0
|
||||
```
|
||||
|
||||
The requested version will be respected regardless of the project's requirements. For example, even
|
||||
if the project requires `httpx==0.24.0`, the output above would be the same.
|
||||
|
||||
### Running scripts
|
||||
|
||||
Scripts that declare inline metadata are automatically executed in environments isolated from the
|
||||
project. See the [scripts guide](../guides/scripts.md#declaring-script-dependencies) for more
|
||||
details.
|
||||
|
||||
For example, given a script:
|
||||
|
||||
```python title="example.py"
|
||||
# /// script
|
||||
# dependencies = [
|
||||
# "httpx",
|
||||
# ]
|
||||
# ///
|
||||
|
||||
import httpx
|
||||
|
||||
resp = httpx.get("https://peps.python.org/api/peps.json")
|
||||
data = resp.json()
|
||||
print([(k, v["title"]) for k, v in data.items()][:10])
|
||||
```
|
||||
|
||||
The invocation `uv run example.py` would run _isolated_ from the project with only the given
|
||||
dependencies listed.
|
||||
|
||||
## Projects with many packages
|
||||
|
||||
If working in a project composed of many packages, see the [workspaces](./workspaces.md)
|
||||
documentation.
|
||||
|
||||
## Building projects
|
||||
|
||||
To distribute your project to others (e.g., to upload it to an index like PyPI), you'll need to
|
||||
build it into a distributable format.
|
||||
|
||||
Python projects are typically distributed as both source distributions (sdists) and binary
|
||||
distributions (wheels). The former is typically a `.tar.gz` or `.zip` file containing the project's
|
||||
source code along with some additional metadata, while the latter is a `.whl` file containing
|
||||
pre-built artifacts that can be installed directly.
|
||||
|
||||
`uv build` can be used to build both source distributions and binary distributions for your project.
|
||||
By default, `uv build` will build the project in the current directory, and place the built
|
||||
artifacts in a `dist/` subdirectory:
|
||||
|
||||
```console
|
||||
$ uv build
|
||||
$ ls dist/
|
||||
example-0.1.0-py3-none-any.whl
|
||||
example-0.1.0.tar.gz
|
||||
```
|
||||
|
||||
You can build the project in a different directory by providing a path to `uv build`, e.g.,
|
||||
`uv build path/to/project`.
|
||||
|
||||
`uv build` will first build a source distribution, and then build a binary distribution (wheel) from
|
||||
that source distribution.
|
||||
|
||||
You can limit `uv build` to building a source distribution with `uv build --sdist`, a binary
|
||||
distribution with `uv build --wheel`, or build both distributions from source with
|
||||
`uv build --sdist --wheel`.
|
||||
|
||||
`uv build` accepts `--build-constraint`, which can be used to constrain the versions of any build
|
||||
requirements during the build process. When coupled with `--require-hashes`, uv will enforce that
|
||||
the requirement used to build the project match specific, known hashes, for reproducibility.
|
||||
|
||||
For example, given the following `constraints.txt`:
|
||||
|
||||
```text
|
||||
setuptools==68.2.2 --hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
|
||||
```
|
||||
|
||||
Running the following would build the project with the specified version of `setuptools`, and verify
|
||||
that the downloaded `setuptools` distribution matches the specified hash:
|
||||
|
||||
```console
|
||||
$ uv build --build-constraint constraints.txt --require-hashes
|
||||
```
|
||||
|
||||
## Build isolation
|
||||
|
||||
By default, uv builds all packages in isolated virtual environments, as per
|
||||
[PEP 517](https://peps.python.org/pep-0517/). Some packages are incompatible with build isolation,
|
||||
be it intentionally (e.g., due to the use of heavy build dependencies, mostly commonly PyTorch) or
|
||||
unintentionally (e.g., due to the use of legacy packaging setups).
|
||||
|
||||
To disable build isolation for a specific dependency, add it to the `no-build-isolation-package`
|
||||
list in your `pyproject.toml`:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
description = "..."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["cchardet"]
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["cchardet"]
|
||||
```
|
||||
|
||||
Installing packages without build isolation requires that the package's build dependencies are
|
||||
installed in the project environment _prior_ to installing the package itself. This can be achieved
|
||||
by separating out the build dependencies and the packages that require them into distinct extras.
|
||||
For example:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
description = "..."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[project.optional-dependencies]
|
||||
build = ["setuptools", "cython"]
|
||||
compile = ["cchardet"]
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["cchardet"]
|
||||
```
|
||||
|
||||
Given the above, a user would first sync the `build` dependencies:
|
||||
|
||||
```console
|
||||
$ uv sync --extra build
|
||||
+ cython==3.0.11
|
||||
+ foo==0.1.0 (from file:///Users/crmarsh/workspace/uv/foo)
|
||||
+ setuptools==73.0.1
|
||||
```
|
||||
|
||||
Followed by the `compile` dependencies:
|
||||
|
||||
```console
|
||||
$ uv sync --extra compile
|
||||
+ cchardet==2.1.7
|
||||
- cython==3.0.11
|
||||
- setuptools==73.0.1
|
||||
```
|
||||
|
||||
Note that `uv sync --extra compile` would, by default, uninstall the `cython` and `setuptools`
|
||||
packages. To instead retain the build dependencies, include both extras in the second `uv sync`
|
||||
invocation:
|
||||
|
||||
```console
|
||||
$ uv sync --extra build
|
||||
$ uv sync --extra build --extra compile
|
||||
```
|
||||
|
||||
Some packages, like `cchardet` above, only require build dependencies for the _installation_ phase
|
||||
of `uv sync`. Others, like `flash-attn`, require their build dependencies to be present even just to
|
||||
resolve the project's lockfile during the _resolution_ phase.
|
||||
|
||||
In such cases, the build dependencies must be installed prior to running any `uv lock` or `uv sync`
|
||||
commands, using the lower lower-level `uv pip` API. For example, given:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
description = "..."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["flash-attn"]
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["flash-attn"]
|
||||
```
|
||||
|
||||
You could run the following sequence of commands to sync `flash-attn`:
|
||||
|
||||
```console
|
||||
$ uv venv
|
||||
$ uv pip install torch
|
||||
$ uv sync
|
||||
```
|
||||
|
||||
Alternatively, you can provide the `flash-attn` metadata upfront via the
|
||||
[`dependency-metadata`](../reference/settings.md#dependency-metadata) setting, thereby forgoing the
|
||||
need to build the package during the dependency resolution phase. For example, to provide the
|
||||
`flash-attn` metadata upfront, include the following in your `pyproject.toml`:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[[tool.uv.dependency-metadata]]
|
||||
name = "flash-attn"
|
||||
version = "2.6.3"
|
||||
requires-dist = ["torch", "einops"]
|
||||
```
|
||||
|
||||
!!! tip
|
||||
|
||||
To determine the package metadata for a package like `flash-attn`, navigate to the appropriate Git repository,
|
||||
or look it up on [PyPI](https://pypi.org/project/flash-attn) and download the package's source distribution.
|
||||
The package requirements can typically be found in the `setup.py` or `setup.cfg` file.
|
||||
|
||||
(If the package includes a built distribution, you can unzip it to find the `METADATA` file; however, the presence
|
||||
of a built distribution would negate the need to provide the metadata upfront, since it would already be available
|
||||
to uv.)
|
||||
|
||||
Once included, you can again use the two-step `uv sync` process to install the build dependencies.
|
||||
Given the following `pyproject.toml`:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
description = "..."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[project.optional-dependencies]
|
||||
build = ["torch", "setuptools", "packaging"]
|
||||
compile = ["flash-attn"]
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["flash-attn"]
|
||||
|
||||
[[tool.uv.dependency-metadata]]
|
||||
name = "flash-attn"
|
||||
version = "2.6.3"
|
||||
requires-dist = ["torch", "einops"]
|
||||
```
|
||||
|
||||
You could run the following sequence of commands to sync `flash-attn`:
|
||||
|
||||
```console
|
||||
$ uv sync --extra build
|
||||
$ uv sync --extra build --extra compile
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
The `version` field in `tool.uv.dependency-metadata` is optional for registry-based
|
||||
dependencies (when omitted, uv will assume the metadata applies to all versions of the package),
|
||||
but _required_ for direct URL dependencies (like Git dependencies).
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# Building distributions
|
||||
|
||||
To distribute your project to others (e.g., to upload it to an index like PyPI), you'll need to
|
||||
build it into a distributable format.
|
||||
|
||||
Python projects are typically distributed as both source distributions (sdists) and binary
|
||||
distributions (wheels). The former is typically a `.tar.gz` or `.zip` file containing the project's
|
||||
source code along with some additional metadata, while the latter is a `.whl` file containing
|
||||
pre-built artifacts that can be installed directly.
|
||||
|
||||
## Using `uv build`
|
||||
|
||||
`uv build` can be used to build both source distributions and binary distributions for your project.
|
||||
By default, `uv build` will build the project in the current directory, and place the built
|
||||
artifacts in a `dist/` subdirectory:
|
||||
|
||||
```console
|
||||
$ uv build
|
||||
$ ls dist/
|
||||
example-0.1.0-py3-none-any.whl
|
||||
example-0.1.0.tar.gz
|
||||
```
|
||||
|
||||
You can build the project in a different directory by providing a path to `uv build`, e.g.,
|
||||
`uv build path/to/project`.
|
||||
|
||||
`uv build` will first build a source distribution, and then build a binary distribution (wheel) from
|
||||
that source distribution.
|
||||
|
||||
You can limit `uv build` to building a source distribution with `uv build --sdist`, a binary
|
||||
distribution with `uv build --wheel`, or build both distributions from source with
|
||||
`uv build --sdist --wheel`.
|
||||
|
||||
## Build constraints
|
||||
|
||||
`uv build` accepts `--build-constraint`, which can be used to constrain the versions of any build
|
||||
requirements during the build process. When coupled with `--require-hashes`, uv will enforce that
|
||||
the requirement used to build the project match specific, known hashes, for reproducibility.
|
||||
|
||||
For example, given the following `constraints.txt`:
|
||||
|
||||
```text
|
||||
setuptools==68.2.2 --hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
|
||||
```
|
||||
|
||||
Running the following would build the project with the specified version of `setuptools`, and verify
|
||||
that the downloaded `setuptools` distribution matches the specified hash:
|
||||
|
||||
```console
|
||||
$ uv build --build-constraint constraints.txt --require-hashes
|
||||
```
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
# Configuring projects
|
||||
|
||||
## Entry points
|
||||
|
||||
uv uses the standard `[project.scripts]` table to define entry points for the project.
|
||||
|
||||
For example, to declare a command called `hello` that invokes the `hello` function in the
|
||||
`example_package_app` module:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project.scripts]
|
||||
hello = "example_package_app:hello"
|
||||
```
|
||||
|
||||
!!! important
|
||||
|
||||
Using `[project.scripts]` requires a [build system](#build-systems) to be defined.
|
||||
|
||||
## Build systems
|
||||
|
||||
Projects _may_ define a `[build-system]` in the `pyproject.toml`. The build system defines how the
|
||||
project should be packaged and installed.
|
||||
|
||||
uv uses the presence of a build system to determine if a project contains a package that should be
|
||||
installed in the project virtual environment. If a build system is not defined, uv will not attempt
|
||||
to build or install the project itself, just its dependencies. If a build system is defined, uv will
|
||||
build and install the project into the project environment. By default, projects are installed in
|
||||
[editable mode](https://setuptools.pypa.io/en/latest/userguide/development_mode.html) so changes to
|
||||
the source code are reflected immediately, without re-installation.
|
||||
|
||||
## Project packaging
|
||||
|
||||
While uv usually uses the declaration of a [build system](#build-systems) to determine if a project
|
||||
should be packaged, uv also allows overriding this behavior with the
|
||||
[`tool.uv.package`](../../reference/settings.md#package) setting.
|
||||
|
||||
Setting `tool.uv.package = true` will force a project to be built and installed into the project
|
||||
environment. If no build system is defined, uv will use the setuptools legacy backend.
|
||||
|
||||
Setting `tool.uv.package = false` will force a project package _not_ to be built and installed into
|
||||
the project environment. uv will ignore a declared build system when interacting with the project.
|
||||
|
||||
## Project environment path
|
||||
|
||||
The `UV_PROJECT_ENVIRONMENT` environment variable can be used to configure the project virtual
|
||||
environment path (`.venv` by default).
|
||||
|
||||
If a relative path is provided, it will be resolved relative to the workspace root. If an absolute
|
||||
path is provided, it will be used as-is, i.e. a child directory will not be created for the
|
||||
environment. If an environment is not present at the provided path, uv will create it.
|
||||
|
||||
This option can be used to write to the system Python environment, though it is not recommended.
|
||||
`uv sync` will remove extraneous packages from the environment by default and, as such, may leave
|
||||
the system in a broken state.
|
||||
|
||||
!!! important
|
||||
|
||||
If an absolute path is provided and the setting is used across multiple projects, the
|
||||
environment will be overwritten by invocations in each project. This setting is only recommended
|
||||
for use for a single project in CI or Docker images.
|
||||
|
||||
!!! note
|
||||
|
||||
uv does not read the `VIRTUAL_ENV` environment variable during project operations. A warning
|
||||
will be displayed if `VIRTUAL_ENV` is set to a different path than the project's environment.
|
||||
|
||||
## Limited resolution environments
|
||||
|
||||
If your project supports a more limited set of platforms or Python versions, you can constrain the
|
||||
set of solved platforms via the `environments` setting, which accepts a list of PEP 508 environment
|
||||
markers. For example, to constrain the lockfile to macOS and Linux, and exclude Windows:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[tool.uv]
|
||||
environments = [
|
||||
"sys_platform == 'darwin'",
|
||||
"sys_platform == 'linux'",
|
||||
]
|
||||
```
|
||||
|
||||
Entries in the `environments` setting must be disjoint (i.e., they must not overlap). For example,
|
||||
`sys_platform == 'darwin'` and `sys_platform == 'linux'` are disjoint, but
|
||||
`sys_platform == 'darwin'` and `python_version >= '3.9'` are not, since both could be true at the
|
||||
same time.
|
||||
|
||||
## Build isolation
|
||||
|
||||
By default, uv builds all packages in isolated virtual environments, as per
|
||||
[PEP 517](https://peps.python.org/pep-0517/). Some packages are incompatible with build isolation,
|
||||
be it intentionally (e.g., due to the use of heavy build dependencies, mostly commonly PyTorch) or
|
||||
unintentionally (e.g., due to the use of legacy packaging setups).
|
||||
|
||||
To disable build isolation for a specific dependency, add it to the `no-build-isolation-package`
|
||||
list in your `pyproject.toml`:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
description = "..."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["cchardet"]
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["cchardet"]
|
||||
```
|
||||
|
||||
Installing packages without build isolation requires that the package's build dependencies are
|
||||
installed in the project environment _prior_ to installing the package itself. This can be achieved
|
||||
by separating out the build dependencies and the packages that require them into distinct extras.
|
||||
For example:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
description = "..."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[project.optional-dependencies]
|
||||
build = ["setuptools", "cython"]
|
||||
compile = ["cchardet"]
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["cchardet"]
|
||||
```
|
||||
|
||||
Given the above, a user would first sync the `build` dependencies:
|
||||
|
||||
```console
|
||||
$ uv sync --extra build
|
||||
+ cython==3.0.11
|
||||
+ foo==0.1.0 (from file:///Users/crmarsh/workspace/uv/foo)
|
||||
+ setuptools==73.0.1
|
||||
```
|
||||
|
||||
Followed by the `compile` dependencies:
|
||||
|
||||
```console
|
||||
$ uv sync --extra compile
|
||||
+ cchardet==2.1.7
|
||||
- cython==3.0.11
|
||||
- setuptools==73.0.1
|
||||
```
|
||||
|
||||
Note that `uv sync --extra compile` would, by default, uninstall the `cython` and `setuptools`
|
||||
packages. To instead retain the build dependencies, include both extras in the second `uv sync`
|
||||
invocation:
|
||||
|
||||
```console
|
||||
$ uv sync --extra build
|
||||
$ uv sync --extra build --extra compile
|
||||
```
|
||||
|
||||
Some packages, like `cchardet` above, only require build dependencies for the _installation_ phase
|
||||
of `uv sync`. Others, like `flash-attn`, require their build dependencies to be present even just to
|
||||
resolve the project's lockfile during the _resolution_ phase.
|
||||
|
||||
In such cases, the build dependencies must be installed prior to running any `uv lock` or `uv sync`
|
||||
commands, using the lower lower-level `uv pip` API. For example, given:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
description = "..."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["flash-attn"]
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["flash-attn"]
|
||||
```
|
||||
|
||||
You could run the following sequence of commands to sync `flash-attn`:
|
||||
|
||||
```console
|
||||
$ uv venv
|
||||
$ uv pip install torch
|
||||
$ uv sync
|
||||
```
|
||||
|
||||
Alternatively, you can provide the `flash-attn` metadata upfront via the
|
||||
[`dependency-metadata`](../../reference/settings.md#dependency-metadata) setting, thereby forgoing
|
||||
the need to build the package during the dependency resolution phase. For example, to provide the
|
||||
`flash-attn` metadata upfront, include the following in your `pyproject.toml`:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[[tool.uv.dependency-metadata]]
|
||||
name = "flash-attn"
|
||||
version = "2.6.3"
|
||||
requires-dist = ["torch", "einops"]
|
||||
```
|
||||
|
||||
!!! tip
|
||||
|
||||
To determine the package metadata for a package like `flash-attn`, navigate to the appropriate Git repository,
|
||||
or look it up on [PyPI](https://pypi.org/project/flash-attn) and download the package's source distribution.
|
||||
The package requirements can typically be found in the `setup.py` or `setup.cfg` file.
|
||||
|
||||
(If the package includes a built distribution, you can unzip it to find the `METADATA` file; however, the presence
|
||||
of a built distribution would negate the need to provide the metadata upfront, since it would already be available
|
||||
to uv.)
|
||||
|
||||
Once included, you can again use the two-step `uv sync` process to install the build dependencies.
|
||||
Given the following `pyproject.toml`:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
description = "..."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[project.optional-dependencies]
|
||||
build = ["torch", "setuptools", "packaging"]
|
||||
compile = ["flash-attn"]
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["flash-attn"]
|
||||
|
||||
[[tool.uv.dependency-metadata]]
|
||||
name = "flash-attn"
|
||||
version = "2.6.3"
|
||||
requires-dist = ["torch", "einops"]
|
||||
```
|
||||
|
||||
You could run the following sequence of commands to sync `flash-attn`:
|
||||
|
||||
```console
|
||||
$ uv sync --extra build
|
||||
$ uv sync --extra build --extra compile
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
The `version` field in `tool.uv.dependency-metadata` is optional for registry-based
|
||||
dependencies (when omitted, uv will assume the metadata applies to all versions of the package),
|
||||
but _required_ for direct URL dependencies (like Git dependencies).
|
||||
|
||||
## Editable mode
|
||||
|
||||
By default, the project will be installed in editable mode, such that changes to the source code are
|
||||
immediately reflected in the environment. `uv sync` and `uv run` both accept a `--no-editable` flag,
|
||||
which instructs uv to install the project in non-editable mode. `--no-editable` is intended for
|
||||
deployment use-cases, such as building a Docker container, in which the project should be included
|
||||
in the deployed environment without a dependency on the originating source code.
|
||||
|
||||
### Conflicting dependencies
|
||||
|
||||
uv requires that all optional dependencies ("extras") declared by the project are compatible with
|
||||
each other and resolves all optional dependencies together when creating the lockfile.
|
||||
|
||||
If optional dependencies declared in one extra are not compatible with those in another extra, uv
|
||||
will fail to resolve the requirements of the project with an error.
|
||||
|
||||
To work around this, uv supports declaring conflicting extras. For example, consider two sets of
|
||||
optional dependencies that conflict with one another:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project.optional-dependencies]
|
||||
extra1 = ["numpy==2.1.2"]
|
||||
extra2 = ["numpy==2.0.0"]
|
||||
```
|
||||
|
||||
If you run `uv lock` with the above dependencies, resolution will fail:
|
||||
|
||||
```console
|
||||
$ uv lock
|
||||
x No solution found when resolving dependencies:
|
||||
`-> Because myproject[extra2] depends on numpy==2.0.0 and myproject[extra1] depends on numpy==2.1.2, we can conclude that myproject[extra1] and
|
||||
myproject[extra2] are incompatible.
|
||||
And because your project requires myproject[extra1] and myproject[extra2], we can conclude that your projects's requirements are unsatisfiable.
|
||||
```
|
||||
|
||||
But if you specify that `extra1` and `extra2` are conflicting, uv will resolve them separately.
|
||||
Specify conflicts in the `tool.uv` section:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[tool.uv]
|
||||
conflicts = [
|
||||
[
|
||||
{ extra = "extra1" },
|
||||
{ extra = "extra2" },
|
||||
],
|
||||
]
|
||||
```
|
||||
|
||||
Now, running `uv lock` will succeed. Note though, that now you cannot install both `extra1` and
|
||||
`extra2` at the same time:
|
||||
|
||||
```console
|
||||
$ uv sync --extra extra1 --extra extra2
|
||||
Resolved 3 packages in 14ms
|
||||
error: extra `extra1`, extra `extra2` are incompatible with the declared conflicts: {`myproject[extra1]`, `myproject[extra2]`}
|
||||
```
|
||||
|
||||
This error occurs because installing both `extra1` and `extra2` would result in installing two
|
||||
different versions of a package into the same environment.
|
||||
|
||||
The above strategy for dealing with conflicting extras also works with dependency groups:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[dependency-groups]
|
||||
group1 = ["numpy==2.1.2"]
|
||||
group2 = ["numpy==2.0.0"]
|
||||
|
||||
[tool.uv]
|
||||
conflicts = [
|
||||
[
|
||||
{ group = "group1" },
|
||||
{ group = "group2" },
|
||||
],
|
||||
]
|
||||
```
|
||||
|
||||
The only difference with conflicting extras is that you need to use `group` instead of `extra`.
|
||||
|
|
@ -1,4 +1,104 @@
|
|||
# Specifying dependencies
|
||||
# Managing dependencies
|
||||
|
||||
uv is capable of adding, updating, and removing dependencies using the CLI.
|
||||
|
||||
## Adding dependencies
|
||||
|
||||
To add a dependency:
|
||||
|
||||
```console
|
||||
$ 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.
|
||||
|
||||
uv will raise an error if the dependency cannot be resolved, e.g.:
|
||||
|
||||
```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.
|
||||
```
|
||||
|
||||
## Removing dependencies
|
||||
|
||||
To remove a dependency:
|
||||
|
||||
```console
|
||||
$ uv remove httpx
|
||||
```
|
||||
|
||||
## Updating dependencies
|
||||
|
||||
To update an existing dependency, e.g., to add a lower bound to the `httpx` version:
|
||||
|
||||
```console
|
||||
$ 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 <name>`, 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'
|
||||
```
|
||||
|
||||
To add a dependency source, e.g., to use `httpx` from GitHub during development:
|
||||
|
||||
```console
|
||||
$ uv add git+https://github.com/encode/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.
|
||||
|
||||
For example, to install `jax` on Linux, but not on Windows or macOS:
|
||||
|
||||
```console
|
||||
$ uv add 'jax; sys_platform == "linux"'
|
||||
```
|
||||
|
||||
The resulting `pyproject.toml` will then include the environment marker in the dependency
|
||||
definition:
|
||||
|
||||
```toml title="pyproject.toml" hl_lines="6"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = ["jax; sys_platform == 'linux'"]
|
||||
```
|
||||
|
||||
Similarly, to include `numpy` on Python 3.11 and later:
|
||||
|
||||
```console
|
||||
$ 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`.
|
||||
|
|
@ -61,11 +161,6 @@ sufficient. If the project depends on packages from Git, remote URLs, or local s
|
|||
`tool.uv.sources` can be used to enrich the dependency metadata without ejecting from the
|
||||
standards-compliant `project.dependencies` table.
|
||||
|
||||
!!! tip
|
||||
|
||||
See the [projects](./projects.md#managing-dependencies) documentation to add, remove, or update
|
||||
dependencies from the `pyproject.toml` from the CLI.
|
||||
|
||||
## Dependency sources
|
||||
|
||||
During development, a project may rely on a package that isn't available on PyPI. The following
|
||||
|
|
@ -190,7 +285,7 @@ A `subdirectory` may be specified if the package isn't in the repository root.
|
|||
|
||||
To add a URL source, provide a `https://` URL to either a wheel (ending in `.whl`) or a source
|
||||
distribution (typically ending in `.tar.gz` or `.zip`; see
|
||||
[here](../concepts/resolution.md#source-distribution) for all supported formats).
|
||||
[here](../../concepts/resolution.md#source-distribution) for all supported formats).
|
||||
|
||||
For example:
|
||||
|
||||
|
|
@ -217,8 +312,9 @@ archive root.
|
|||
### Path
|
||||
|
||||
To add a path source, provide the path of a wheel (ending in `.whl`), a source distribution
|
||||
(typically ending in `.tar.gz` or `.zip`; see [here](../concepts/resolution.md#source-distribution)
|
||||
for all supported formats), or a directory containing a `pyproject.toml`.
|
||||
(typically ending in `.tar.gz` or `.zip`; see
|
||||
[here](../../concepts/resolution.md#source-distribution) for all supported formats), or a directory
|
||||
containing a `pyproject.toml`.
|
||||
|
||||
For example:
|
||||
|
||||
|
|
@ -391,7 +487,7 @@ $ uv add httpx --optional network
|
|||
!!! note
|
||||
|
||||
If you have optional dependencies that conflict with one another, resolution will fail
|
||||
unless you explicitly [declare them as conflicting](./projects.md#optional-dependencies).
|
||||
unless you explicitly [declare them as conflicting](./config.md#conflicting-dependencies).
|
||||
|
||||
Sources can also be declared as applying only to a specific optional dependency. For example, to
|
||||
pull `torch` from different PyTorch indexes based on an optional `cpu` or `gpu` extra:
|
||||
|
|
@ -490,7 +586,7 @@ to resolve the requirements of the project with an error.
|
|||
!!! note
|
||||
|
||||
If you have dependency groups that conflict with one another, resolution will fail
|
||||
unless you explicitly [declare them as conflicting](./projects.md#optional-dependencies).
|
||||
unless you explicitly [declare them as conflicting](./config.md#conflicting-dependencies).
|
||||
|
||||
### Default groups
|
||||
|
||||
|
|
@ -528,7 +624,7 @@ Dependencies declared in this section will be combined with the contents in the
|
|||
|
||||
## Build dependencies
|
||||
|
||||
If a project is structured as [Python package](./projects.md#build-systems), it may declare
|
||||
If a project is structured as [Python package](./config.md#build-systems), it may declare
|
||||
dependencies that are required to build the project, but not required to run it. These dependencies
|
||||
are specified in the `[build-system]` table under `build-system.requires`, following
|
||||
[PEP 518](https://peps.python.org/pep-0518/).
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Projects
|
||||
|
||||
Projects help manage Python code spanning multiple files.
|
||||
|
||||
!!! tip
|
||||
|
||||
Looking for an introduction to creating a project with uv? See the [projects guide](../../guides/projects.md) first.
|
||||
|
||||
Working on projects is a core part of the uv experience. Learn more about using projects:
|
||||
|
||||
- [Understanding project structure and files](./layout.md)
|
||||
- [Creating new projects](./init.md)
|
||||
- [Managing project dependencies](./dependencies.md)
|
||||
- [Running commands and scripts in a project](./run.md)
|
||||
- [Using lockfiles and syncing the environment](./sync.md)
|
||||
- [Configuring the project for advanced use cases](./config.md)
|
||||
- [Building distributions to publish a project](./build.md)
|
||||
- [Using workspaces to work on multiple projects at once](./workspaces.md)
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
# Creating projects
|
||||
|
||||
uv supports creating a project with `uv init`.
|
||||
|
||||
uv will create a project in the working directory, or, in a target directory by providing a name,
|
||||
e.g., `uv init foo`. If there's already a project in the target directory, i.e., there's a
|
||||
`pyproject.toml`, uv will exit with an error.
|
||||
|
||||
When creating projects, uv distinguishes between two types: [**applications**](#applications) and
|
||||
[**libraries**](#libraries).
|
||||
|
||||
By default, uv will create a project for an application. The `--lib` flag can be used to create a
|
||||
project for a library instead.
|
||||
|
||||
### Applications
|
||||
|
||||
Application projects are suitable for web servers, scripts, and command-line interfaces.
|
||||
|
||||
Applications are the default target for `uv init`, but can also be specified with the `--app` flag:
|
||||
|
||||
```console
|
||||
$ uv init --app example-app
|
||||
$ tree example-app
|
||||
example-app
|
||||
├── .python-version
|
||||
├── README.md
|
||||
├── hello.py
|
||||
└── pyproject.toml
|
||||
```
|
||||
|
||||
When creating an application, uv will generate a minimal `pyproject.toml`. A build system is not
|
||||
defined and the source code is in the top-level directory, e.g., `hello.py`. The project does not
|
||||
contain a package that will be built and installed into the project environment.
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "example-app"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = []
|
||||
```
|
||||
|
||||
The created script defines a `main` function with some standard boilerplate:
|
||||
|
||||
```python title="hello.py"
|
||||
def main():
|
||||
print("Hello from example-app!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
And can be executed with `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run hello.py
|
||||
Hello from example-project!
|
||||
```
|
||||
|
||||
### Libraries
|
||||
|
||||
A library is a project that is intended to be built and distributed as a Python package, for
|
||||
example, by uploading it to PyPI. A library provides functions and objects for other projects to
|
||||
consume.
|
||||
|
||||
Libraries can be created by using the `--lib` flag:
|
||||
|
||||
```console
|
||||
$ uv init --lib example-lib
|
||||
$ tree example-lib
|
||||
example-lib
|
||||
├── .python-version
|
||||
├── README.md
|
||||
├── pyproject.toml
|
||||
└── src
|
||||
└── example_lib
|
||||
├── py.typed
|
||||
└── __init__.py
|
||||
```
|
||||
|
||||
When creating a library, uv defines a build system and places the source code in a `src` directory.
|
||||
These changes ensure that the library is isolated from any `python` invocations in the project root
|
||||
and that distributed library code is well separated from the rest of the project source code. The
|
||||
project includes a package at `src/example_lib` that will be built and installed into the project
|
||||
environment.
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "example-lib"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = []
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
uv does not provide a build backend yet. `hatchling` is used by default, but there are other
|
||||
options. You may need to use the [hatch build](https://hatch.pypa.io/1.9/config/build/) options
|
||||
to configure `hatchling` for your project structure.
|
||||
|
||||
Progress towards a uv build backend can be tracked in [astral-sh/uv#3957](https://github.com/astral-sh/uv/issues/3957).
|
||||
|
||||
The created module defines a simple API function:
|
||||
|
||||
```python title="__init__.py"
|
||||
def hello() -> str:
|
||||
return "Hello from example-lib!"
|
||||
```
|
||||
|
||||
And you can import and execute it using `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run --directory example-lib python -c "import example_lib; print(example_lib.hello())"
|
||||
Hello from example-lib!
|
||||
```
|
||||
|
||||
You can select a different build backend template by using `--build-backend` with `hatchling`,
|
||||
`flit-core`, `pdm-backend`, `setuptools`, `maturin`, or `scikit-build-core`.
|
||||
|
||||
```console
|
||||
$ uv init --lib --build-backend maturin example-lib
|
||||
$ tree example-lib
|
||||
example-lib
|
||||
├── .python-version
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── pyproject.toml
|
||||
└── src
|
||||
├── lib.rs
|
||||
└── example_lib
|
||||
├── py.typed
|
||||
├── __init__.py
|
||||
└── _core.pyi
|
||||
```
|
||||
|
||||
And you can import and execute it using `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run --directory example-lib python -c "import example_lib; print(example_lib.hello())"
|
||||
Hello from example-lib!
|
||||
```
|
||||
|
||||
!!! tip
|
||||
|
||||
Changes to `lib.rs` or `main.cpp` will require running `--reinstall` when using binary build
|
||||
backends such as `maturin` and `scikit-build-core`.
|
||||
|
||||
### Packaged applications
|
||||
|
||||
The `--package` flag can be passed to `uv init` to create a distributable application, e.g., if you
|
||||
want to publish a command-line interface via PyPI. uv will define a build backend for the project,
|
||||
include a `[project.scripts]` entrypoint, and install the project package into the project
|
||||
environment.
|
||||
|
||||
The project structure looks the same as a library:
|
||||
|
||||
```console
|
||||
$ uv init --app --package example-packaged-app
|
||||
$ tree example-packaged-app
|
||||
example-packaged-app
|
||||
├── .python-version
|
||||
├── README.md
|
||||
├── pyproject.toml
|
||||
└── src
|
||||
└── example_packaged_app
|
||||
└── __init__.py
|
||||
```
|
||||
|
||||
But the module defines a CLI function:
|
||||
|
||||
```python title="__init__.py"
|
||||
def main() -> None:
|
||||
print("Hello from example-packaged-app!")
|
||||
```
|
||||
|
||||
And the `pyproject.toml` includes a script entrypoint:
|
||||
|
||||
```toml title="pyproject.toml" hl_lines="9 10"
|
||||
[project]
|
||||
name = "example-packaged-app"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = []
|
||||
|
||||
[project.scripts]
|
||||
example-packaged-app = "example_packaged_app:main"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
```
|
||||
|
||||
Which can be executed with `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run --directory example-packaged-app example-packaged-app
|
||||
Hello from example-packaged-app!
|
||||
```
|
||||
|
||||
!!! tip
|
||||
|
||||
An existing application can be redefined as a distributable package by adding a build system.
|
||||
However, this may require changes to the project directory structure, depending on the build
|
||||
backend.
|
||||
|
||||
In addition, you can further customize the build backend of a packaged application by specifying
|
||||
`--build-backend` including binary build backends such as `maturin`.
|
||||
|
||||
```console
|
||||
$ uv init --app --package --build-backend maturin example-packaged-app
|
||||
$ tree example-packaged-app
|
||||
example-packaged-app
|
||||
├── .python-version
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── pyproject.toml
|
||||
└── src
|
||||
├── lib.rs
|
||||
└── example_packaged_app
|
||||
├── __init__.py
|
||||
└── _core.pyi
|
||||
```
|
||||
|
||||
Which can also be executed with `uv run`:
|
||||
|
||||
```console
|
||||
$ uv run --directory example-packaged-app example-packaged-app
|
||||
Hello from example-packaged-app!
|
||||
```
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
# Project structure and files
|
||||
|
||||
## The `pyproject.toml`
|
||||
|
||||
Python project metadata is defined in a `pyproject.toml` file. uv requires this file to identify the
|
||||
root directory of a project.
|
||||
|
||||
!!! tip
|
||||
|
||||
`uv init` can be used to create a new project. See [Creating projects](./init.md) for
|
||||
details.
|
||||
|
||||
A minimal project definition includes a name, version, and description:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[project]
|
||||
name = "example"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
```
|
||||
|
||||
It's recommended, but not required, to include a Python version requirement in the `[project]`
|
||||
section:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
requires-python = ">=3.12"
|
||||
```
|
||||
|
||||
Including a Python version requirement defines the Python syntax that is allowed in the project and
|
||||
affects selection of dependency versions (they must support the same Python version range).
|
||||
|
||||
The `pyproject.toml` also lists dependencies of the project in the `project.dependencies` and
|
||||
`project.optional-dependencies` fields. uv supports modifying the project's dependencies from the
|
||||
command line with `uv add` and `uv remove`. uv also supports extending the standard dependency
|
||||
definitions with [package sources](./dependencies.md) in `tool.uv.sources`.
|
||||
|
||||
!!! tip
|
||||
|
||||
See the official [`pyproject.toml` guide](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/) for more details on getting started with a `pyproject.toml`.
|
||||
|
||||
## The project environment
|
||||
|
||||
When working on a project with uv, uv will create a virtual environment as needed. While some uv
|
||||
commands will create a temporary environment (e.g., `uv run --isolated`), uv also manages a
|
||||
persistent environment with the project and its dependencies in a `.venv` directory next to the
|
||||
`pyproject.toml`. It is stored inside the project to make it easy for editors to find — they need
|
||||
the environment to give code completions and type hints. It is not recommended to include the
|
||||
`.venv` directory in version control; it is automatically excluded from `git` with an internal
|
||||
`.gitignore` file.
|
||||
|
||||
To run a command in the project environment, use `uv run`. Alternatively the project environment can
|
||||
be activated as normal for a virtual environment.
|
||||
|
||||
When `uv run` is invoked, it will create the project environment if it does not exist yet or ensure
|
||||
it is up-to-date if it exists. The project environment can also be explicitly created with
|
||||
`uv sync`.
|
||||
|
||||
It is _not_ recommended to modify the project environment manually, e.g., with `uv pip install`. For
|
||||
project dependencies, use `uv add` to add a package to the environment. For one-off requirements,
|
||||
use [`uvx`](../../guides/tools.md) or
|
||||
[`uv run --with`](./run.md#requesting-additional-dependencies).
|
||||
|
||||
!!! tip
|
||||
|
||||
If you don't want uv to manage the project environment, set [`managed = false`](../../reference/settings.md#managed)
|
||||
to disable automatic locking and syncing of the project. For example:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[tool.uv]
|
||||
managed = false
|
||||
```
|
||||
|
||||
## The lockfile
|
||||
|
||||
uv creates a `uv.lock` file next to the `pyproject.toml`.
|
||||
|
||||
`uv.lock` is a _universal_ or _cross-platform_ lockfile that captures the packages that would be
|
||||
installed across all possible Python markers such as operating system, architecture, and Python
|
||||
version.
|
||||
|
||||
Unlike the `pyproject.toml`, which is used to specify the broad requirements of your project, the
|
||||
lockfile contains the exact resolved versions that are installed in the project environment. This
|
||||
file should be checked into version control, allowing for consistent and reproducible installations
|
||||
across machines.
|
||||
|
||||
A lockfile ensures that developers working on the project are using a consistent set of package
|
||||
versions. Additionally, it ensures when deploying the project as an application that the exact set
|
||||
of used package versions is known.
|
||||
|
||||
The lockfile is created and updated during uv invocations that use the project environment, i.e.,
|
||||
`uv sync` and `uv run`. The lockfile may also be explicitly updated using `uv lock`.
|
||||
|
||||
`uv.lock` is a human-readable TOML file but is managed by uv and should not be edited manually.
|
||||
There is no Python standard for lockfiles at this time, so the format of this file is specific to uv
|
||||
and not usable by other tools.
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# Running commands in projects
|
||||
|
||||
When working on a project, it is installed into virtual environment at `.venv`. This environment is
|
||||
isolated from the current shell by default, so invocations that require the project, e.g.,
|
||||
`python -c "import example"`, will fail. Instead, use `uv run` to run commands in the project
|
||||
environment:
|
||||
|
||||
```console
|
||||
$ uv run python -c "import example"
|
||||
```
|
||||
|
||||
When using `run`, uv will ensure that the project environment is up-to-date before running the given
|
||||
command.
|
||||
|
||||
The given command can be provided by the project environment or exist outside of it, e.g.:
|
||||
|
||||
```console
|
||||
$ # Presuming the project provides `example-cli`
|
||||
$ uv run example-cli foo
|
||||
|
||||
$ # Running a `bash` script that requires the project to be available
|
||||
$ uv run bash scripts/foo.sh
|
||||
```
|
||||
|
||||
## Requesting additional dependencies
|
||||
|
||||
Additional dependencies or different versions of dependencies can be requested per invocation.
|
||||
|
||||
The `--with` option is used to include a dependency for the invocation, e.g., to request a different
|
||||
version of `httpx`:
|
||||
|
||||
```console
|
||||
$ uv run --with httpx==0.26.0 python -c "import httpx; print(httpx.__version__)"
|
||||
0.26.0
|
||||
$ uv run --with httpx==0.25.0 python -c "import httpx; print(httpx.__version__)"
|
||||
0.25.0
|
||||
```
|
||||
|
||||
The requested version will be respected regardless of the project's requirements. For example, even
|
||||
if the project requires `httpx==0.24.0`, the output above would be the same.
|
||||
|
||||
## Running scripts
|
||||
|
||||
Scripts that declare inline metadata are automatically executed in environments isolated from the
|
||||
project. See the [scripts guide](../../guides/scripts.md#declaring-script-dependencies) for more
|
||||
details.
|
||||
|
||||
For example, given a script:
|
||||
|
||||
```python title="example.py"
|
||||
# /// script
|
||||
# dependencies = [
|
||||
# "httpx",
|
||||
# ]
|
||||
# ///
|
||||
|
||||
import httpx
|
||||
|
||||
resp = httpx.get("https://peps.python.org/api/peps.json")
|
||||
data = resp.json()
|
||||
print([(k, v["title"]) for k, v in data.items()][:10])
|
||||
```
|
||||
|
||||
The invocation `uv run example.py` would run _isolated_ from the project with only the given
|
||||
dependencies listed.
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# Locking and syncing
|
||||
|
||||
### Creating the lockfile
|
||||
|
||||
The lockfile is created and updated during uv invocations that use the project environment, i.e.,
|
||||
`uv sync` and `uv run`. The lockfile may also be explicitly created or updated using `uv lock`:
|
||||
|
||||
```console
|
||||
$ uv lock
|
||||
```
|
||||
|
||||
### Exporting the lockfile
|
||||
|
||||
If you need to integrate uv with other tools or workflows, you can export `uv.lock` to
|
||||
`requirements.txt` format with `uv export --format requirements-txt`. The generated
|
||||
`requirements.txt` file can then be installed via `uv pip install`, or with other tools like `pip`.
|
||||
|
||||
In general, we recommend against using both a `uv.lock` and a `requirements.txt` file. If you find
|
||||
yourself exporting a `uv.lock` file, consider opening an issue to discuss your use case.
|
||||
|
||||
### Checking if the lockfile is up-to-date
|
||||
|
||||
To avoid updating the lockfile during `uv sync` and `uv run` invocations, use the `--frozen` flag.
|
||||
|
||||
To avoid updating the environment during `uv run` invocations, use the `--no-sync` flag.
|
||||
|
||||
To assert the lockfile matches the project metadata, use the `--locked` flag. If the lockfile is not
|
||||
up-to-date, an error will be raised instead of updating the lockfile.
|
||||
|
||||
### Upgrading locked package versions
|
||||
|
||||
By default, uv will prefer the locked versions of packages when running `uv sync` and `uv lock`.
|
||||
Package versions will only change if the project's dependency constraints exclude the previous,
|
||||
locked version.
|
||||
|
||||
To upgrade all packages:
|
||||
|
||||
```console
|
||||
$ uv lock --upgrade
|
||||
```
|
||||
|
||||
To upgrade a single package to the latest version, while retaining the locked versions of all other
|
||||
packages:
|
||||
|
||||
```console
|
||||
$ uv lock --upgrade-package <package>
|
||||
```
|
||||
|
||||
To upgrade a single package to a specific version:
|
||||
|
||||
```console
|
||||
$ uv lock --upgrade-package <package>==<version>
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
In all cases, upgrades are limited to the project's dependency constraints. For example, if the
|
||||
project defines an upper bound for a package then an upgrade will not go beyond that version.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Workspaces
|
||||
# Using workspaces
|
||||
|
||||
Inspired by the [Cargo](https://doc.rust-lang.org/cargo/reference/workspaces.html) concept of the
|
||||
same name, a workspace is "a collection of one or more packages, called _workspace members_, that
|
||||
|
|
@ -49,8 +49,8 @@ build-backend = "hatchling.build"
|
|||
|
||||
Every directory included by the `members` globs (and not excluded by the `exclude` globs) must
|
||||
contain a `pyproject.toml` file. However, workspace members can be _either_
|
||||
[applications](./projects.md#applications) or [libraries](./projects.md#libraries); both are
|
||||
supported in the workspace context.
|
||||
[applications](./init.md#applications) or [libraries](./init.md#libraries); both are supported in
|
||||
the workspace context.
|
||||
|
||||
Every workspace needs a root, which is _also_ a workspace member. In the above example, `albatross`
|
||||
is the workspace root, and the workspace members include all projects under the `packages`
|
||||
|
|
@ -86,7 +86,7 @@ uv supports both [platform-specific](#platform-specific-resolution) and
|
|||
uv's lockfile (`uv.lock`) is created with a universal resolution and is portable across platforms.
|
||||
This ensures that dependencies are locked for everyone working on the project, regardless of
|
||||
operating system, architecture, and Python version. The uv lockfile is created and modified by
|
||||
[project](../concepts/projects.md) commands such as `uv lock`, `uv sync`, and `uv add`.
|
||||
[project](../concepts/projects/index.md) commands such as `uv lock`, `uv sync`, and `uv add`.
|
||||
|
||||
universal resolution is also available in uv's pip interface, i.e.,
|
||||
[`uv pip compile`](../pip/compile.md), with the `--universal` flag. The resulting requirements file
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ Equivalent to the `--preview` argument. Enables preview mode.
|
|||
### `UV_PROJECT_ENVIRONMENT`
|
||||
|
||||
Specifies the path to the directory to use for a project virtual environment.
|
||||
See the [project documentation](../concepts/projects.md#configuring-the-project-environment-path)
|
||||
See the [project documentation](../concepts/projects/config.md#project-environment-path)
|
||||
for more details.
|
||||
|
||||
### `UV_PUBLISH_CHECK_URL`
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ uv is supported by [Renovate](https://github.com/renovatebot/renovate).
|
|||
|
||||
Renovate uses the presence of a `uv.lock` file to determine that uv is used for managing
|
||||
dependencies, and will suggest upgrades to
|
||||
[project dependencies](../../concepts/dependencies.md#project-dependencies),
|
||||
[optional dependencies](../../concepts/dependencies.md#optional-dependencies) and
|
||||
[development dependencies](../../concepts/dependencies.md#development-dependencies). Renovate will
|
||||
update both the `pyproject.toml` and `uv.lock` files.
|
||||
[project dependencies](../../concepts/projects/dependencies.md#project-dependencies),
|
||||
[optional dependencies](../../concepts/projects/dependencies.md#optional-dependencies) and
|
||||
[development dependencies](../../concepts/projects/dependencies.md#development-dependencies).
|
||||
Renovate will update both the `pyproject.toml` and `uv.lock` files.
|
||||
|
||||
The lockfile can also be refreshed on a regular basis (for instance to update transitive
|
||||
dependencies) by enabling the
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ RUN uv run some_script.py
|
|||
!!! tip
|
||||
|
||||
Alternatively, the
|
||||
[`UV_PROJECT_ENVIRONMENT` setting](../../concepts/projects.md#configuring-the-project-environment-path) can
|
||||
[`UV_PROJECT_ENVIRONMENT` setting](../../concepts/projects/config.md#project-environment-path) can
|
||||
be set before syncing to install to the system Python environment and skip environment activation
|
||||
entirely.
|
||||
|
||||
|
|
@ -366,7 +366,7 @@ _contents_ are not copied into the image until the final `uv sync` command.
|
|||
|
||||
!!! tip
|
||||
|
||||
If you're using a [workspace](../../concepts/workspaces.md), then use the
|
||||
If you're using a [workspace](../../concepts/projects/workspaces.md), then use the
|
||||
`--no-install-workspace` flag which excludes the project _and_ any workspace members.
|
||||
|
||||
If you want to remove specific packages from the sync, use `--no-install-package <name>`.
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ To use uv with this application, inside the `project` directory run:
|
|||
$ uv init --app
|
||||
```
|
||||
|
||||
This creates an [Application project](../../concepts/projects.md#applications) with a
|
||||
`pyproject.toml` file.
|
||||
This creates an [project with an application layout](../../concepts/projects/init.md#applications)
|
||||
and a `pyproject.toml` file.
|
||||
|
||||
Then, add a dependency on FastAPI:
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ jobs:
|
|||
!!! tip
|
||||
|
||||
The
|
||||
[`UV_PROJECT_ENVIRONMENT` setting](../../concepts/projects.md#configuring-the-project-environment-path) can
|
||||
[`UV_PROJECT_ENVIRONMENT` setting](../../concepts/projects/config.md#project-environment-path) can
|
||||
be used to install to the system Python environment instead of creating a virtual environment.
|
||||
|
||||
## Caching
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ with a project, or as a standalone tool.
|
|||
|
||||
## Using Jupyter within a project
|
||||
|
||||
If you're working within a [project](../../concepts/projects.md), you can start a Jupyter server
|
||||
with access to the project's virtual environment via the following:
|
||||
If you're working within a [project](../../concepts/projects/index.md), you can start a Jupyter
|
||||
server with access to the project's virtual environment via the following:
|
||||
|
||||
```console
|
||||
$ uv run --with jupyter jupyter lab
|
||||
|
|
@ -96,8 +96,8 @@ an isolated environment.
|
|||
## Using Jupyter with a non-project environment
|
||||
|
||||
If you need to run Jupyter in a virtual environment that isn't associated with a
|
||||
[project](../../concepts/projects.md) (e.g., has no `pyproject.toml` or `uv.lock`), you can do so by
|
||||
adding Jupyter to the environment directly. For example:
|
||||
[project](../../concepts/projects/index.md) (e.g., has no `pyproject.toml` or `uv.lock`), you can do
|
||||
so by adding Jupyter to the environment directly. For example:
|
||||
|
||||
```console
|
||||
$ uv venv --seed
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ Python version to use when creating the project's virtual environment.
|
|||
The `.venv` folder contains your project's virtual environment, a Python environment that is
|
||||
isolated from the rest of your system. This is where uv will install your project's dependencies.
|
||||
|
||||
See the [project environment](../concepts/projects.md#project-environments) documentation for more
|
||||
details.
|
||||
See the [project environment](../concepts/projects/layout.md#the-project-environment) documentation
|
||||
for more details.
|
||||
|
||||
### `uv.lock`
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ reproducible installations across machines.
|
|||
|
||||
`uv.lock` is a human-readable TOML file but is managed by uv and should not be edited manually.
|
||||
|
||||
See the [lockfile](../concepts/projects.md#project-lockfile) documentation for more details.
|
||||
See the [lockfile](../concepts/projects/layout.md#the-lockfile) documentation for more details.
|
||||
|
||||
## Managing dependencies
|
||||
|
||||
|
|
@ -142,8 +142,8 @@ $ uv lock --upgrade-package requests
|
|||
The `--upgrade-package` flag will attempt to update the specified package to the latest compatible
|
||||
version, while keeping the rest of the lockfile intact.
|
||||
|
||||
See the documentation on [managing dependencies](../concepts/projects.md#managing-dependencies) for
|
||||
more details.
|
||||
See the documentation on [managing dependencies](../concepts/projects/dependencies.md) for more
|
||||
details.
|
||||
|
||||
## Running commands
|
||||
|
||||
|
|
@ -188,8 +188,8 @@ $ python example.py
|
|||
|
||||
The virtual environment must be active to run scripts and commands in the project without `uv run`. Virtual environment activation differs per shell and platform.
|
||||
|
||||
See the documentation on [running commands](../concepts/projects.md#running-commands) and
|
||||
[running scripts](../concepts/projects.md#running-scripts) in projects for more details.
|
||||
See the documentation on [running commands and scripts](../concepts/projects/run.md) in projects for
|
||||
more details.
|
||||
|
||||
## Building distributions
|
||||
|
||||
|
|
@ -206,12 +206,12 @@ hello-world-0.1.0-py3-none-any.whl
|
|||
hello-world-0.1.0.tar.gz
|
||||
```
|
||||
|
||||
See the documentation on [building projects](../concepts/projects.md#building-projects) for more
|
||||
details.
|
||||
See the documentation on [building projects](../concepts/projects/build.md) for more details.
|
||||
|
||||
## Next steps
|
||||
|
||||
To learn more about working on projects with uv, see the [Projects concept](../concepts/projects.md)
|
||||
page and the [command reference](../reference/cli.md#uv).
|
||||
To learn more about working on projects with uv, see the
|
||||
[projects concept](../concepts/projects/index.md) page and the
|
||||
[command reference](../reference/cli.md#uv).
|
||||
|
||||
Or, read on to learn how to [publish your project as a package](./publish.md).
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ distribution.
|
|||
If your project does not include a `[build-system]` definition in the `pyproject.toml`, uv will not
|
||||
build it by default. This means that your project may not be ready for distribution. Read more about
|
||||
the effect of declaring a build system in the
|
||||
[project concept](../concepts/projects.md#build-systems) documentation.
|
||||
[project concept](../concepts/projects/config.md#build-systems) documentation.
|
||||
|
||||
!!! note
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ $ uv run example.py
|
|||
|
||||
!!! important
|
||||
|
||||
When using inline script metadata, even if `uv run` is [used in a _project_](../concepts/projects.md#running-scripts), the project's dependencies will be ignored. The `--no-project` flag is not required.
|
||||
When using inline script metadata, even if `uv run` is [used in a _project_](../concepts/projects/run.md), the project's dependencies will be ignored. The `--no-project` flag is not required.
|
||||
|
||||
uv also respects Python version requirements:
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ Tools are installed into temporary, isolated environments when using `uvx`.
|
|||
|
||||
!!! note
|
||||
|
||||
If you are running a tool in a [_project_](../concepts/projects.md) and the tool requires that
|
||||
If you are running a tool in a [_project_](../concepts/projects/index.md) and the tool requires that
|
||||
your project is installed, e.g., when using `pytest` or `mypy`, you'll want to use
|
||||
[`uv run`](./projects.md#running-commands) instead of `uvx`. Otherwise, the tool will be run in
|
||||
a virtual environment that is isolated from your project.
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ An extremely fast Python package and project manager, written in Rust.
|
|||
- ❇️ [Runs scripts](#script-support), with support for
|
||||
[inline dependency metadata](./guides/scripts.md#declaring-script-dependencies).
|
||||
- 🗂️ Provides [comprehensive project management](#project-management), with a
|
||||
[universal lockfile](./concepts/projects.md#project-lockfile).
|
||||
[universal lockfile](./concepts/projects/layout.md#the-lockfile).
|
||||
- 🔩 Includes a [pip-compatible interface](#the-pip-interface) for a performance boost with a
|
||||
familiar CLI.
|
||||
- 🏢 Supports Cargo-style [workspaces](./concepts/workspaces.md) for scalable projects.
|
||||
- 🏢 Supports Cargo-style [workspaces](./concepts/projects/workspaces.md) for scalable projects.
|
||||
- 💾 Disk-space efficient, with a [global cache](./concepts/cache.md) for dependency deduplication.
|
||||
- ⏬ Installable without Rust or Python via `curl` or `pip`.
|
||||
- 🖥️ Supports macOS, Linux, and Windows.
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ The sources to use when resolving dependencies.
|
|||
during development. A dependency source can be a Git repository, a URL, a local path, or an
|
||||
alternative registry.
|
||||
|
||||
See [Dependencies](../concepts/dependencies.md) for more.
|
||||
See [Dependencies](../concepts/projects/dependencies.md) for more.
|
||||
|
||||
**Default value**: `{}`
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ mkdocs-material @ git+ssh://git@github.com/astral-sh/mkdocs-material-insiders.gi
|
|||
# -r docs/requirements.in
|
||||
mkdocs-material-extensions==1.3.1
|
||||
# via mkdocs-material
|
||||
mkdocs-redirects==1.2.1
|
||||
mkdocs-redirects==1.2.2
|
||||
# via -r docs/requirements.in
|
||||
more-itertools==10.3.0
|
||||
# via mdformat-mkdocs
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ mkdocs-redirects>=1.2.1
|
|||
mdformat>=0.7.17
|
||||
mdformat-mkdocs>=2.0.4
|
||||
mdformat-admon>=2.0.2
|
||||
mkdocs-redirects>=1.2.2
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ mkdocs-material==9.5.29
|
|||
# via -r docs/requirements.in
|
||||
mkdocs-material-extensions==1.3.1
|
||||
# via mkdocs-material
|
||||
mkdocs-redirects==1.2.1
|
||||
mkdocs-redirects==1.2.2
|
||||
# via -r docs/requirements.in
|
||||
more-itertools==10.3.0
|
||||
# via mdformat-mkdocs
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ markdown_extensions:
|
|||
alternate_style: true
|
||||
plugins:
|
||||
- search
|
||||
- redirects:
|
||||
redirect_maps:
|
||||
"concepts/workspaces.md": "concepts/projects/workspaces.md"
|
||||
"concepts/dependencies.md": "concepts/projects/dependencies.md"
|
||||
extra_css:
|
||||
- stylesheets/extra.css
|
||||
extra_javascript:
|
||||
|
|
@ -94,9 +98,16 @@ nav:
|
|||
- Publishing packages: guides/publish.md
|
||||
- Concepts:
|
||||
- concepts/index.md
|
||||
- Projects: concepts/projects.md
|
||||
- Dependencies: concepts/dependencies.md
|
||||
- Workspaces: concepts/workspaces.md
|
||||
- Projects:
|
||||
- concepts/projects/index.md
|
||||
- Structure and files: concepts/projects/layout.md
|
||||
- Creating projects: concepts/projects/init.md
|
||||
- Managing dependencies: concepts/projects/dependencies.md
|
||||
- Running commands: concepts/projects/run.md
|
||||
- Locking and syncing: concepts/projects/sync.md
|
||||
- Configuring projects: concepts/projects/config.md
|
||||
- Building distributions: concepts/projects/build.md
|
||||
- Using workspaces: concepts/projects/workspaces.md
|
||||
- Tools: concepts/tools.md
|
||||
- Python versions: concepts/python-versions.md
|
||||
- Resolution: concepts/resolution.md
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@
|
|||
]
|
||||
},
|
||||
"sources": {
|
||||
"description": "The sources to use when resolving dependencies.\n\n`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.\n\nSee [Dependencies](https://docs.astral.sh/uv/concepts/dependencies/) for more.",
|
||||
"description": "The sources to use when resolving dependencies.\n\n`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.\n\nSee [Dependencies](https://docs.astral.sh/uv/concepts/projects/dependencies/) for more.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ToolUvSources"
|
||||
|
|
|
|||
Loading…
Reference in New Issue