Skip to content

fix(python): use lockfile URL for precompiled installs#8750

Merged
jdx merged 2 commits intojdx:mainfrom
hehaoqian:copilot/fix-bug-in-discussion-8749
Apr 4, 2026
Merged

fix(python): use lockfile URL for precompiled installs#8750
jdx merged 2 commits intojdx:mainfrom
hehaoqian:copilot/fix-bug-in-discussion-8749

Conversation

@hehaoqian
Copy link
Copy Markdown
Contributor

@hehaoqian hehaoqian commented Mar 25, 2026

When installing precompiled Python, install_precompiled would always recompute the download URL from the remote version index, ignoring any URL already recorded in mise.lock. This broke reproducibility for locked installs.

Now checks lock_platforms for an existing URL before fetching remote versions. If found, uses it directly.

Fixes #8749

Copilot AI review requested due to automatic review settings March 25, 2026 06:02
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a bug where the Python plugin in mise would recompute the download URL for Python installations, even when a URL was already present in the mise.lock file. This behavior could lead to inconsistent or non-reproducible builds. The changes ensure that if a URL is specified in the lockfile for a given platform, it is used directly, enhancing the reliability of locked Python environments.

Highlights

  • Lockfile URL Obedience: Implemented logic to ensure that Python installations respect the URL specified in the mise.lock file, preventing recomputation of download URLs.
  • New E2E Test: Added an end-to-end test case to test_lockfile_python that deliberately corrupts the lockfile URL to confirm that mise install fails, proving the lockfile URL is honored.
  • Helper Function: Introduced a new utility function lockfile_url_for_platform in python.rs to safely retrieve URLs from platform-specific lockfile entries.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@hehaoqian hehaoqian changed the title Copilot/fix Obey python url in lock file fix: Obey python url in lock file Mar 25, 2026
@hehaoqian hehaoqian changed the title fix: Obey python url in lock file fix(python): Obey python url in lock file Mar 25, 2026
@hehaoqian hehaoqian marked this pull request as draft March 25, 2026 06:04
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 25, 2026

Greptile Summary

This PR fixes a bug where mise install for Python was ignoring the URL recorded in the lockfile and instead recomputing it fresh from the remote API. The fix adds an early check at the top of install_precompiled that reads the URL directly from tv.lock_platforms (if present) and skips the remote fetch entirely, ensuring the lockfile's recorded URL is authoritative. An accompanying e2e test validates this by injecting a deliberately wrong URL into the lockfile and confirming that mise install fails while attempting to download from that URL.

Key changes:

  • src/plugins/core/python.rs: install_precompiled now reads the URL from tv.lock_platforms[platform_key].url first, falling back to the remote version-lookup path only when no URL is stored
  • e2e/lockfile/test_lockfile_python: New test section that corrupts the lockfile URL with a fake value and asserts the install fails with that URL in the error output, confirming lockfile URL obedience
  • The platform_key binding is hoisted to the top of install_precompiled so it's shared by the early-exit path and the existing recording-after-download path

Confidence Score: 5/5

Safe to merge — the fix is a minimal, well-targeted change with a concrete regression test

The core logic change is correct: checking tv.lock_platforms[platform_key].url before doing the remote fetch ensures the lockfile URL is authoritative. The platform_key hoist is clean. The redundant URL re-assignment after download is a harmless no-op. The test harness's quiet_assert_fail already redirects stderr so the new assertion works correctly. No P0/P1 findings remain.

No files require special attention

Important Files Changed

Filename Overview
src/plugins/core/python.rs Correctly prioritises the lockfile URL over a freshly-computed one; hoisted platform_key is used consistently; the redundant re-assignment of url after download (when it came from the lockfile) is a benign no-op since entry().or_default() returns the already-existing PlatformInfo
e2e/lockfile/test_lockfile_python New test section correctly validates the lockfile URL is obeyed; quiet_assert_fail in assert.sh already injects 2>&1 internally so stderr capture is handled even without an explicit redirect in the command string

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[install_precompiled called] --> B[get_platform_key]
    B --> C{tv.lock_platforms\nhas URL for key?}
    C -- Yes --> D[Use lockfile URL directly\nskip remote fetch]
    C -- No --> E[fetch_precompiled_remote_versions]
    E --> F{Match found\nfor tv.version?}
    F -- Yes --> G[Build URL from tag + filename\nShow precompiled hint]
    F -- No --> H{windows or\ncompile=false?}
    H -- Yes --> I[bail! no precompiled found]
    H -- No --> J[install_compiled fallback]
    D --> K[download tarball from URL]
    G --> K
    K --> L[Record URL in lock_platforms]
    L --> M[verify_checksum\nread/write checksum+size]
    M --> N[verify_github_artifact_attestations]
    N --> O{provenance\ndowngrade check}
    O -- Pass --> P[untar + patch sysconfig]
    O -- Fail --> Q[bail! downgrade attack]
