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 lock-only requirements.txt discovery (#412, #523) by mikolalysenko · Pull Request #530 · SocketDev/socket-patch

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 2, 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 #412
Fixes #523

Summary

A pip project with no venv yet (a fresh clone, a CI job or a Docker build) is discovered through the lockfile-only requirements.txt inventory. That inventory missed two common ways of writing pins, so those packages never reached the patch API. scan printed "No patches available" and exited 0 in both hosted and vendored mode, and pip install -r requirements.txt then installed the unpatched release. With this PR, discovery reads the same pins pip installs.

Root cause

inventory_requirements_txt in vendor/lock_inventory/pypi.rs read requirements differently from both pip and socket-patch's own writers:

  • Lockfile-only scan ignores pins in requirements.txt -r includes, so a fresh checkout reports "No patches available" and installs unpatched (hosted and vendored) #412: it read only the root requirements.txt and skipped -r lines without following them. The vendored writer, by contrast, already walks every in-root include.
  • Lockfile-only requirements.txt discovery skips exact pins written with spaces (six == 1.15.0, six (==1.15.0)), so a fresh checkout reports "No patches available" and pip installs the unpatched release #523: it recognized pins with utils::requirements::exact_pin, which only looked at the first whitespace token. So six == 1.15.0, six ==1.15.0, six== 1.15.0, six[x] == 1.15.0 and the legacy six (==1.15.0) weren't seen as pins. pip and the hosted rewriter (requirement_version) both accept all of these.

Changes

  • utils::requirements::exact_pin now parses the requirement the way pip does: name, then optional extras, optional parentheses and ==, with whitespace allowed between them. Only options (--hash=…) may follow the version. As a side effect, a range like six==1.0,<2 is no longer mistaken for the pin 1.0,<2. Lock-only vex discovery (vex::discover::pypi_other) uses the same function and gets the fix too.
  • vendor::pypi_requirements::requirements_includes is the include parser pulled out of the vendored writer's walk, now shared. is_in_root_rel is now pub(crate).
  • inventory_requirements_txt reads the root file plus every in-root -r / --requirement include through a new requirements_tree walk. The walk runs over the ProjectView, so the in-memory hosted engine reads the same tree. It resolves each include relative to the including file, guards against cycles, never follows -c constraints, and skips out-of-root or absolute includes, matching the writer. The public_index rule (an index option makes hashed pins unverifiable) now spans the whole tree, because pip applies options from any file globally.

In hosted mode, an installed pin that lives only in an include is documented as rewrite-refused (redirect_requirements_entry_not_found). Lock-only checkouts now reach that same documented path instead of silently skipping the package.

Tests (red → green)

Issue Test Without fix With fix
#523 utils::requirements::tests::exact_pin_is_the_shared_registry_pin_rule (spaced, tab, paren and extras forms; ==1.*, ,<2 and stray-paren negatives) FAILED ok
#523 vendor::lock_inventory::tests::requirements_spaced_and_parenthesised_pins_are_inventoried FAILED ok
#523 scan_requirements_lock_only::lock_only_scan_discovers_spaced_pins (built binary; hosted + vendored; purls must reach /patches/batch) FAILED ok
#412 vendor::lock_inventory::tests::requirements_in_root_includes_are_inventoried (nested and relative includes, --requirement=, -rfile, cycle, -c and ../ not followed, ProjectView::Memory) FAILED ok
#412 vendor::lock_inventory::tests::requirements_index_option_in_an_include_spans_the_tree FAILED ok
#412 scan_requirements_lock_only::lock_only_scan_discovers_included_pins (built binary; hosted + vendored) FAILED ok

Validation

  • cargo clippy --workspace --all-features -- -D warnings: clean.
  • cargo test --workspace --all-features --no-fail-fast: 214 targets. 12 tests fail only because this sandbox runs as root, which ignores the read-only or unremovable fixtures they rely on (*_write_failure_*, *unremovable*, relax_loop_must_not_traverse_symlinked_root). All 12 pass when re-run as a non-root user. Everything else passes.
  • cargo test -p socket-patch-cli --test e2e_vex_build -- pip:: --ignored (real pip, every major, hosted + vendored → manifest-less VEX): ok.
  • cargo fmt --all -- --check is not clean on main itself with the pinned 1.93.1 toolchain (128 files), and CI doesn't run it. The files this PR touches are rustfmt-clean, and no unrelated files were reformatted.
  • The npm, pypi and gem wrappers are unaffected: the change is entirely in the Rust core.
  • CI on acb0abb: 477 success, 6 skipped (matrix templates and canary/downgrade), 0 failed. native (ubuntu-latest, 2.9.3) failed once in its PDM extras vendored lane (appliedExactlyOne). That lane reads pdm.lock and never reaches the requirements.txt inventory, and it passed on its single re-run.
  • Cursor Bugbot on acb0abb: no issues found.

Follow-ups

None.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JASDoVJNrZUBy9kd7fWPxN


Generated by Claude Code

Sorry, something went wrong.

Uh oh!

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

All reactions
@claude
Start fix for #412, #523
3fce3bc
Assisted-by: Claude Code:claude-opus-5-5
This was referenced Oct 2, 2026
Lockfile-only scan ignores pins in requirements.txt -r includes, so a fresh checkout reports "No patches available" and installs unpatched (hosted and vendored) #412
Closed
Lockfile-only requirements.txt discovery skips exact pins written with spaces (six == 1.15.0, six (==1.15.0)), so a fresh checkout reports "No patches available" and pip installs the unpatched release #523
Closed
Claude (claude) added 2 commits October 2, 2026 04:46
@claude
Read spaced requirements.txt pins as exact
e1a6198
A requirements.txt pin written with spaces around `==` (`six ==
1.15.0`), or in the legacy `six (==1.15.0)` form, was not recognized
as an exact pin. On a fresh checkout with no venv, lock-only discovery
never asked the patch API about the package. scan reported "No patches
available" and pip installed the unpatched release. pip treats these
forms exactly like `six==1.15.0`, and so does the hosted rewriter.

exact_pin now parses the name, extras, optional parentheses and `==`
the way pip does. Only options may follow the version, so a range such
as `six==1.0,<2` is no longer mistaken for a pin. Lock-only `vex`
evidence uses the same rule and gets the fix too.

Fixes #523

Assisted-by: Claude Code:claude-opus-5-5
@claude
Discover pins in requirements.txt -r includes
acb0abb
On a fresh checkout, lock-only discovery read only the root
requirements.txt and skipped its `-r` include lines. A pin kept in an
included file (`-r requirements/base.txt`) was never sent to the patch
API. scan reported "No patches available", exited 0, and pip installed
the unpatched release, in both hosted and vendored mode.

The lock inventory now walks the same in-root include tree the
vendored writer edits, using the writer's include parser. The walk runs
through the project view, so the in-memory hosted engine sees it too.
`-c` constraints and out-of-root includes are still not followed. An
index option in any file of the tree now makes hashed pins
unverifiable everywhere, matching how pip applies options globally.

Fixes #412

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 2, 2026 05:12
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 2, 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 Oct 2, 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 acb0abb. 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 2, 2026
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Ready for review at acb0abb.

  • CI: all required checks green on acb0abb (latest run per check; no failures, Bugbot neutral).
  • Mergeable against main, no conflicts.
  • Cursor Bugbot reviewed acb0abb: no issues found; no unresolved review threads.
  • Reviewer focus: the requirements.txt lock-only inventory now follows -r includes and matches pins the way pip / socket-patch's writers do (Lockfile-only scan ignores pins in requirements.txt -r includes, so a fresh checkout reports "No patches available" and installs unpatched (hosted and vendored) #412, Lockfile-only requirements.txt discovery skips exact pins written with spaces (six == 1.15.0, six (==1.15.0)), so a fresh checkout reports "No patches available" and pip installs the unpatched release #523).

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) mentioned this pull request Oct 2, 2026
Fix vendored rescans failing on unwired ledger entries (#541) #543
Merged
Tanmay182003
Tanmay Singla (Tanmay182003) approved these changes Oct 2, 2026
View reviewed changes
@mikolalysenko

Mikola Lysenko (mikolalysenko) commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Reviewed acb0abb5f4130b8d3ef52a48dcb6c2a8a53fa4f2. Recommendation: ready to merge as-is from code review.

No actionable correctness/security regressions found. Checked pin parsing, relative includes/cycle guards, in-memory parity, global index-option handling, and the shared writer/VEX behavior.

Validation: cargo test -p socket-patch-core --lib requirements — 87 passed; cargo test -p socket-patch-cli --test scan_requirements_lock_only — 2 passed, exercising hosted and vendored discovery through the binary. Full workspace/platform matrix not rerun.

All reactions

Sorry, something went wrong.

Uh oh!

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

@mikolalysenko
Mikola Lysenko (mikolalysenko) merged commit d63ae5f into main Oct 2, 2026
527 of 528 checks passed

Uh oh!

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

@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-requirements-lock-inventory branch October 2, 2026 14:28
This was referenced Oct 2, 2026
Hosted scan in a Pipenv project whose requirements.txt pins the package through an -r include rewires only Pipfile.lock, then reports success while vex and rollback refuse the contested lock it just created #567
Closed
Benchmark tracking: socket-patch scan #580
Open
Lock-only requirements.txt discovery drops a pin whose last line ends in a dangling \ continuation (six==1.16.0 \ at EOF): scan exits 0 with "No patches", but pip installs it #1249
Closed
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
@Tanmay182003 Tanmay Singla (Tanmay182003) Tanmay182003 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.

Lockfile-only requirements.txt discovery skips exact pins written with spaces (six == 1.15.0, six (==1.15.0)), so a fresh checkout reports "No patches available" and pip installs the unpatched release Lockfile-only scan ignores pins in requirements.txt -r includes, so a fresh checkout reports "No patches available" and installs unpatched (hosted and vendored)

Uh oh!

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

3 participants

@mikolalysenko @Tanmay182003 @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.