diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee0943b17..74f86f34a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,7 @@ jobs: code: - "**/*" - "!docs/**/*" + - "!mkdocs.*.yml" - "!**/*.md" - "!bin/**" - "!assets/**" diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico index b247f569f..a7181b99e 100644 Binary files a/docs/assets/favicon.ico and b/docs/assets/favicon.ico differ diff --git a/docs/dependencies.md b/docs/dependencies.md new file mode 100644 index 000000000..2bca8321b --- /dev/null +++ b/docs/dependencies.md @@ -0,0 +1,185 @@ +# Specifying dependencies + +In uv, project dependency specification is divided between two `pyproject.toml` tables: `project.dependencies` and +`tool.uv.sources`. + +`project.dependencies` is used to define the standards-compliant dependency metadata, +propagated when uploading to PyPI or building a wheel. `tool.uv.sources` is used to specify the _sources_ +required to install the dependencies, which can come from a Git repository, a URL, a local path, a +different index, etc. This metadata must be expressed separately because the `project.dependencies` standard does not allow these common patterns. + +## Project dependencies + +The `project.dependencies` table represents the dependencies that are used when uploading to PyPI or +building a wheel. Individual dependencies are specified using [PEP 508](#pep-508) syntax, and the table follows the [PEP 621](https://packaging.python.org/en/latest/specifications/pyproject-toml/) +standard. + +`project.dependencies` defines the packages that are required for the project, along with the version constraints that should be used when installing them. + +`project.dependencies` is structured as a list. Each entry includes a dependency name and +version. An entry may include extras or environment markers for platform-specific packages. For example: + +```toml +[project] +name = "albatross" +version = "0.1.0" +dependencies = [ + # Any version in this range + "tqdm >=4.66.2,<5", + # Exactly this version of torch + "torch ==2.2.2", + # Install transformers with the torch extra + "transformers[torch] >=4.39.3,<5", + # Only install this package on older python versions + # See "Environment Markers" for more information + "importlib_metadata >=7.1.0,<8; python_version < '3.10'", + "mollymawk ==0.1.0" +] +``` + +If the project only requires packages from standaard package indexes, then `project.dependencies` is sufficient. If, the project depends on packages from Git, remote URLs, or local sources, `tool.uv.sources` is needed. + +## Dependency sources + +During development, the project may rely on a package that isn't available on PyPI. In the following example, the project will require several package sources: + +- `tqdm` from a specific Git commit +- `importlib_metadata` from a dedicated URL +- `torch` from the PyTorch-specific index +- `mollymawk` from the current workspace + +These requirements can be expressed by extending the definitions in the `project.dependencies` table with `tool.uv.sources` entries: + +```toml +[project] +name = "albatross" +version = "0.1.0" +dependencies = [ + # Any version in this range. + "tqdm >=4.66.2,<5", + # Exactly this version of torch. + "torch ==2.2.2", + # Install transformers with the torch extra. + "transformers[torch] >=4.39.3,<5", + # Only install this package on Python versions prior to 3.10. + "importlib_metadata >=7.1.0,<8; python_version < '3.10'", + "mollymawk ==0.1.0" +] + +[tool.uv.sources] +# Install a specific Git commit. +tqdm = { git = "https://github.com/tqdm/tqdm", rev = "cc372d09dcd5a5eabdc6ed4cf365bdb0be004d44" } +# Install a remote source distribution (`.zip`, `.tar.gz`) or wheel (`.whl`). +importlib_metadata = { url = "https://github.com/python/importlib_metadata/archive/refs/tags/v7.1.0.zip" } +# Use a package included in the same workspace (as an editable installation). +mollymawk = { workspace = true } + +[tool.uv.workspace] +include = [ + "packages/mollymawk" +] +``` + +uv supports the following sources: + +- **Git**: `git = `. A git-compatible URL to clone. A target revision may be specified with one of: `rev`, `tag`, or `branch`. A `subdirectory` may be specified if the package isn't in the repository root. +- **URL**: `url = `. An `https://` URL to either a wheel (ending in `.whl`) or a source distribution + (ending in `.zip` or `.tar.gz`). A `subdirectory` may be specified if the if the source distribution isn't in the archive root. +- **Path**: `path = `. A path to a wheel (ending in `.whl`), a source + distribution (ending in `.zip` or `.tar.gz`), or a directory containing a `pyproject.toml`. + The path may be absolute or relative path. It is recommended to use _workspaces_ instead of manual path dependencies. For directories, `editable = true` may be specified for an [editable](#editables-dependencies) installation. +- **Workspace**: `workspace = true`. All workspace dependencies must be explicitly stated. Workspace dependencies are [editable](#editables-dependencies) by default; `editable = false` may be specified to install them as regular dependencies. See the [workspace](./workspaces.md) documentation for more details on workspaces. + +Only a single source may be defined for each dependency. + +Note that if a non-uv project uses this project as a Git- or path-dependency, only +`project.dependencies` is respected, the information in the source table +will need to be specified in a format specific to the other package manager. + +## Optional dependencies + +It is common for projects that are published as libraries to make some features optional to reduce the default dependency tree. For example, +Pandas has an [`excel` extra](https://pandas.pydata.org/docs/getting_started/install.html#excel-files) +and a [`plot` extra](https://pandas.pydata.org/docs/getting_started/install.html#visualization) to avoid installation of Excel parsers and `matplotlib` unless someone explicitly requires them. Extras are requested with the `package[]` syntax, e.g., `pandas[plot, excel]`. + +Optional dependencies are specified in `[project.optional-dependencies]`, a TOML table that maps +from extra name to its dependencies, following [PEP 508](#pep-508) syntax. + +Optional dependencies can have entries in `tool.uv.sources` the same as normal dependencies. + +```toml +[project] +name = "pandas" +version = "1.0.0" + +[project.optional-dependencies] +plot = [ + "matplotlib>=3.6.3" +] +excel = [ + "odfpy>=1.4.1", + "openpyxl>=3.1.0", + "python-calamine>=0.1.7", + "pyxlsb>=1.0.10", + "xlrd>=2.0.1", + "xlsxwriter>=3.0.5" +] +``` + +## Development dependencies + +Unlike optional dependencies, development dependencies are local-only and will _not_ be included in the project requirements when published to PyPI or other indexes. As such, development dependencies are included under `[tool.uv]` instead of `[project]`. + +Development dependencies can have entries in `tool.uv.sources` the same as normal dependencies. + +```toml +[tool.uv] +dev-dependencies = [ + "pytest >=8.1.1,<9" +] +``` + +## PEP 508 + +[PEP 508](https://peps.python.org/pep-0508/) defines a syntax for dependency specification. It is composed of, in order: + +- The dependency name +- The extras you want (optional) +- The version specifier +- An environment marker (optional) + +The version specifiers are comma separated and added together, e.g., `foo >=1.2.3,<2,!=1.4.0` is +interpreted as "a version of `foo` that's at least 1.2.3, but less than 2, and not 1.4.0". + +Specifiers are padded with trailing zeros if required, so `foo ==2` matches foo 2.0.0, too. + +A star can be used for the last digit with equals, e.g. `foo ==2.1.*` will accept any release from +the 2.1 series. Similarly, `~=` matches where the last digit is equal or higher, e.g., `foo ~=1.2` +is equal to `foo >=1.2,<2`, and `foo ~=1.2.3` is equal to `foo >=1.2.3,<1.3`. + +Extras are comma-separated in square bracket between name and version, e.g., `pandas[excel,plot] ==2.2`. Whitespace between extra names is ignored. + +Some dependencies are only required in specific environments, e.g., a specific Python version or +operating system. For example to install the `importlib-metadata` backport for the +`importlib.metadata` module, use `importlib-metadata >=7.1.0,<8; python_version < '3.10'`. +To install `colorama` on Windows (but omit it on other platforms), use +`colorama >=0.4.6,<5; platform_system == "Windows"`. + +Markers are combined with `and`, `or`, and parentheses, e.g., `aiohttp >=3.7.4,<4; (sys_platform != 'win32' or implementation_name != 'pypy') and python_version >= '3.10'`. +Note that versions within markers must be quoted, while versions _outside_ of markers must _not_ be +quoted. + +## Editable dependencies + +A regular installation of a directory with a Python package first builds a wheel and then installs +that wheel into your virtual environment, copying all source files. When the package source files are edited, +the virtual environment will contain outdated versions. + +Editable installations solve this problem by adding a link to the project within the virtual environment +(a `.pth` file), which instructs the interpreter to include the source files directly. + +There are some limitations to editables (mainly: the build backend needs to support them, and +native modules aren't recompiled before import), but they are useful for development, as the +virtual environment will always use the latest changes to the package. + +uv uses editable installation for workspace packages and patched dependencies by default. diff --git a/docs/features.md b/docs/features.md new file mode 100644 index 000000000..ec105addd --- /dev/null +++ b/docs/features.md @@ -0,0 +1,123 @@ + +# Feature overview + +uv supports the full Python development experience β€” from installing Python and hacking on simple scripts to working on large projects that support multiple Python versions and platforms. + +uv's commands can be broken down into sections of discrete features which can be used independently. + +## Python version management + +Installing and managing Python itself. + +- `uv python install` +- `uv python list` +- `uv python find` +- `uv python pin` +- `uv python uninstall` + +See the [guide on installing Python](./guides/install-python.md) to get started. + +## Running scripts + +Executing standalone Python scripts, e.g., `example.py`. + +- `uv run` + +See the [guide on running scripts](./guides/scripts.md) to get started. + +## Project management + +Creating and working on Python projects, i.e., with a `pyproject.toml`. + +- `uv init` +- `uv add` +- `uv remove` +- `uv sync` +- `uv lock` +- `uv run` +- `uv tree` + +See the [guide on projects](./guides/projects.md) to get started. + +## Tool installation + +Running and installing tools published to Python package indexes, e.g., `ruff` or `black`. + +- `uvx` / `uv tool run` +- `uv tool install` +- `uv tool uninstall` +- `uv tool list` +- `uv tool update-shell` + +See the [guide on tools](./guides/tools.md) to get started. + +## Low-level commands + +Manually managing environments and packages β€” intended to be used in legacy workflows or cases where the high-level commands do not provide enough control. + +Creating virtual environments (replacing `venv` and `virtualenv`): + +- `uv venv` + +See the documentation on [using environments](./pip/environments.md) for details. + +Managing packages in an environment (replacing [`pip`](https://github.com/pypa/pip)): + +- `uv pip install` +- `uv pip show` +- `uv pip freeze` +- `uv pip check` +- `uv pip list` +- `uv pip uninstall` + +See the documentation on [managing packages](./pip/packages.md) for details. + +Locking packages in an environment (replacing [`pip-tools`](https://github.com/jazzband/pip-tools)): + +- `uv pip compile` +- `uv pip sync` + +See the documentation on [locking environments](./pip/compile.md) for details. + +Viewing package dependencies in an environment (replacing [`pipdeptree`](https://github.com/tox-dev/pipdeptree)): + +- `uv pip tree` + +!!! important + + These commands do not exactly implement the interfaces and behavior of the tools they are based on. The further you stray from common workflows, the more likely you are to encounter differences. Consult the [pip-compatibility guide](./pip/compatibility.md) for details. + +## Internal commands + +Managing and inspecting uv's state, such as the cache, storage directories, or performing a self-update: + +- `uv cache clean` +- `uv cache prune` +- `uv cache dir` +- `uv tool dir` +- `uv python dir` +- `uv self update` + +## Next steps + +Check out one of our guides to get started: + +- [Installing Python](./guides/install-python.md) +- [Running scripts](./guides/scripts.md) +- [Using tools](./guides/tools.md) +- [Working on projects](./guides/projects.md) +- [Using in Docker](./guides/integration/docker.md) +- [Using with pre-commit](./guides/integration/pre-commit.md) +- [Using in GitHub Actions](./guides/integration/github.md) +- [Using with commercial package indexes](./guides/integration/commercial-indexes.md) + +Or, explore the concept documentation for comprehensive breakdown of each feature: + +- [Projects](./projects.md) +- [Dependencies](./dependencies.md) +- [Workspaces](./workspaces.md) +- [Tools](./tools.md) +- [Python versions](./python-versions.md) +- [Resolution](./resolution.md) +- [Caching](./cache.md) +- [Authentication](./configuration/authentication.md) diff --git a/docs/first-steps.md b/docs/first-steps.md index 3bb63fd0a..1fecb76f6 100644 --- a/docs/first-steps.md +++ b/docs/first-steps.md @@ -1,72 +1,59 @@ # First steps with uv -## Check the version +uv only provides a command-line interface and must be used from a terminal. -After [installing uv](./installation.md), check that it works from the CLI: +After [installing uv](./installation.md), you can check that uv is installed by running the `uv` command: -```bash -uv version +```console +$ uv ``` -The installed version should be displayed. +You should see a help menu listing the available commands. -## uv's interfaces +## Viewing the version -uv's commands can be grouped into a few sections. +To check the installed version: -### Project management +```console +$ uv version +``` -These commands are intended for managing development of a Python project. In these workflows, management of the virtual environment is done automatically by uv. +The following are also valid: -- `uv add` -- `uv remove` -- `uv sync` -- `uv lock` +```console +$ uv --version # Same output as `uv version` +$ uv -V # Will not include the build commit and date +$ uv pip --version # Can be used with a subcommand +``` -See the [project guide](./guides/projects.md) for more details on getting started. +## Help menus -### Toolchain management +The `--help` flag can be used to view the help menu for a command, e.g., for `uv`: -These commands are used to manage Python itself. uv is capable of installing and managing multiple Python versions. +```console +$ uv --help +``` -- `uv python install` -- `uv python list` -- `uv python find` +To view the help menu for a specific command, e.g., for `uv init`: -See the documentation on [toolchains](./python-versions.md) for more details on getting started. +```console +$ uv init --help +``` -### Command-line tool management +When using the `--help` flag, uv displays a condensed help menu. To view a longer help menu for a command, use `uv help`: -These commands are used to manage command-line tools written in Python. +```console +$ uv help +``` -- `uv tool run` +To view the long help menu for a specific command, e.g., for `uv init`: -See the documentation on [tools](./tools.md) for more details on getting started. +```console +$ uv help init +``` -### Low-level plumbing commands +When using the long help menu, uv will attempt to use `less` or `more` to "page" the output so it is not all displayed at once. To exit the pager, press `q`. -The commands in this group allow manual management of environments and packages. They are intended to be used in legacy workflows or cases where the high-level commands do not provide enough control. +## Next steps -This command is designed as replacement for the Python `venv` and `virtualenv` modules: - -- `uv venv` - -These commands are designed as replacements for `pip`: - -- `uv pip install` -- `uv pip show` -- `uv pip freeze` -- `uv pip check` -- `uv pip list` -- `uv pip uninstall` - -These commands are designed as replacements for `pip-tools`: - -- `uv pip compile` -- `uv pip sync` - -This command is designed as a replacement for `pipdeptree`: - -- `uv pip tree` - -Please note these commands do not exactly implement the interfaces and behavior of the tools that informed their design. Consult the [pip-compatibility guide](./pip/compatibility.md) for details on differences. +Now that you've confirmed uv is installed and know how to get help, check out the [feature overview](./features.md) to start using uv. diff --git a/docs/guides/install-python.md b/docs/guides/install-python.md index 3fc4627ac..5c3501ccb 100644 --- a/docs/guides/install-python.md +++ b/docs/guides/install-python.md @@ -1,14 +1,19 @@ # Installing Python -If Python is already installed, uv will [detect and use](#using-an-existing-python-installation) it without configuration. However, uv can also install and manage Python versions. +If Python is already installed on your system, uv will [detect and use](#using-an-existing-python-installation) it without configuration. However, uv can also install and manage Python versions for you. -To install Python: +To install the latest Python version: ```console $ uv python install ``` -This will install a uv-managed Python version even if there is already a Python installation on the system. +This will install a uv managed Python version even if there is already a Python installation on your system. + +!!! note + + Python does not publish official distributable binaries so uv uses third-party distributions from the [`python-build-standalone`](https://github.com/indygreg/python-build-standalone) project. The project is partially maintained by the uv maintainers and is used by many other Python projects. See the [Python distributions](../python-versions.md#python-distributions) documentation for more details. + -Once Python is installed, it will be used by `uv` commands. +Once Python is installed, it will be used by `uv` commands automatically. ## Installing a specific version @@ -32,7 +37,7 @@ To install a specific Python version: $ uv python install 3.12 ``` -See the [Python versions](../python-versions.md) documentation for more details. +See the [`python install`](../python-versions.md#installing-a-python-version) documentation for more details. ## Viewing Python installations @@ -66,6 +71,6 @@ Note that when an automatic Python installation occurs, the `python` command wil ## Using an existing Python installation -uv will also use an existing Python installation if already present on the system. There's no configuration necessary for this behavior: uv will use the system Python if it satisfies the requirements of the command invocation. See the [Python discovery](../python-versions.md#discovery-order) documentation for details. +uv will also use an existing Python installation if already present on your system. There is no configuration necessary for this behavior: uv will use the system Python if it satisfies the requirements of the command invocation. See the [Python discovery](../python-versions.md#discovery-order) documentation for details. To force uv to use the system Python, provide the `--python-preference only-system` option. See the [Python version preference](../python-versions.md#adjusting-python-version-preferences) documentation for more details. diff --git a/docs/guides/integration/commercial-indexes.md b/docs/guides/integration/commercial-indexes.md index d899001dd..665208e03 100644 --- a/docs/guides/integration/commercial-indexes.md +++ b/docs/guides/integration/commercial-indexes.md @@ -6,7 +6,7 @@ While uv uses the official Python Package Index (PyPI) by default, it also suppo uv can install packages from [Azure DevOps Artifacts](https://learn.microsoft.com/en-us/azure/devops/artifacts/start-using-azure-artifacts?view=azure-devops&tabs=nuget%2Cnugetserver). Authenticate to a feed using a [Personal Access Token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows) (PAT) or interactively using the [`keyring`](https://github.com/jaraco/keyring) package. -### Authenticate using a PAT +### Using a PAT If there is a PAT available (eg [`$(System.AccessToken)` in an Azure pipeline](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken)), credentials can be provided via the "Basic" HTTP authentication scheme. Include the PAT in the password field of the URL. A username must be included as well, but can be any string. @@ -15,7 +15,7 @@ If there is a PAT available (eg [`$(System.AccessToken)` in an Azure pipeline](h export UV_EXTRA_INDEX_URL=https://dummy:$ADO_PAT@pkgs.dev.azure.com/{organisation}/{project}/_packaging/{feedName}/pypi/simple/ ``` -### Authenticate using the `keyring` plugin +### Using `keyring` If there is not a PAT available, authenticate to Artifacts using the [`keyring`](https://github.com/jaraco/keyring) package with [the `artifacts-keyring` plugin](https://github.com/Microsoft/artifacts-keyring). Because these two packages are required to authenticate to Azure Artifacts, they must be pre-installed from a source other than Artifacts. diff --git a/docs/guides/integration/github.md b/docs/guides/integration/github.md index ae8612c10..c0b2c4923 100644 --- a/docs/guides/integration/github.md +++ b/docs/guides/integration/github.md @@ -1 +1,159 @@ # Using uv in GitHub Actions + +## Installation + +uv installation differs depending on the platform. + +### on Unix + +```yaml +name: Example on Unix + +jobs: + uv-example-linux: + name: python-linux + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up uv + # Install uv using the standalone installer + run: curl -LsSf https://astral.sh/uv/install.sh | sh +``` + +### on Windows + +```yaml +name: Example on Windows + +jobs: + uv-example-windows: + name: python-windows + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up uv + # Install uv using the standalone installer + run: irm https://astral.sh/uv/install.ps1 | iex + shell: powershell +``` + +### Using a matrix + +```yaml +name: Example + +jobs: + uv-example-multiplatform: + name: python-${{ matrix.os }} + + strategy: + matrix: + os: + - ubuntu-latest + - windows-latest + - macos-latest + + fail-fast: false + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up uv + if: ${{ matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' }} + run: curl -LsSf https://astral.sh/uv/install.sh | sh + + - name: Set up uv + if: ${{ matrix.os == 'windows-latest' }} + run: irm https://astral.sh/uv/install.ps1 | iex + shell: powershell +``` + +## Setting up Python + +Python can be installed with the `python install` command: + +```yaml +steps: + # ... setup up uv ... + + - name: Set up Python + run: uv python install +``` + +This will respect the Python version pinned in the project. + +Or, when using a matrix, as in: + +```yaml +strategy: + matrix: + python-version: + - "3.10" + - "3.11" + - "3.12" +``` + +Provide the version to the `python install` invocation: + +```yaml +steps: + # ... setup up uv ... + + - name: Set up Python ${{ matrix.python-version }} + run: uv python install ${{ matrix.python-version }} +``` + +Alternatively, the official GitHub `setup-python` action can be used. This is generally faster, but will not respect the project's pinned Python version. + +```yaml +steps: + - name: "Set up Python" + uses: actions/setup-python@v5 + with: + python-version: 3.12 +``` + +## Syncing and running + +Once uv and Python are installed, the project can be installed with `uv sync` and commands can be run in the environment with `uv run`: + +```yaml +steps: + # ... setup up Python and uv ... + + - name: Install the project + run: uv sync --all-extras --dev + + - name: Run tests + # For example, using `pytest` + run: uv run -- pytest tests +``` + +## Using `uv pip` + +If using the `uv pip` interface instead of the uv project interface, uv requires a virtual environment by default. To allow installing packages into the system environment, use the `--system` flag on all `uv` invocations or set the `UV_SYSTEM_PYTHON` variable, e.g.: + +```yaml +steps: + - name: Allow uv to use the system Python by default + run: echo "UV_SYSTEM_PYTHON=1" >> $GITHUB_ENV +``` + +Now, `uv pip` can modify the system environment without creating and activating a virtual environment. + +```yaml +steps: + # ... setup up Python and uv ... + + - name: Install requirements + run: uv pip install -r requirements.txt + + - name: Run tests + run: pytest tests +``` diff --git a/docs/guides/projects.md b/docs/guides/projects.md index cc5593715..c5b43a5b6 100644 --- a/docs/guides/projects.md +++ b/docs/guides/projects.md @@ -1,6 +1,6 @@ # Working on projects -uv can manage the development of a Python project from the ground up. +uv is capable of managing Python projects following the `pyproject.toml` standard. ## Creating a new project @@ -14,6 +14,7 @@ $ cd hello-world Alternatively, you can initialize a project in the working directory: ```console +$ mkdir hello-world $ cd hello-world $ uv init ``` @@ -33,13 +34,12 @@ This will create the following directory structure: If your project already contains a standard `pyproject.toml`, you can start using uv without any extra work. Commands like `uv add` and `uv run` will -create the lockfile and virtual environment the first time they are run. +create a lockfile and virtual environment the first time they are used. If you are migrating from an alternative Python package manager, you may need to -edit your `pyproject.toml` manually to use uv. uv uses the `[tool.uv]` section -of the `pyproject.toml` to support non-standard features, such as development -dependencies. Alternative Python package managers may use different sections, -or a custom format altogether. +edit your `pyproject.toml` manually before using uv. uv uses a `[tool.uv]` section +in the `pyproject.toml` to support features that are not yet included in the `pyproject.toml` standard, such as development dependencies. Alternative Python package managers may use +different sections or format. ## Project structure diff --git a/docs/guides/scripts.md b/docs/guides/scripts.md index 072dc8962..ed490b680 100644 --- a/docs/guides/scripts.md +++ b/docs/guides/scripts.md @@ -5,7 +5,7 @@ script dependencies are properly managed inside and outside of projects. ## Running a script without dependencies -If a script has no dependencies, it can be executed with `uv run`: +If your script has no dependencies, you can execute it with `uv run`: ```python print("Hello world") @@ -16,7 +16,9 @@ $ uv run example.py Hello world ``` -Similarly, if the script depends on a module in the standard library, there's nothing more to do: + + +Similarly, if your script depends on a module in the standard library, there's nothing more to do: ```python import os @@ -29,7 +31,7 @@ $ uv run example.py /Users/astral ``` -Arguments can be passed to the script: +Arguments may be provided to the script: ```python import sys @@ -45,18 +47,18 @@ $ uv run example.py hello world! hello world! ``` -Note that if `uv run` is used in a _project_, i.e. a directory with a `pyproject.toml`, it will install the current project before running the script. If the script does not depend on the project, use the `--isolated` flag to skip this: +Note that if you use `uv run` in a _project_, i.e. a directory with a `pyproject.toml`, it will install the current project before running the script. If your script does not depend on the project, use the `--isolated` flag to skip this: ```console # Note, it is important that the flag comes _before_ the script $ uv run --isolated example.py ``` -See the [projects](./projects.md) guide for more details on working in projects. +See the [projects guide](./projects.md) for more details on working in projects. ## Running a script with dependencies -When a script requires dependencies, they must be installed into the environment that the script runs in. uv prefers to create these environments on-demand instead of maintaining a long-lived virtual environment with manually managed dependencies. This requires explicit declaration +When your script requires other packages, they must be installed into the environment that the script runs in. uv prefers to create these environments on-demand instead of using a long-lived virtual environment with manually managed dependencies. This requires explicit declaration of dependencies that are required for the script. Generally, it's recommended to use a [project](./projects.md) or [inline metadata](#declaring-script-dependencies) to declare dependencies, but uv supports requesting dependencies per invocation as well. For example, the following script requires `rich`. @@ -79,7 +81,7 @@ Traceback (most recent call last): ModuleNotFoundError: No module named 'rich' ``` -The dependency can be requested with the `--with` option: +Request the dependency using the `--with` option: ```console $ uv run --with rich example.py @@ -175,4 +177,4 @@ $ uv run --python 3.10 example.py 3.10.13 ``` -See the [Python versions](../python-versions.md) documentation for more details on requesting Python versions. +See the [Python version request](../python-versions.md#requesting-a-version) documentation for more details on requesting Python versions. diff --git a/docs/guides/tools.md b/docs/guides/tools.md index 797b9540c..b5c04044c 100644 --- a/docs/guides/tools.md +++ b/docs/guides/tools.md @@ -4,7 +4,7 @@ Many Python packages provide command-line interfaces which are useful as standal ## Using `uvx` -The `uvx` command is an alias for `uv tool run`, which can be used to invoke a tool without installing it. +The `uvx` command invokes a tool without installing it. For example, to run `ruff`: @@ -12,13 +12,17 @@ For example, to run `ruff`: $ uvx ruff ``` -Note this is exactly equivalent to: +!!! note -```console -$ uv tool run ruff -``` + This is exactly equivalent to: -Arguments can be passed after the tool name: + ```console + $ uv tool run ruff + ``` + + `uvx` is provided as a short alias since the operation is very common. + +Arguments can be provided after the tool name: ```console $ uvx pycowsay hello from uv @@ -36,7 +40,7 @@ $ uvx pycowsay hello from uv ## Commands with different package names -In `uvx ruff`, the `ruff` package is installed to provide the `ruff` command. However, sometimes the package name differs from the command name. +When you invoke `uvx ruff`, uv installs the `ruff` package which provides the `ruff` command. However, sometimes the package and command names differ. The `--from` option can be used to invoke a command from a specific package, e.g. `http` which is provided by `httpie`: diff --git a/docs/index.md b/docs/index.md index 373e02ba0..601d0e73a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,12 +1,12 @@ -[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) -[![image](https://img.shields.io/pypi/v/uv.svg)](https://pypi.python.org/pypi/uv) -[![image](https://img.shields.io/pypi/l/uv.svg)](https://pypi.python.org/pypi/uv) -[![image](https://img.shields.io/pypi/pyversions/uv.svg)](https://pypi.python.org/pypi/uv) -[![Actions status](https://github.com/astral-sh/uv/actions/workflows/ci.yml/badge.svg)](https://github.com/astral-sh/uv/actions) -[![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord&logoColor=white)](https://discord.gg/astral-sh) -An extremely fast Python package installer and resolver, written in Rust. Designed as a drop-in -replacement for common `pip` and `pip-tools` workflows. +
+ + + + +
+ +An extremely fast Python version, package, and project manager, written in Rust.