Loading

Greploops — Automatically fix all review issues by running /greploops in Claude Code. It iterates: fix, push, re-review, repeat until 5/5 confidence.
Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal.

Reviews (2): Last reviewed commit: "test(python): add e2e test verifying loc..." | Re-trigger Greptile

@hehaoqian
Copy link
Copy Markdown
Contributor Author

Not really ready. Fully AI generated. Better look at the bug manually when I have time.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances the Python plugin's lockfile handling by ensuring that mise prioritizes the download URL specified in the lockfile for a given platform over recomputing it. A new end-to-end test was added to validate this behavior by verifying that mise attempts to download from a deliberately corrupted lockfile URL, leading to a failure. Additionally, a new helper function lockfile_url_for_platform with comprehensive unit tests was introduced to facilitate this logic. There is no feedback to provide.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an issue where the core Python plugin could recompute the python-build-standalone download URL during install instead of using the URL already recorded in mise.lock, improving reproducibility and aligning installs with locked artifacts.

Changes:

  • Prefer an existing per-platform URL from tv.lock_platforms when installing precompiled Python, falling back to computing the URL only when absent.
  • Add unit tests for the lockfile URL lookup helper.
  • Extend the Python lockfile E2E test to ensure installs obey the lockfile URL (and fail when it’s deliberately corrupted).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/plugins/core/python.rs Uses lockfile-stored platform URL as the source of truth for precompiled Python downloads; adds helper + unit tests.
e2e/lockfile/test_lockfile_python Adds an E2E regression check that a tampered lockfile URL is actually used during install.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jonathan-guihard
Copy link
Copy Markdown

Any update on this one?

When a URL is already recorded in mise.lock for the current platform,
use it directly instead of recomputing from the remote version index.
This ensures locked installs are reproducible.

Fixes jdx#8749

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jdx jdx marked this pull request as ready for review April 4, 2026 17:00
@jdx jdx force-pushed the copilot/fix-bug-in-discussion-8749 branch from b6d6247 to 586db4f Compare April 4, 2026 17:02
Corrupts the lockfile URL to a fake value and asserts that mise install
fails trying to download from it, proving the lockfile URL is used
instead of being recomputed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jdx jdx changed the title fix(python): Obey python url in lock file fix(python): use lockfile URL for precompiled installs Apr 4, 2026
@jdx jdx merged commit 438ebe1 into jdx:main Apr 4, 2026
35 checks passed
jdx pushed a commit that referenced this pull request Apr 5, 2026
### 🚀 Features

