Skip to content

fix(python-setup): select the shared uv workspace venv for a workspace member - #2253

Merged
rugpanov merged 3 commits into
mainfrom
uv-workspace-shared-venv
Oct 14, 2026
Merged

rugpanov merged 3 commits into
mainfrom
uv-workspace-shared-venv

Conversation

@rugpanov

@rugpanov rugpanov commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Stack (merge in this order):

  1. fix(python-setup): select the shared uv workspace venv for a workspace member #2253 fix(python-setup): select the shared uv workspace venv for a workspace member (see diff) <- this PR
  2. fix(python-setup): recover a uv workspace member from a constraint conflict #2254 fix(python-setup): recover a uv workspace member from a constraint conflict (see diff)

Changes

In a monorepo with one uv workspace and one bundle per member, the Python environment setup selects the wrong interpreter (#2157). The Databricks CLI now supports uv workspace members in databricks environments setup-local (databricks/cli#7018, databricks/cli#7026). For a member, the CLI provisions one shared venv at the workspace root. It reports venvPath relative to the member folder, for example ../../.venv, and it adds uvWorkspaceRoot and uvWorkspaceBackupPath.

  • The extension resolves venvPath to an absolute folder. It uses this folder to select the interpreter and to read the venv name from pyvenv.cfg.
    • A value that climbs (../../.venv) counts from the symlink-resolved project folder on Unix, as the CLI does.
    • .venv stays under the project folder as opened.
    • An absolute value (from an absolute UV_PROJECT_ENVIRONMENT) stays as it is.
  • Before this change, the extension gave the Python extension a relative interpreter path. It also read pyvenv.cfg relative to the working folder of the extension host, so the venv name did not show in the summary. These fixes also apply to a standalone project.
  • The result parser reads uvWorkspaceRoot and uvWorkspaceBackupPath.
  • For a member, the success summary names the shared venv and the root pyproject.toml. The venv folder uses Windows separators on Windows.
  • The warning histogram counts W_UV_WORKSPACE_CONSTRAINTS_REPLACED.

Tests

  • New unit tests cover the venv folder for a member, a symlinked project folder, .venv under the opened folder, an absolute venvPath, the venv name, the result fields, the summary text on Linux and Windows, and the warning count.
  • Full unit suite: 1401 passing, 0 failing. yarn run test:lint reports 0 errors.

Known limitations

This pull request and its description were written by Isaac.

@rugpanov

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests running for 2374c915 — ⏳.
View run

@rugpanov

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests running for 5ecb3068 — ⏳.
View run

@rugpanov

rugpanov commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ❌ failed for 9752a1c4.
View run

@rugpanov
rugpanov force-pushed the uv-workspace-shared-venv branch from 9752a1c to a1c4bd1 Compare October 13, 2026 20:13
@rugpanov

rugpanov commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ✅ passed for a1c4bd1c.
View run

@rugpanov rugpanov changed the title fix(python-setup): use the shared uv workspace venv for a workspace member fix(python-setup): select the shared uv workspace venv for a workspace member Oct 13, 2026
@rugpanov

rugpanov commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ✅ passed for e169b071.
View run

@rugpanov
rugpanov marked this pull request as ready for review October 14, 2026 07:55
@rugpanov
rugpanov requested a review from misha-db October 14, 2026 07:55
@misha-db

Copy link
Copy Markdown
Contributor

A review turned up three low-severity items — all nice-to-haves, none blocking. Noting them here in case they're worth a follow-up.

1. Constraint-conflict recovery doesn't restore the workspace-root pyproject.toml

src/python-setup/controllers/PythonSetupEnvironmentSetup.ts (~L565)

For a uv workspace member, the conflicting managed pins live in the root pyproject.toml (the new uvWorkspaceBackupPath), but the Full-preset recovery only restores result.backupPath over cwd/pyproject.toml. On E_PROVISION_CONFLICT, "Retry DB Connect setup" rolls back only the member file; the root's conflicting pins stay on disk, so the --no-constraints retry can still resolve against them and the conflict may recur. uvWorkspaceBackupPath is wired up for display but not for recovery, and restoreProjectFile's lexical containment guard would reject the root backup anyway (it sits above cwd).

2. Success notification echoes a raw relative venvPath that diverges under symlinks

src/python-setup/utils/setupSummary.ts (~L131)

The toast/log print the CLI's raw relative venvPath (e.g. ../../.venv) interpreted from the opened folder, while adoption resolves a climbing path from the symlink-resolved real folder. If the member is opened via a symlink, adoption targets the correct venv but the displayed interpreter path (../../.venv/bin/python) resolves elsewhere from the opened folder — purely a cosmetic/display divergence.

3. A realpath failure gets labeled as an "adopt"-phase extension bug

src/python-setup/controllers/PythonSetupEnvironmentSetup.ts (~L618)

resolveVenvDir (which does the realpath call for climbing paths) sits inside the adopt try-catch. If the open folder is renamed/deleted during the multi-second CLI run, realpath(cwd) rejects with ENOENT and the catch labels failurePhase: 'adopt', surfacing a "Report this problem" action — mis-attributing an environmental/filesystem error to an extension defect, even though adoptInterpreter never ran.

rugpanov and others added 3 commits October 14, 2026 15:05
…e member

*Why*:
* In a monorepo with one uv workspace and one bundle per member, setup-local provisions the shared venv at the workspace root and reports `venvPath` relative to the member folder, for example `../../.venv` (#2157).
* The extension passed `venvPath` to the Python extension without resolving it against the project folder, and it read the venv name from a path relative to the extension host's working folder.

*What*:
* Resolve `venvPath` to an absolute folder before adopting it and reading its name. A value that climbs counts from the symlink-resolved project folder on Unix, as the CLI does; `.venv` stays under the folder as opened; an absolute value stays as is.
* Parse `uvWorkspaceRoot` and `uvWorkspaceBackupPath`. The success summary names the shared venv and the root pyproject.toml for a member, with Windows separators on Windows.
* Count `W_UV_WORKSPACE_CONSTRAINTS_REPLACED` in the setup-result warning histogram.

Co-authored-by: Isaac <no-reply@databricks.com>
…he warning list

Co-authored-by: Isaac <no-reply@databricks.com>
…fore adoption

A realpath failure on the project folder (renamed or deleted during the
CLI run) is a filesystem state, not an extension defect. Show a plain
error without "Report this problem" and record reportOffered: false.

Co-authored-by: Isaac <no-reply@databricks.com>
@rugpanov
rugpanov force-pushed the uv-workspace-shared-venv branch from e169b07 to d377b62 Compare October 14, 2026 13:06
@rugpanov

Copy link
Copy Markdown
Contributor Author

Thanks for the review!

  1. Root pyproject.toml restore: fix(python-setup): recover a uv workspace member from a constraint conflict #2254 fixes this. The retry checks and restores both backups, the member and the workspace root.
  2. Raw relative venvPath in the toast: only the displayed text is different, so I will fix it in a follow-up.
  3. realpath failure labeled as an extension bug: fixed in d377b62. A missing project folder now shows a plain error without "Report this problem" and records reportOffered: false.

@github-actions

Copy link
Copy Markdown
Contributor

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/vscode

Inputs:

  • PR number: 2253
  • Commit SHA: d377b620b44a9ef56d91d1de89ad1725a6fc0d5c

Checks will be approved automatically on success.

@rugpanov

rugpanov commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Integration tests ❌ failed for d377b620.
View run

@rugpanov
rugpanov merged commit faa6f58 into main Oct 14, 2026
9 checks passed
rugpanov added a commit that referenced this pull request Oct 15, 2026
…nflict (#2254)

**Stack** (merge in this order):

1. #2253 fix(python-setup): select the shared uv workspace venv for a
workspace member (merged)
2. #2254 fix(python-setup): recover a uv workspace member from a
constraint conflict ([see
diff](main...uv-workspace-shared-venv-2))
**<- this PR**

## Changes

For a uv workspace member, `setup-local` writes the constraint pins into
the root `pyproject.toml` and shares one venv at the root. The conflict
recovery and the adoption gauge assumed one `pyproject.toml` and one
`.venv` in the project folder.

- **Retry DB Connect setup:** the retry also restores the root
`pyproject.toml` from `uvWorkspaceBackupPath`. Without this, the retry
with `--no-constraints` keeps the conflicting root pins and fails again.
  - The retry checks every backup before it restores the first one.
- The extension trusts `uvWorkspaceRoot` only when it contains the
project folder, as opened or symlink-resolved, because the restore
writes there.
- A member with no root backup gets no retry, because the root pins
stay.
- A later setup run inside the restored folder (the workspace root for a
member, else the project) makes an older retry stale, because that run
can rewrite the same files. A stale click tells the user to run the
setup again.
- **Open pyproject.toml** opens the root file for a member, because it
holds the pins.
- **Adoption gauge:** the saved setup state records the project folder
and the absolute venv folder. The gauge checks that venv folder. It
skips a reading while the state belongs to another bundle in the same
workspace folder. State saved by older versions keeps the old behavior.

## Tests

- New unit tests cover the root restore, the check before the restore, a
root-only backup, a member without a root backup, an untrusted root, a
symlinked project folder, stale retries after a member run, after a root
project run, and through a symlink, a live retry after an unrelated run,
a backup that cannot be read, the "Open" target, the saved state, and
the gauge.
- Full unit suite: 1420 passing, 0 failing. `yarn run test:lint` reports
0 errors.

## Known limitations

- The stale-retry check works within one session. A run that starts
outside the restored folder, for example a member opened through a
symlink that points outside the workspace root, does not make the retry
stale.
- After a retry restores the member file, a failed copy of the root file
can still leave the two files out of step. The check before the restore
makes this rare.
- Members share one venv, so a sync for member B can remove packages
that only member A needs. Member A still shows as ready in this session.
- Drift detection still reads the single setup state and does not use
the new project folder.

This pull request and its description were written by Isaac.

---------

Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions github-actions Bot mentioned this pull request Oct 22, 2026
@github-actions github-actions Bot mentioned this pull request Oct 22, 2026
@rugpanov
rugpanov deleted the uv-workspace-shared-venv branch October 22, 2026 15:02
abdelrahmanomar1515 pushed a commit that referenced this pull request Oct 22, 2026
## packages/databricks-vscode
##  (2026-10-22)

- fix(bundle): find sub-projects without blocking the extension host
(#2249)
([5ebf39f](5ebf39f))
- fix(network): let VS Code handle proxies and certificates for SDK
calls (#2266)
([589041a](589041a))
- fix(python-setup): recover a uv workspace member from a constraint
conflict (#2254)
([7752f5d](7752f5d))
- fix(python-setup): select the shared uv workspace venv for a workspace
member (#2253)
([faa6f58](faa6f58))
- Expose the bundle Configuration view and Bundle Resource Explorer in
Databricks Remote SSH mode (#2236)
([375dd8d](375dd8d))
- Update Databricks CLI to v1.22.1 (#2270)
([bc837b5](bc837b5))


## packages/databricks-vscode-types
##  (2026-10-22)

Co-authored-by: releasebot <noreply@github.com>

This branch was previously deployed

1 inactive deployment
test-trigger-is — d377b620 Deployed Oct 14, 2026 by rugpanov via Trigger Tests #2371
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.

2 participants