Shows a bar chart with benchmark results. @@ -22,23 +22,29 @@ replacement for common `pip` and `pip-tools` workflows. ## Highlights -- βš–οΈ Drop-in replacement for common `pip`, `pip-tools`, and `virtualenv` commands. +- 🐍 [Installs and manages](./guides/install-python.md) Python versions. +- πŸ› οΈ [Executes and installs](./guides/tools.md) commands provided by Python packages. +- ❇️ [Runs scripts](./guides/scripts.md) with inline dependency metadata. +- πŸ—‚οΈ Provides comprehensive project management, with a multi-platform lock file. +- 🏒 Supports Cargo-style workspaces for large projects. +- πŸš€ A replacement for `pip`, `pip-tools`, `pipx`, `poetry`, `pyenv`, and more. - ⚑️ [10-100x faster](https://github.com/astral-sh/uv/blob/main/BENCHMARKS.md) than `pip` and `pip-tools` (`pip-compile` and `pip-sync`). -- πŸ’Ύ Disk-space efficient, with a global cache for dependency deduplication. -- 🐍 Installable via `curl`, `pip`, `pipx`, etc. uv is a static binary that can be installed - without Rust or Python. - πŸ§ͺ Tested at-scale against the top 10,000 PyPI packages. -- πŸ–₯️ Support for macOS, Linux, and Windows. -- 🧰 Advanced features such as dependency version overrides, multi-platform resolutions, reproducible resolutions, - alternative resolution strategies, and more. +- πŸ’Ύ Disk-space efficient, with a global cache for dependency deduplication. - ⁉️ Best-in-class error messages with a conflict-tracking resolver. -- 🀝 Support for a wide range of advanced `pip` features, including editable installs, Git - dependencies, direct URL dependencies, local dependencies, constraints, source distributions, - HTML and JSON indexes, and more. +- ⏬ A static binary that can be installed without Rust or Python via `curl` or `pip`. +- πŸ–₯️ Support for macOS, Linux, and Windows. uv is backed by [Astral](https://astral.sh), the creators of [Ruff](https://github.com/astral-sh/ruff). +## Replacement for `pip` and `pip-tools` + +uv provides a drop-in replacement for common `pip`, `pip-tools`, and `virtualenv` commands with support for +a wide range of advanced `pip` features, including editable installs, Git dependencies, direct URL dependencies, local dependencies, constraints, source distributions, HTML and JSON indexes, and more. + +uv extends these interfaces with advanced features, such as dependency version overrides, multi-platform resolutions, reproducible resolutions, alternative resolution strategies, and more. + ## Getting started Install uv with our official standalone installer: @@ -51,23 +57,4 @@ curl -LsSf https://astral.sh/uv/install.sh | sh powershell -c "irm https://astral.sh/uv/install.ps1 | iex" ``` -Or, see our [installation guide](./installation.md) for more options. - -Then, check out our documentation [creating an environment](pip/environments.md). - -## Features - -uv supports features familiar from `pip` and `pip-tools`: - -- [Managing Python environments](pip/environments.md) -- [Installing packages](pip/packages.md) -- [Inspecting packages](pip/inspection.md) -- [Locking environments](pip/compile.md) - -uv also supports many advanced features: - -- [Multi-platform resolution](./resolution.md#multi-platform-resolution) -- [Dependency overrides](./resolution.md#dependency-overrides) -- [Reproducible resolutions](./resolution.md#time-restricted-reproducible-resolutions) -- [Resolution strategies for multiple indexes](./resolution.md#resolution-strategy) -- [Dependency caching](./cache.md#dependency-caching) +Then, check out the [first steps](./first-steps.md) or see more [installation methods](./installation.md). diff --git a/docs/installation.md b/docs/installation.md index 352a2e017..0bdac9850 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -46,13 +46,13 @@ When the standalone installer is used, uv can upgrade itself. uv self update ``` -Note when all other installers are used, self updates are disabled. +When all other installers are used, self updates are disabled. Use the package manager's upgrade method instead. ## PyPI For convenience, uv is published to [PyPI](https://pypi.org/project/uv/). -If installing from PyPI, we recommend using `pipx` to install uv into an isolated environment: +If installing from PyPI, we recommend installing uv into an isolated environment, e.g., with `pipx`: ```bash pipx install uv @@ -64,7 +64,9 @@ However, `pip` can also be used: pip install uv ``` -There are prebuilt distributions (wheels) for many platforms; if not available for a given platform, uv will be built from source which requires a Rust toolchain to be installed. See the [contributing setup guide](https://github.com/astral-sh/uv/blob/main/CONTRIBUTING.md#setup) for details on building uv from source. +!!! note + + There are prebuilt distributions (wheels) for many platforms; if not available for a given platform, uv will be built from source which requires a Rust toolchain to be installed. See the [contributing setup guide](https://github.com/astral-sh/uv/blob/main/CONTRIBUTING.md#setup) for details on building uv from source. ## Homebrew @@ -82,6 +84,6 @@ See our guide on [using uv in Docker](./guides/integration/docker.md) for more d ## GitHub Releases -uv artifacts can be downloaded directly from [GitHub Releases](https://github.com/astral-sh/uv/releases). +uv release artifacts can be downloaded directly from [GitHub Releases](https://github.com/astral-sh/uv/releases). Each release page includes binaries for all supported platforms as well as instructions for using the standalone installer via `github.com` instead of `astral.sh`. diff --git a/docs/preview/dependencies.md b/docs/preview/dependencies.md deleted file mode 100644 index 578706966..000000000 --- a/docs/preview/dependencies.md +++ /dev/null @@ -1,203 +0,0 @@ -**Warning: This documentation refers to experimental features that may change.** - -# Specifying dependencies - -In uv, dependency specification is divided between two tables: `project.dependencies` and -`tool.uv.sources`. - -At a high-level, the former is used to define the standards-compliant dependency metadata, -propagated when uploading to PyPI or building a wheel. The latter is used to specify the _sources_ -required to install the dependencies, which can come from a Git repository, a URL, a local path, a -different index, etc. - -## `project.dependencies` - -The `project.dependencies` table represents the dependencies that are used when uploading to PyPI or -building a wheel. Individual dependencies are specified using [PEP 508](#pep-508), and the table as -a whole follows the [PEP 621](https://packaging.python.org/en/latest/specifications/pyproject-toml/) -standard. - -You should think of `project.dependencies` as defining the packages that are required for your -project, along with the version constraints that should be used when installing them. - -`project.dependencies` is structured as a list in which each entry includes a dependency name and -version, and optionally extras or environment markers for platform-specific packages, as in: - -```toml -[project] -name = "albatross" -version = "0.1.0" -dependencies = [ - # Any version in this range - "tqdm >=4.66.2,<5", - # Exactly this version of torch - "torch ==2.2.2", - # Install transformers with the torch extra - "transformers[torch] >=4.39.3,<5", - # Only install this package on older python versions - # See "Environment Markers" for more information - "importlib_metadata >=7.1.0,<8; python_version < '3.10'", - "mollymawk ==0.1.0" -] -``` - -If you only require packages from PyPI or a single `--index-url`, then `project.dependencies` is all -you need. If, however, you depend on local packages, Git dependencies, or packages from a different -index, you should use `tool.uv.sources`. - -## `tool.uv.sources` - -During development, you may rely on a package that isn't available on PyPI. For example, let’s say -that we need to pull in a version of `tqdm` from a specific Git commit, `importlib_metadata` from -a dedicated URL, `torch` from the PyTorch-specific index, and `mollymawk` from our own workspace. - -We can express these requirements by enriching the `project.dependencies` table with -`tool.uv.sources`: - -```toml -[project] -name = "albatross" -version = "0.1.0" -dependencies = [ - # Any version in this range. - "tqdm >=4.66.2,<5", - # Exactly this version of torch. - "torch ==2.2.2", - # Install transformers with the torch extra. - "transformers[torch] >=4.39.3,<5", - # Only install this package on Python versions prior to 3.10. - "importlib_metadata >=7.1.0,<8; python_version < '3.10'", - "mollymawk ==0.1.0" -] - -[tool.uv.sources] -# Install a specific Git commit. -tqdm = { git = "https://github.com/tqdm/tqdm", rev = "cc372d09dcd5a5eabdc6ed4cf365bdb0be004d44" } -# Install a remote source distribution (`.zip`, `.tar.gz`) or wheel (`.whl`). -importlib_metadata = { url = "https://github.com/python/importlib_metadata/archive/refs/tags/v7.1.0.zip" } -# Pin a dependency for a specific registry. -torch = { index = "torch-cu118" } -# Use a package included in the same repository (editable installation). -mollymawk = { workspace = true } - -# See "Workspaces". -[tool.uv.workspace] -include = [ - "packages/mollymawk" -] - -# See "Indexes". -[tool.uv.indexes] -torch-cu118 = "https://download.pytorch.org/whl/cu118" -``` - -We support the following sources (which are mutually exclusive for a given dependency): - -- Git: Use `git` with a Git URL, optionally one of `rev`, `tag`, or `branch`, and - optionally a `subdirectoy`, if the package isn't in the repository root. -- URL: A `url` key with an `https://` URL to a wheel (ending in `.whl`) or a source distribution - (ending in `.zip` or `.tar.gz`), and optionally a `subdirectory` if the source distribution isn't - in the archive root. -- Path: The `path` is an absolute or relative path to a wheel (ending in `.whl`), a source - distribution (ending in `.zip` or `.tar.gz`), or a directory containing a `pyproject.toml`. We - recommend using workspaces over manual path dependencies. For directories, you can specify - `editable = true` for an [editable](#Editables) installation. -- Index: Set the `index` key to the name of an index name to install it - from this registry instead of your default index. -- Workspace: Set `workspace = true` to use the workspace dependency. You need to explicitly require - all workspace dependencies you use. They are [editable](#Editables) by default; specify - `editable = false` to install them as regular dependencies. - -Note that if a non-uv project uses this project as a Git- or path-dependency, only -`project.dependencies` is transferred, and you'll need to apply the information in the source table -using the configuration of the other project's package manager. - -## Optional dependencies - -For libraries, you may want to make certain features and their dependencies optional. For example, -pandas has an [`excel` extra](https://pandas.pydata.org/docs/getting_started/install.html#excel-files) -and a [`plot` extra](https://pandas.pydata.org/docs/getting_started/install.html#visualization) to limit the installation of Excel parsers and (e.g.) `matplotlib` to -those that explicitly require them. In the case of Pandas, you can install those extras with: -`pandas[plot, excel]`. - -Optional dependencies are specified in `[project.optional-dependencies]`, a TOML table that maps -from extra name to its dependencies, following the [PEP 508](#PEP 508) syntax. - -`tool.uv.sources` applies to this table equally. - -```toml -[project] -name = "pandas" -version = "1.0.0" - -[project.optional-dependencies] -plot = [ - "matplotlib>=3.6.3" -] -excel = [ - "odfpy>=1.4.1", - "openpyxl>=3.1.0", - "python-calamine>=0.1.7", - "pyxlsb>=1.0.10", - "xlrd>=2.0.1", - "xlsxwriter>=3.0.5" -] -``` - -## Development dependencies - -Unlike optional dependencies, development dependencies are local-only and will _not_ be published -to PyPI or other indexes. As such, development dependencies are included under `[tool.uv]` instead -of `[project]`. `tool.uv.sources` applies to them equally. - -```toml -[tool.uv] -dev-dependencies = [ - "pytest >=8.1.1,<9" -] -``` - -## PEP 508 - -The [PEP 508](https://peps.python.org/pep-0508/) syntax allows you to specify, in order: - -- The dependency name -- The extras you want (optional) -- The version specifier -- An environment marker (optional) - -The version specifiers are comma separated and added together, e.g., `foo >=1.2.3,<2,!=1.4.0` is -interpreted as "a version of `foo` that's at least 1.2.3, but less than 2, and not 1.4.0". - -Specifiers are padded with trailing zeros if required, so `foo ==2` matches foo 2.0.0, too. - -You can use a star for the last digit with equals, e.g. `foo ==2.1.*` will accept any release from -the 2.1 series. Similarly, `~=` matches where the last digit is equal or higher, e.g., `foo ~=1.2` -is equal to `foo >=1.2,<2`, and `foo ~=1.2.3` is equal to `foo >=1.2.3,<1.3`. - -Extras are comma-separated in square bracket between name and version, e.g., `pandas[excel,plot] ==2.2`. - -Some dependencies are only required in specific environments, e.g., a specific Python version or -operating system. For example to install the `importlib-metadata` backport for the -`importlib.metadata` module, you would use `importlib-metadata >=7.1.0,<8; python_version < '3.10'`. -To install `colorama` on Windows (but omit it on other platforms), use -`colorama >=0.4.6,<5; platform_system == "Windows"`. - -You combine markers with `and` and `or` and parentheses, e.g., `aiohttp >=3.7.4,<4; (sys_platform != 'win32' or implementation_name != 'pypy') and python_version >= '3.10'`. -Note that versions within markers must be quoted, while versions _outside_ of markers must _not_ be -quoted. - -## Editables - -A regular installation of a directory with a Python package first builds a wheel and then installs -that wheel into your virtual environment, copying all source files. When you edit the source files, -the virtual environment will contain outdated versions. - -Editable installations instead add a link to the project within the virtual environment -(a `.pth` file), which instructs the interpreter to include your sources directly. - -There are some limitations to editables (mainly: your build backend needs to support them, and -native modules aren't recompiled before import), but they are useful for development, as your -virtual environment will always use the latest version of your package. - -uv uses editable installation for workspace packages and patched dependencies by default. diff --git a/docs/projects.md b/docs/projects.md index 32e744b4d..310178470 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -52,4 +52,4 @@ Scripts that declare inline metadata are automatically executed in environments ## Projects with many packages -See the [workspaces](./preview/workspaces.md) documentation. +See the [workspaces](./workspaces.md) documentation. diff --git a/docs/python-versions.md b/docs/python-versions.md index fcf4b12ce..8d3f27870 100644 --- a/docs/python-versions.md +++ b/docs/python-versions.md @@ -1,27 +1,19 @@ -**Warning: This documentation refers to experimental features that may change.** - # Python versions -A Python installation is composed of a Python interpreter (i.e. the `python` executable), the standard library, and other supporting files. It is common for an operating system to come with a Python version installed and there are many tools to help manage Python versions. +A Python version is composed of a Python interpreter (i.e. the `python` executable), the standard library, and other supporting files. It is common for an operating system to come with a Python version installed. ## Requesting a version uv will automatically download a Python version if it cannot be found. -In stable commands, this behavior requires enabling preview mode. For example, when creating a virtual environment: +For example, when creating a virtual environment: ```bash -uv venv --preview --python 3.11.6 +uv venv --python 3.11.6 ``` uv will ensure that Python 3.11.6 is available β€” downloading and installing it if necessary β€” then create the virtual environment with it. -For commands that are in preview, like `uv sync`, preview behavior is always on. - -```bash -uv sync --python 3.12.3 -``` - Many Python version request formats are supported: - `` e.g. `3`, `3.12`, `3.12.3` @@ -127,3 +119,11 @@ When searching for a Python version, the following locations are checked: If a specific Python version is requested, e.g. `--python 3.7`, additional executable names are included in the search: - A Python interpreter on the `PATH` as, e.g., `python3.7` on macOS and Linux. + +## Python distributions + +Python does not publish official distributable binaries, uv uses third-party standalone distributions from the [`python-build-standalone`](https://github.com/indygreg/python-build-standalone) project. The project is partially maintained by the uv maintainers and is used by many other Python projects. + +The Python distributions are self-contained and highly-portable. Additionally, these distributions have various build-time optimizations enabled to ensure they are performant. + +These distributions have some behavior quirks, generally as a consequence of portability. See the [`python-build-standalone` quirks](https://gregoryszorc.com/docs/python-build-standalone/main/quirks.html) documentation for details. diff --git a/docs/resolution.md b/docs/resolution.md index 3dcc7077e..c61552125 100644 --- a/docs/resolution.md +++ b/docs/resolution.md @@ -106,10 +106,21 @@ hatch for erroneous upper version bounds. ## Multi-platform resolution By default, uv's `pip-compile` command produces a resolution that's known to be compatible with -the current platform and Python version. Unlike Poetry and PDM, uv does not yet produce a -machine-agnostic lockfile ([#2679](https://github.com/astral-sh/uv/issues/2679)). +the current platform and Python version. -However, uv _does_ support resolving for alternate platforms and Python versions via the +uv also supports a machine agnostic resolution. uv supports writing multiplatform resolutions in both a `requirements.txt` format +and uv-specific (`uv.lock`) format. + +If using uv's `pip compile`, the `--universal` flag will generate a resolution that is compatible with all operating systems, +architectures, and Python implementations. In universal mode, the current Python version (or provided `--python-version`) +will be treated as a lower bound. For example, `--universal --python-version 3.7` would produce a universal resolution +for Python 3.7 and later. + +If using uv's [project](./guides/projects.md) interface, the machine agnostic resolution will be used +automatically and a `uv.lock` file will be created. The lock file can also be created with an explicit `uv lock` +invocation. + +uv also supports resolving for specific alternate platforms and Python versions via the `--python-platform` and `--python-version` command line arguments. For example, if you're running uv on macOS, but want to resolve for Linux, you can run @@ -123,12 +134,15 @@ The `--python-platform` and `--python-version` arguments can be combined to prod a specific platform and Python version, enabling users to generate multiple lockfiles for different environments from a single machine. -_N.B. Python's environment markers expose far more information about the current machine -than can be expressed by a simple `--python-platform` argument. For example, the `platform_version` marker -on macOS includes the time at which the kernel was built, which can (in theory) be encoded in -package requirements. uv's resolver makes a best-effort attempt to generate a resolution that is -compatible with any machine running on the target `--python-platform`, which should be sufficient for -most use cases, but may lose fidelity for complex package and platform combinations._ +!!! note + + Python's environment markers expose far more information about the current machine + than can be expressed by a simple `--python-platform` argument. For example, the `platform_version` marker + on macOS includes the time at which the kernel was built, which can (in theory) be encoded in + package requirements. uv's resolver makes a best-effort attempt to generate a resolution that is + compatible with any machine running on the target `--python-platform`, which should be sufficient for + most use cases, but may lose fidelity for complex package and platform combinations. + ## Time-restricted reproducible resolutions diff --git a/docs/preview/workspaces.md b/docs/workspaces.md similarity index 77% rename from docs/preview/workspaces.md rename to docs/workspaces.md index bd5cae0f7..5559551df 100644 --- a/docs/preview/workspaces.md +++ b/docs/workspaces.md @@ -1,5 +1,3 @@ -**Warning: This documentation refers to experimental features that may change.** - # Workspaces Workspaces help organize large codebases by splitting them into multiple packages with @@ -25,15 +23,11 @@ exclude = ["example/excluded_example"] If `tool.uv.sources` is defined in the workspace root, it applies to all packages, unless overridden in the `tool.uv.sources` of a specific project. -## Common usage +## Common structures -There a two main usage patterns: A root package and helpers, and the flat workspace. The root -workspace layout defines one main package in the root of the repository, with helper packages in -`packages`. In the flat layout, all packages are in the `packages` directory, and the root -`pyproject.toml` defines a so-called virtual workspace. +There a two main workspace structures: A **root package with helpers** and a **flat workspace**. -Root package and helpers: In this layout `albatross/pyproject.toml` has both a `project` section and -a `tool.uv.workspace` section. +The root workspace layout defines one main package in the root of the repository, with helper packages in `packages`. In this example `albatross/pyproject.toml` has both a `project` section and a `tool.uv.workspace` section. ``` albatross @@ -58,7 +52,8 @@ albatross └── main.py ``` -Flat workspace: In this layout `albatross/pyproject.toml` has only a `tool.uv.workspace` section, +In the flat layout, all packages are in the `packages` directory, and the root +`pyproject.toml` defines a so-called virtual workspace. In this example `albatross/pyproject.toml` has only a `tool.uv.workspace` section, but no `project`. ``` diff --git a/mkdocs.template.yml b/mkdocs.template.yml index 575000469..9ad05fe7b 100644 --- a/mkdocs.template.yml +++ b/mkdocs.template.yml @@ -1,7 +1,7 @@ site_name: uv theme: name: material - favicon: assets/favicon.ico + favicon: assets/favicon.svg features: - navigation.instant - navigation.instant.prefetch @@ -10,6 +10,7 @@ theme: - navigation.tracking - content.code.annotate - toc.follow + - navigation.footer - navigation.path - navigation.top - content.code.copy @@ -71,6 +72,7 @@ nav: - Getting started: - Installation: installation.md - First steps: first-steps.md + - Feature overview: features.md - Guides: - Installing Python: guides/install-python.md - Running scripts: guides/scripts.md @@ -78,10 +80,10 @@ nav: - Working on projects: guides/projects.md - Concepts: - Projects: projects.md + - Dependencies: dependencies.md + - Workspaces: workspaces.md - Tools: tools.md - Python versions: python-versions.md - - Workspaces: preview/workspaces.md - - Dependency sources: preview/dependencies.md - Resolution: resolution.md - Caching: cache.md - Authentication: configuration/authentication.md