Question presented to candidate: "Say we have a monorepo with an API service, a worker and a shared core library, all in Python, managed with uv. How would you set it up as a uv workspace, how do the packages depend on each other, and how do you keep test, lint and docs tools out of production installs with dependency groups?"
What a strong answer should cover:
- A workspace is a root
pyproject.tomlwith[tool.uv.workspace]members(globs) and optionalexclude; every member keeps its ownpyproject.toml, but there is oneuv.lockand one.venvat the root, so all members agree on every version - Members depend on each other by normal name in
[project].dependenciesplus{ workspace = true }in[tool.uv.sources]; they are installed as editable, and uv errors if the source entry is missing - Commands work on the root by default and target a member with
--package(or all with--all-packages);requires-pythonis the intersection over all members - Dependency groups (PEP 735,
[dependency-groups]) are named lists of requirements that are not published in the package metadata, unlike extras in[project.optional-dependencies];{ include-group = "..." }composes them, names are normalised, cycles are errors - uv installs the
devgroup by default;--no-dev,--group,--only-group,--all-groupsand[tool.uv] default-groupschange the selection, and[tool.uv] conflictsallows groups that cannot be installed together - Trade-off: one lock means one version of each dependency for the whole repo; members with genuinely incompatible requirements belong in separate projects (or path dependencies)
Clarifying questions expected:
- Must every service be deployable and versioned separately, or is it one product?
- Do any members need a different version of a shared dependency, or a different Python?
- Which tools must be in CI only, and which are needed for local development?
Code / implementation expected: Yes โ sketch the root and member pyproject.toml tables and the uv sync / uv run --package commands.