Using workspacesワークスペースの使用
Inspired by the Cargo concept of the same name, a workspace is "a collection of one or more packages, called workspace members, that are managed together."同名のCargoの概念に触発されて、ワークスペースは「ワークスペースメンバーと呼ばれる1つ以上のパッケージのコレクションであり、一緒に管理される。」
Workspaces organize large codebases by splitting them into multiple packages with common dependencies. Think: a FastAPI-based web application, alongside a series of libraries that are versioned and maintained as separate Python packages, all in the same Git repository.ワークスペースは、大規模なコードベースを共通の依存関係を持つ複数のパッケージに分割することで整理します。例えば、FastAPIベースのウェブアプリケーションと、バージョン管理され、別々のPythonパッケージとして維持される一連のライブラリが同じGitリポジトリ内にあると考えてください。
In a workspace, each package defines its own pyproject.toml, but the workspace shares a single
lockfile, ensuring that the workspace operates with a consistent set of dependencies.ワークスペース内では、各パッケージが独自の pyproject.toml を定義しますが、ワークスペースは単一のロックファイルを共有し、ワークスペースが一貫した依存関係のセットで動作することを保証します。
As such, uv lock operates on the entire workspace at once, while uv run and uv sync operate on
the workspace root by default, though both accept a --package argument, allowing you to run a
command in a particular workspace member from any workspace directory.そのため、 uv lock はワークスペース全体で一度に操作し、 uv run と uv sync はデフォルトでワークスペースのルートで操作しますが、どちらも --package 引数を受け付け、任意のワークスペースディレクトリから特定のワークスペースメンバーでコマンドを実行できるようにします。
Getting startedはじめに
To create a workspace, add a tool.uv.workspace table to a pyproject.toml, which will implicitly
create a workspace rooted at that package.ワークスペースを作成するには、 pyproject.toml に tool.uv.workspace テーブルを追加します。これにより、そのパッケージをルートとするワークスペースが暗黙的に作成されます。
Tipヒント
By default, running uv init inside an existing package will add the newly created member to the workspace, creating a tool.uv.workspace table in the workspace root if it doesn't already exist.デフォルトでは、既存のパッケージ内で uv init を実行すると、新しく作成されたメンバーがワークスペースに追加され、既に存在しない場合はワークスペースのルートに tool.uv.workspace テーブルが作成されます。
In defining a workspace, you must specify the members (required) and exclude (optional) keys,
which direct the workspace to include or exclude specific directories as members respectively, and
accept lists of globs:ワークスペースを定義する際には、 members (必須)および exclude (オプション)キーを指定する必要があります。これにより、ワークスペースは特定のディレクトリをメンバーとして含めるか除外するかを指示し、グロブのリストを受け入れます:
[project]
name = "albatross"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["bird-feeder", "tqdm>=4,<5"]
[tool.uv.sources]
bird-feeder = { workspace = true }
[tool.uv.workspace]
members = ["packages/*"]
exclude = ["packages/seeds"]
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 or libraries; both are supported in
the workspace context.members グロブによって含まれるすべてのディレクトリ(および exclude グロブによって除外されないもの)は、 pyproject.toml ファイルを含む必要があります。ただし、ワークスペースメンバーは アプリケーション または ライブラリ のいずれかであることができます。両方ともワークスペースのコンテキストでサポートされています。
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
directory, except seeds.すべてのワークスペースにはルートが必要であり、それは ワークスペースメンバーでもあります。上記の例では、 albatross がワークスペースのルートであり、ワークスペースメンバーには packages ディレクトリ内のすべてのプロジェクトが含まれ、 seeds は除外されます。
By default, uv run and uv sync operates on the workspace root. For example, in the above
example, uv run and uv run --package albatross would be equivalent, while
uv run --package bird-feeder would run the command in the bird-feeder package.デフォルトでは、 uv run と uv sync はワークスペースのルートで操作します。例えば、上記の例では、 uv run と uv run --package albatross は同等ですが、 uv run --package bird-feeder は bird-feeder パッケージ内でコマンドを実行します。
Workspace sourcesワークスペースのソース
Within a workspace, dependencies on workspace members are facilitated via
tool.uv.sources, as in:ワークスペース内では、ワークスペースメンバーへの依存関係は、
tool.uv.sourcesを介して容易に行われます。例えば:
[project]
name = "albatross"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["bird-feeder", "tqdm>=4,<5"]
[tool.uv.sources]
bird-feeder = { workspace = true }
[tool.uv.workspace]
members = ["packages/*"]
[build-system]
requires = ["uv_build>=0.9.13,<0.10.0"]
build-backend = "uv_build"
In this example, the albatross project depends on the bird-feeder project, which is a member of
the workspace. The workspace = true key-value pair in the tool.uv.sources table indicates the
bird-feeder dependency should be provided by the workspace, rather than fetched from PyPI or
another registry.この例では、albatrossプロジェクトは、ワークスペースのメンバーであるbird-feederプロジェクトに依存しています。tool.uv.sourcesテーブルのworkspace = trueキーと値のペアは、bird-feederの依存関係がPyPIや他のレジストリから取得されるのではなく、ワークスペースによって提供されるべきであることを示しています。
Note注意
Dependencies between workspace members are editable.ワークスペースメンバー間の依存関係は編集可能です。
Any tool.uv.sources definitions in the workspace root apply to all members, unless overridden in
the tool.uv.sources of a specific member. For example, given the following pyproject.toml:ワークスペースルート内の任意のtool.uv.sources定義は、特定のメンバーのtool.uv.sourcesで上書きされない限り、すべてのメンバーに適用されます。例えば、次のpyproject.tomlを考えてみましょう:
[project]
name = "albatross"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["bird-feeder", "tqdm>=4,<5"]
[tool.uv.sources]
bird-feeder = { workspace = true }
tqdm = { git = "https://github.com/tqdm/tqdm" }
[tool.uv.workspace]
members = ["packages/*"]
[build-system]
requires = ["uv_build>=0.9.13,<0.10.0"]
build-backend = "uv_build"
Every workspace member would, by default, install tqdm from GitHub, unless a specific member
overrides the tqdm entry in its own tool.uv.sources table.デフォルトでは、すべてのワークスペースメンバーはtqdmをGitHubからインストールしますが、特定のメンバーが自分のtool.uv.sourcesテーブル内のtqdmエントリを上書きする場合を除きます。
Note注意
If a workspace member provides tool.uv.sources for some dependency, it will ignore any
tool.uv.sources for the same dependency in the workspace root, even if the member's source is
limited by a marker that doesn't match the current
platform.ワークスペースメンバーが特定の依存関係のためにtool.uv.sourcesを提供する場合、そのメンバーのソースが現在のプラットフォームと一致しないmarkerによって制限されていても、ワークスペースルート内の同じ依存関係に対するtool.uv.sourcesは無視されます。
Workspace layoutsワークスペースのレイアウト
The most common workspace layout can be thought of as a root project with a series of accompanying libraries.最も一般的なワークスペースのレイアウトは、ルートプロジェクトと一連の付随するライブラリとして考えることができます。
For example, continuing with the above example, this workspace has an explicit root at albatross,
with two libraries (bird-feeder and seeds) in the packages directory:例えば、上記の例を続けると、このワークスペースはalbatrossで明示的なルートを持ち、packagesディレクトリ内に2つのライブラリ(bird-feederとseeds)があります。
albatross
├── packages
│ ├── bird-feeder
│ │ ├── pyproject.toml
│ │ └── src
│ │ └── bird_feeder
│ │ ├── __init__.py
│ │ └── foo.py
│ └── seeds
│ ├── pyproject.toml
│ └── src
│ └── seeds
│ ├── __init__.py
│ └── bar.py
├── pyproject.toml
├── README.md
├── uv.lock
└── src
└── albatross
└── main.py
Since seeds was excluded in the pyproject.toml, the workspace has two members total: albatross
(the root) and bird-feeder.seedsがpyproject.tomlから除外されたため、ワークスペースには合計2つのメンバーがあります:albatross(ルート)とbird-feeder。
When (not) to use workspacesワークスペースを使用する(しない)場合
Workspaces are intended to facilitate the development of multiple interconnected packages within a single repository. As a codebase grows in complexity, it can be helpful to split it into smaller, composable packages, each with their own dependencies and version constraints.ワークスペースは、単一のリポジトリ内で複数の相互接続されたパッケージの開発を促進することを目的としています。コードベースが複雑になるにつれて、それをより小さく、構成可能なパッケージに分割することが役立つ場合があります。それぞれのパッケージには独自の依存関係とバージョン制約があります。
Workspaces help enforce isolation and separation of concerns. For example, in uv, we have separate packages for the core library and the command-line interface, enabling us to test the core library independently of the CLI, and vice versa.ワークスペースは、隔離と関心の分離を強制するのに役立ちます。例えば、uvでは、コアライブラリとコマンドラインインターフェースのために別々のパッケージを持っており、CLIとは独立してコアライブラリをテストできるようにしています。
Other common use cases for workspaces include:ワークスペースの他の一般的な使用例には、以下が含まれます:
- A library with a performance-critical subroutine implemented in an extension module (Rust, C++, etc.).拡張モジュール(Rust、C++など)で実装されたパフォーマンスクリティカルなサブルーチンを持つライブラリ。
- A library with a plugin system, where each plugin is a separate workspace package with a dependency on the root.各プラグインがルートに依存する別々のワークスペースパッケージであるプラグインシステムを持つライブラリ。
Workspaces are not suited for cases in which members have conflicting requirements, or desire a
separate virtual environment for each member. In this case, path dependencies are often preferable.
For example, rather than grouping albatross and its members in a workspace, you can always define
each package as its own independent project, with inter-package dependencies defined as path
dependencies in tool.uv.sources:ワークスペースは、メンバー間に競合する要件がある場合や、各メンバーに対して別々の仮想環境を望む場合には適していません。この場合、パス依存関係がしばしば好まれます。例えば、albatrossとそのメンバーをワークスペースにグループ化するのではなく、各パッケージを独立したプロジェクトとして定義し、パッケージ間の依存関係をtool.uv.sourcesのパス依存関係として定義することができます:
[project]
name = "albatross"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["bird-feeder", "tqdm>=4,<5"]
[tool.uv.sources]
bird-feeder = { path = "packages/bird-feeder" }
[build-system]
requires = ["uv_build>=0.9.13,<0.10.0"]
build-backend = "uv_build"
This approach conveys many of the same benefits, but allows for more fine-grained control over
dependency resolution and virtual environment management (with the downside that uv run --package
is no longer available; instead, commands must be run from the relevant package directory).このアプローチは多くの同じ利点を提供しますが、依存関係の解決と仮想環境管理に対してより細かい制御を可能にします(その欠点は、uv run --packageが利用できなくなることです。代わりに、コマンドは関連するパッケージディレクトリから実行する必要があります)。
Finally, uv's workspaces enforce a single requires-python for the entire workspace, taking the
intersection of all members' requires-python values. If you need to support testing a given member
on a Python version that isn't supported by the rest of the workspace, you may need to use uv pip
to install that member in a separate virtual environment.最後に、uvのワークスペースは、すべてのメンバーのrequires-python値の交差を取り、ワークスペース全体に対して単一のrequires-pythonを強制します。ワークスペースの他の部分がサポートしていないPythonバージョンで特定のメンバーのテストをサポートする必要がある場合、そのメンバーを別の仮想環境にインストールするためにuv pipを使用する必要があるかもしれません。
Note注意
As Python does not provide dependency isolation, uv can't ensure that a package uses its declared dependencies and nothing else. For workspaces specifically, uv can't ensure that packages don't import dependencies declared by another workspace member.Pythonは依存関係の隔離を提供しないため、uvはパッケージが宣言された依存関係のみを使用することを保証できません。特にワークスペースにおいて、uvはパッケージが他のワークスペースメンバーによって宣言された依存関係をインポートしないことを保証できません。