Skip to content

WIP: Support for uv workspaces#1547

Draft
fpgmaas wants to merge 16 commits intomainfrom
feat/uv-workspace
Draft

WIP: Support for uv workspaces#1547
fpgmaas wants to merge 16 commits intomainfrom
feat/uv-workspace

Conversation

@fpgmaas
Copy link
Copy Markdown
Member

@fpgmaas fpgmaas commented Apr 5, 2026

PR Checklist

  • A description of the changes is added to the description of this PR.
  • If there is a related issue, make sure it is linked to this PR.
  • If you've fixed a bug or added code that should be tested, add tests!
  • If you've added or modified a feature, documentation in docs is updated

Description of changes

Add support for uv workspaces

Closes #1060.

Why

uv's own docs call out a gap deptry can fill:

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.

Until now deptry treated a uv workspace as a single project, so the only way to run deptry correctly on a uv workspace is to invoke it once for each workspace member. Even that is suboptimal, because deptry is not aware of the other packages+modules in the workspace while scanning one of them.

Approach

Core detects whether the project is a plain project or a uv workspace and dispatches to either ProjectScanner or the new UvWorkspaceScanner. The UvWorkspaceScanner scanner runs ProjectScanner once per member with a lightly adapted config (reading each member's own [tool.deptry] section), and builds a global package -> top-level modules map up front by resolving each member's editable .pth file via importlib.metadata so a member can recognise sibling packages by their import name, not just their distribution name. Dev deps declared at the workspace root are merged into each member scan, since they live in the shared environment.

New error codes

Code Name Description
DEP101 Missing workspace dependency A module from a sibling workspace member is imported but that member is not declared as a dependency of the importing package.
DEP102 Workspace transitive dependency A third-party package is imported without being declared; it only resolves because another workspace member declares it. Would otherwise be misreported as DEP003.

Both are demonstrated by tests/fixtures/uv_workspace/:

  • bar declares pandas but never uses it → DEP002
  • baz imports bar2 (from sibling bar) without declaring barDEP101
  • foo imports pandas without declaring it; only resolves via barDEP102

Assumptions

  • The workspace is synced before running deptry, i.e. uv sync --all-packages so every member is editable-installed. The package-to-module map walks editable .pth files; members that aren't installed are silently skipped.
  • Each member has a pyproject.toml with a [project] table and a discoverable top-level module.

TODO

  • Verify that the overall architecture is OK. Is this the way to go?
  • Do we need to cover additional violations?
  • Add an example with a root project + packages, not just packages.
  • Add documentation.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 5, 2026

@fpgmaas fpgmaas linked an issue Apr 5, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support uv workspaces

1 participant