- **(ci)** auto-convert external PRs to draft mode by @jdx in
[#8896](#8896)
- **(deps)** add `depends` field for user-specified tool dependencies by
@cprecioso in [#8776](#8776)
- **(dotnet)** support runtime-only installs by @fragon10 in
[#8524](#8524)
- **(npm)** apply install_before to transitive dependencies by @risu729
in [#8851](#8851)
- **(task)** allow passing arguments to task dependencies via
{{usage.*}} templates by @jdx in
[#8893](#8893)
- add options field to BackendListVersionsCtx by @esteve in
[#8875](#8875)

### 🐛 Bug Fixes

- **(backend)** filter PEP 440 .dev versions in fuzzy version matching
by @richardthe3rd in [#8849](#8849)
- **(ci)** update COPR BuildRequires rust version to match MSRV 1.88 by
@jdx in [#8911](#8911)
- **(ci)** add Ruby build dependencies to e2e Docker image by @jdx in
[#8910](#8910)
- **(ci)** add missing build dependencies to e2e Docker image by @jdx in
[#8912](#8912)
- **(ci)** add missing build dependencies to e2e Docker image by @jdx in
[#8914](#8914)
- **(ci)** use Node 24 LTS for corepack e2e test by @jdx in
[#8915](#8915)
- **(ci)** add libxml2 and pkg-config to e2e Docker image by @jdx in
[#8917](#8917)
- **(ci)** add libxml2-dev to e2e image and disable Swift SPM tests by
@jdx in [#8918](#8918)
- **(docs)** use sans-serif font for badges by @jdx in
[#8887](#8887)
- **(env)** parse --env=VALUE and -E=VALUE flag forms correctly by @jdx
in [#8889](#8889)
- **(exec)** use i64::from() for seccomp syscall numbers to survive
autofix by @jdx in [#8882](#8882)
- **(github)** preserve tool options like filter_bins when version
specified via CLI by @jdx in
[#8888](#8888)
- **(github)** use alias-specific options when tool_alias has its own
config by @jdx in [#8892](#8892)
- **(install)** add locked_verify_provenance setting and detect github
attestations at lock time by @jdx in
[#8901](#8901)
- **(lock)** prune stale version entries during filtered `mise lock
<tool>` runs by @altendky in
[#8599](#8599)
- **(python)** use lockfile URL for precompiled installs by @hehaoqian
in [#8750](#8750)
- **(release)** verify all build targets succeed before releasing by
@jdx in [#8886](#8886)
- **(ruby)** support build revisions for precompiled binaries in
mise.lock by @jdx in [#8900](#8900)
- **(swift)** fall back to Ubuntu 24.04 for unsupported Ubuntu versions
by @jdx in [#8916](#8916)
- **(zsh)** avoid duplicate trust warning after cd by @timothysparg in
[#8898](#8898)
- update flake.lock and add fix for rust-bindgen to default.nix by
@esteve in [#8874](#8874)
- when direnv diff is empty, do not try to parse it by @yaleman in
[#8857](#8857)
- skip trust check for plain .tool-versions in task list by @dportalesr
in [#8876](#8876)

### 🚜 Refactor

- **(go)** rename go_* settings to go.* namespace by @jdbruijn in
[#8598](#8598)

### 📚 Documentation

- **(tasks)** clarify task_config.includes behavior by @risu729 in
[#8905](#8905)

### 🧪 Testing

- **(ci)** run e2e tests inside Docker containers by @jdx in
[#8899](#8899)

### 📦️ Dependency Updates

- bump ubi from 0.8 to 0.9 by @jdx in
[#8906](#8906)
- bump zip from 3 to 8 by @jdx in
[#8908](#8908)
- update lockfile deps (hold back rattler) by @jdx in
[#8909](#8909)
- update bun.lock by @jdx in
[#8913](#8913)

### 📦 Registry

- add turso
([github:tursodatabase/turso-cli](https://github.com/tursodatabase/turso-cli))
by @kenn in [#8884](#8884)
- remove carp test by @jdx in
[#8894](#8894)

### Chore

- **(ci)** add workflow to warn PRs modifying vendored aqua-registry by
@jdx in [#8897](#8897)
- **(ci)** use github.token for draft conversion in auto-draft workflow
by @jdx in [#8903](#8903)
- remove deprecated settings older than 12 months by @jdx in
[#8904](#8904)

### New Contributors

- @dportalesr made their first contribution in
[#8876](#8876)
- @timothysparg made their first contribution in
[#8898](#8898)
- @hehaoqian made their first contribution in
[#8750](#8750)
- @jdbruijn made their first contribution in
[#8598](#8598)
- @cprecioso made their first contribution in
[#8776](#8776)
- @yaleman made their first contribution in
[#8857](#8857)
- @kenn made their first contribution in
[#8884](#8884)
- @fragon10 made their first contribution in
[#8524](#8524)

## 📦 Aqua Registry Updates

#### New Packages (6)

- [`ahkohd/oyo`](https://github.com/ahkohd/oyo)
- [`bellicose100xp/jiq`](https://github.com/bellicose100xp/jiq)
- [`kurama/dealve-tui`](https://github.com/kurama/dealve-tui)
- [`micahkepe/jsongrep`](https://github.com/micahkepe/jsongrep)
- [`textfuel/lazyjira`](https://github.com/textfuel/lazyjira)
- [`ubugeeei/vize`](https://github.com/ubugeeei/vize)

#### Updated Packages (1)

- [`sigstore/cosign`](https://github.com/sigstore/cosign)
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.

4 participants