GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix requirements.txt writers ignoring pip hash mode (#376) by mikolalysenko · Pull Request #383 · SocketDev/socket-patch

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Sep 30, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #376

Summary

Hosted and vendored scans no longer break pip install -r on a requirements.txt that has no hashes.

Scope: this PR originally also fixed #378 (setup writing an unhashed hook line into a hash-pinned requirements.txt). #277 removed the setup command, so that part was dropped when main was merged in at a2dedc5, and #378 was closed as no longer applicable.

Root cause

pip's hash-checking mode is all or nothing. It turns on for the whole install as soon as any requirement carries --hash, and then every requirement, transitive dependencies included, has to be ==-pinned and hashed. The hosted redirect (patch/redirect/requirements.rs) and the vendored writer (vendor/pypi_requirements.rs::vendor_line) always added --hash, without checking which mode the requirements set was in. In an unhashed file that switches the mode on, and pip then refuses every other line.

Fix

  • Shared check: utils::requirements::requires_hashes. It is true when any line has a --hash option (any algorithm) or the file sets --require-hashes. Comments and URL #sha256= fragments don't count.
  • Hosted: a hashed file keeps --hash on the patched line, as before. An unhashed file gets name @ <url>#sha256=<hex> instead. Checked by hand:
    • pip 24 and uv 0.8 both verify the fragment (a wrong hash fails the install);
    • the fragment does not turn on pip's hash mode for other lines;
    • it also satisfies hash mode when that mode is on;
    • VEX already reads it (integrity_of).
  • Vendored: the mode is taken from the whole requirements tree (the root file plus its -r includes). A hashed tree keeps the vendor line unchanged. An unhashed tree gets the committed wheel path with no --hash, because pip can't read a fragment on a bare path. The inventory, VEX and the in-sync ledger fallback already accept a hashless vendor line.
    • Rebuild guard: when there is no ledger entry, the in-sync rebuild guard falls back to the pin on the wired line. A hashless line now still pins its wheel path (wired_pin_in returns an empty sha256 and pin_matches checks the path only). A rebuild under another filename is refused instead of leaving the line pointing at a missing file. Bugbot found this; it is fixed in fcc4fcc.
  • Re-scans are no-ops: every line counts toward the mode, the writer's own lines included, so a re-scan never flips a file between the two shapes. A file that an older version already wrote with --hash into an unhashed set keeps that shape; running rollback followed by a re-scan rewrites it in the new form.

Checklist

  • Hosted: redirect::requirements::tests::unhashed_file_pins_the_artifact_by_url_fragment_not_hash_option and hashed_file_keeps_the_hash_option. Both were red before the fix and are green after.
  • Vendored: vendor::pypi_requirements::tests::unhashed_requirements_get_an_unhashed_vendor_line (red → green) and hashes_in_an_include_keep_the_vendor_line_hashed.
  • Vendored rebuild guard: vendor::pypi::tests::in_sync_ledgerless_rebuild_of_unhashed_line_keeps_the_wired_path (red → green).
  • Real pip: a new unhashed cell (six==1.16.0 + idna==3.7) in e2e_vex_build::pip. Locally on pip 24.3.1 every hosted and vendored step passes: wire, install-patched, manifest-less VEX, re-scan.
  • Shared check: utils::requirements::tests::requires_hashes_reads_pip_hash_checking_mode.

Test updates (intended behavior change)

Several existing tests expected --hash in unhashed files, which is the #376 bug itself. They now expect the unhashed forms:

  • the unit tests in the hosted and vendored writers;
  • the redirect fixture and the VEX discovery golden (redirect-pypi.json);
  • in_process_get_hosted_ecosystems, e2e_hosted_production, e2e_vendored_production and e2e_vendor_pypi_build.

Two tests needed more than a new expected string:

  • vendor_ledger_schema_e2e: the base-binary parity test now names this one intended difference. The legacy fixtures are unchanged, so the legacy-revert coverage stays.
  • The pin-guard tests and the marker e2e rely on a hashed pin, so their inputs are now hash-pinned.

An earlier commit on this branch accidentally reformatted about 55 unrelated files, and e0ed1aa reverts them. main isn't rustfmt-clean and CI doesn't check formatting, so this PR leaves formatting alone.

Evidence

  • cargo clippy --workspace --all-features -- -D warnings: clean on fcc4fcc.
  • cargo test --workspace --all-features (local, sandbox runs as root): every failure is a test that needs a write, removal or permission check to fail, which root bypasses. None exercises code this PR changes.
  • SOCKET_PATCH_PIP_E2E_VERSIONS=24 SOCKET_PATCH_PIP_E2E_REQUIRED=1 cargo test -p socket-patch-cli --all-features --test e2e_vex_build -- pip:: --ignored: passes for all 4 cells × 2 modes (pre-merge).
  • CI is green on fcc4fcc, and Bugbot found no new issues on it.
  • Not touched: the npm, pypi and gem wrappers (they only dispatch to the binary).

🤖 Generated with Claude Code

https://claude.ai/code/session_017aQf44e9818AbFKDYnuAHZ


Note

Medium Risk
Changes how hosted and vendored requirements.txt pins are written, which affects install behavior for mixed hashed/unhashed projects; behavior is heavily tested but wrong detection could weaken or break installs.

Overview
Fixes pip breaking when requirements.txt is patched in an unhashed tree (#376). Hosted and vendored rewrites no longer unconditionally add --hash, which turns on pip’s global hash-checking mode and rejects every other requirement.

A shared requires_hashes helper detects whether the file (or included tree) is already in hash-checking mode. Hosted redirects pin integrity with a URL #sha256= fragment when the file is unhashed, and keep --hash when it is already hashed. Vendored wheel lines omit --hash in unhashed trees (path-only pin); the in-sync rebuild guard treats an empty sha256 as path-only via pin_matches.

CLI contract, redirect/VEX fixtures, and e2e tests (including a new pip VEX unhashed cell) are updated to match the new shapes.

Reviewed by Cursor Bugbot for commit fcc4fcc. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@claude
Start fix for #376, #378
9efcc00
Assisted-by: Claude Code:claude-opus-5-5
This was referenced Sep 30, 2026
Hosted and vendored requirements.txt rewrites add a --hash to one line, which turns on pip's hash-checking mode and breaks pip install -r for every other unhashed line #376
Closed
setup appends an unpinned, unhashed socket-patch[hook] line to a hash-pinned requirements.txt, so pip install -r fails in hash-checking mode #378
Closed
Claude (claude) added 5 commits September 30, 2026 21:42
@claude
Keep unhashed requirements.txt installable
04ecd70
A hosted or vendored scan added --hash to the patched line of a
requirements file that had no hashes. pip then turns on hash-checking
mode for the whole install, so every other requirement and every
transitive dependency failed to install (#376).

Both writers now check whether the requirements set is already in
hash-checking mode. If it is, they keep writing --hash as before. If
not, hosted pins the patched wheel with the url's #sha256= fragment,
which pip still verifies, and vendored writes the committed wheel path
without a hash.

Assisted-by: Claude Code:claude-opus-5-5
@claude
Refuse setup on a hash-pinned requirements.txt
7279f36
socket-patch setup appended an unpinned, unhashed socket-patch[hook]
line to requirements.txt even when the file (or an -r include) was in
pip's hash-checking mode. pip then refused to install anything from it,
while setup reported success (#378).

setup now reports an error and leaves such a file untouched. setup
--remove also drops a hook line together with its backslash
continuation lines, so no stray --hash line is left behind.

Assisted-by: Claude Code:claude-opus-5-5
@claude
Cover a two-line unhashed file in the pip e2e
92ec619
Adds an 'unhashed' cell (six plus idna, no hashes) to the real-pip
capstone. It asserts the wiring adds no --hash and that pip installs
the patched six. Also updates the redirect fixture to the #sha256=
url form written for unhashed files.

Assisted-by: Claude Code:claude-opus-5-5
@claude
Expect url-fragment pins in unhashed pip e2e
39ec2d9
The production and vendored e2e legs write a one-line unhashed
requirements.txt and then asserted a --hash pin, which is the #376
behavior itself. They now assert that no --hash is added. The hosted
leg also asserts the #sha256= url pin, which pip and uv both verify.

Assisted-by: Claude Code:claude-opus-5-5
@claude
Align remaining pip tests with hash-mode wiring
642f609
- The VEX discovery golden now shows the #sha256= url on the hosted
  requirements ref.
- The hosted get test expects the url-fragment pin.
- The vendor ledger parity test allows the one intended change from
  the base binary: no --hash in an unhashed requirements.txt.
- The marker e2e installs with --require-hashes, so its input is now
  hash-pinned the way pip-compile writes it.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review September 30, 2026 22:17
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Sep 30, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@claude
Drop unrelated rustfmt churn from the fix
e0ed1aa
An earlier cargo fmt --all run reformatted about 55 files that this
fix doesn't otherwise touch; main isn't rustfmt-clean and CI doesn't
check formatting. This restores those files to main so the PR diff
only holds the hash-mode change and its tests.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Sep 30, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 1, 2026
Hosted rollback, remove and the vendored takeover refuse a requirements.txt whose only requirements are hosted pins (six==1.16.0 alone can be patched but never unpatched) #410
Closed
Mikola Lysenko @claude
Merge origin/main into agent/fix-requirements-hash-mode
a2dedc5
Bring the pip hash-mode fix onto the v5 workflow from #277. Main removed
the setup command, so the #378 hook-dependency guard in
setup/pypi/edit.rs has no home and is dropped with the file. The #376
half still applies: hosted and vendored requirements.txt writers only
emit --hash when the tree is already in pip's hash-checking mode. The
hosted-get test docs keep main's "no ledger" wording with the fragment
pin, and CLI_CONTRACT.md's requirements rows now describe the
conditional --hash.

Co-Authored-By: Claude <[email protected]>
Claude-Session: https://claude.ai/code/session_01GQoii5oP1pwcJh5mzzo1HU
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 1, 2026
View reviewed changes

@cursor cursor Bot left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread crates/socket-patch-core/src/vendor/pypi_requirements.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

@claude
Keep the pin guard on hashless requirements vendor lines
fcc4fcc
A requirements vendor line written into an unhashed requirements set has
no --hash, so wired_pin_in returned no pin and a ledgerless in-sync
rebuild skipped the guard entirely, including the path check. A rebuilt
wheel at another filename would then leave the wired line pointing at a
file that does not exist.

wired_pin_in now pins the path of a hashless line with an empty sha256,
and the guard treats an empty pinned sha256 as path-only. A hash that is
present but malformed still pins nothing, as before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017aQf44e9818AbFKDYnuAHZ
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 1, 2026
Fix pnpm-workspace.yaml key detection and appends (#400, #402) #414
Merged
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Oct 1, 2026
View reviewed changes

@cursor cursor Bot left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit fcc4fcc. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 1, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator Author

[burn-down agent] Ready for review on fcc4fcc: mergeable, 0 commits behind main.

  • CI: all completed checks green on fcc4fcc (3 skipped by workflow conditions).
  • Bugbot: reviewed fcc4fcc, no new issues. Its earlier finding on a2dedc5 (pin guard on hashless vendor lines) is fixed by fcc4fcc; thread resolved.
  • Reviewer note: only the Hosted and vendored requirements.txt rewrites add a --hash to one line, which turns on pip's hash-checking mode and breaks pip install -r for every other unhashed line #376 half remains. The setup appends an unpinned, unhashed socket-patch[hook] line to a hash-pinned requirements.txt, so pip install -r fails in hash-checking mode #378 setup half was dropped when merging main, because v5 prerelease: scan → vex → vendor workflow, hosted by default #277 removed setup; the description now says so. Main thing to review is the hashless path that writes name @ url#sha256=.

Generated by Claude Code

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko Mikola Lysenko (mikolalysenko) changed the title Fix requirements.txt writers ignoring pip hash mode (#376, #378) Fix requirements.txt writers ignoring pip hash mode (#376) Oct 1, 2026
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 1, 2026
Fix Python crawler missing .egg-info installs (#447) #452
Merged
Wenxin-Jiang
Wenxin Jiang (Wenxin-Jiang) approved these changes Oct 1, 2026
View reviewed changes
@mikolalysenko
Mikola Lysenko (mikolalysenko) merged commit bae5d3a into main Oct 1, 2026
488 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-requirements-hash-mode branch October 1, 2026 16:46
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 2, 2026
Hosted requirements.txt rewrite replaces a user's own direct reference (six @ https://mirror/…/six-1.16.0-….whl, file:// fork) with the Socket PyPI build, and rollback then restores six==1.16.0 from PyPI, losing the original source #542
Closed
@Tanmay182003 Tanmay Singla (Tanmay182003) mentioned this pull request Oct 2, 2026
Fix requirements.txt pins not matched under PEP 440 (#475) #478
Merged
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Oct 2, 2026
@claude
Expect #sha256= pin in the PEP 440 hosted-get test
c331d18
Since #383, a hosted scan of a requirements.txt that is not in
hash-checking mode pins the patched wheel with the url's #sha256=
fragment rather than --hash, so the PEP 440 regression test now
expects that form, matching the existing hosted pypi test.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CVbFzTeYSTvB5iKjY6FRg7
Mikola Lysenko (mikolalysenko) added a commit that referenced this pull request Oct 2, 2026
@mikolalysenko @claude
Fix requirements.txt pins not matched under PEP 440 (#475) (#478)
bf0e0d1
* Start fix for #475

Assisted-by: Claude Code:claude-opus-5-5

* Match requirements pins like pip does (PEP 440)

A hand-written pin such as `six==1.16` installs six 1.16.0, but the
hosted requirements.txt rewrite compared versions as raw strings and
skipped it, so `scan` exited 0 and the project stayed unpatched. The
vendored requirements writer and the Hatch rewriter refused the same
pins as "not pinned".

Add a small PEP 440 equality helper (zero-padded release segments,
leading zeros, case and pre/post/dev spellings) and use it for `==`
pins in all three writers. `===` keeps plain string equality, as PEP
440 defines it.

Fixes #475

Assisted-by: Claude Code:claude-opus-5-5

* Test hosted get over a PEP 440-equivalent pin

Mirrors the #475 repro end to end: `get <uuid> --mode hosted` over
`requests==2.31`, `==2.31.0.0` and `Requests==02.31.0` must redirect
the pin to the hosted wheel. Fails on main, passes with the fix.

Assisted-by: Claude Code:claude-opus-5-5

* Expect #sha256= pin in the PEP 440 hosted-get test

Since #383, a hosted scan of a requirements.txt that is not in
hash-checking mode pins the patched wheel with the url's #sha256=
fragment rather than --hash, so the PEP 440 regression test now
expects that form, matching the existing hosted pypi test.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CVbFzTeYSTvB5iKjY6FRg7

---------

Co-authored-by: Claude <[email protected]>
@mikolalysenko Mikola Lysenko (mikolalysenko) mentioned this pull request Oct 5, 2026
Fix pip rollback refusing all-hosted requirements (#410) #827
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@cursor cursor[bot] cursor[bot] left review comments
@Wenxin-Jiang Wenxin Jiang (Wenxin-Jiang) Wenxin-Jiang approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

setup appends an unpinned, unhashed socket-patch[hook] line to a hash-pinned requirements.txt, so pip install -r fails in hash-checking mode Hosted and vendored requirements.txt rewrites add a --hash to one line, which turns on pip's hash-checking mode and breaks pip install -r for every other unhashed line

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@mikolalysenko @Wenxin-Jiang @claude
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.