Skip to content

Fix requirements pin dropped at a dangling EOF \ (#1249) - #1254

Merged
Mikola Lysenko (mikolalysenko) merged 2 commits into
mainfrom
agent/fix-requirements-eof-continuation
Oct 9, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 2 commits into
mainfrom
agent/fix-requirements-eof-continuation

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

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

Fixes #1249

Root cause

utils::requirements::logical_lines joins a \ continuation only when a
physical line follows it, and strips the backslash only from lines that
have a successor. A file whose last line is six==1.16.0 \ (no line
after it) keeps the backslash in the logical line's text, so
exact_pin rejects it and lock-only discovery never requests the purl.
pip's req_file.join_lines strips the backslash from every continued
line and flushes the pending line at EOF, so it installs six==1.16.0.

Change

logical_lines now also strips the backslash of a continued line that
ends the file (not a comment line). physical stays raw, so the
vendored writer's recorded original and revert are unchanged. Every
reader of the shared lexer benefits: lock-only discovery
(inventory_requirements_txt, root file and -r tree), the vendored
requirements planner and vex::discover::pypi_other. The hosted
redirect rewriter has its own lexer and keeps refusing the line with
redirect_requirements_continuation. Now that discovery finds the pin,
a patched package gets that warning instead of no output at all.

No wrapper changes: npm/, pypi/ and gem/ only dispatch to the binary.

Formatting-only files: 18 of the 22 changed files are cargo fmt --all output only (import order and line wrapping, no token changes), because main currently fails cargo fmt --all -- --check. The functional diff is utils/requirements.rs, vendor/lock_inventory/tests.rs and tests/scan_requirements_lock_only.rs.

Tests (red on main, green with the fix)

Issue variant Test
#1249 lexer, LF / CRLF / no newline, hashed tail, comment control utils::requirements::tests::lexer_strips_a_dangling_continuation_at_eof
#1249 lock inventory, root file + -r include vendor::lock_inventory::tests::requirements_dangling_eof_continuation_is_inventoried
#1249 end to end: scan sends the purl (default + --mode vendored) scan_requirements_lock_only::lock_only_scan_discovers_pin_with_dangling_eof_continuation

All three failed before the fix (lexer kept \; inventory returned
None; the CLI never sent the purl) and pass after it.

Local checks

  • cargo fmt --all -- --check: clean
  • cargo clippy --workspace --all-features -- -D warnings: clean
  • cargo test -p socket-patch-core --all-features: 5980 passed, 4 failed. The same 4 fail on origin/main here: they are permission tests that don't hold when run as root (wire_failure_rolls_back_already_written_files, wire_write_failure_maps_error_and_leaves_lock_untouched, an_unremovable_hidden_lock_keeps_every_store_entry, relax_loop_must_not_traverse_symlinked_root).
  • CLI suites scan_requirements_lock_only, scan_vendor_requirements_unwired, e2e_vex_redirect, policy_pypi_names, in_process_vendor_pypi_takeover: all pass. In mode_migration_pypi, 44 pass and 1 fails (pipenv_hosted_to_vendored_names_the_unpatched_requirements); it fails identically on origin/main in this sandbox.
  • The full cargo test --workspace didn't fit in this sandbox's disk (linker hit ENOSPC), so CI is the full run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XSB4zeguGS1uuS1Ji5LBjg


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
A requirements file whose last line is `six==1.16.0 \` with nothing
after it was read with the backslash still attached, so scan never
asked the patch API about six and reported "No patches" while pip
installed the unpatched release. pip strips that dangling backslash
and reads the line as `six==1.16.0`; the shared requirements lexer
now does the same, so lock-only discovery, the vendored planner and
VEX discovery all see the pin, in the root file or a `-r` include,
with LF or CRLF endings.

Hosted rewrites keep refusing such a line with
redirect_requirements_continuation; discovery now finds the pin,
so a patched package gets that warning instead of silence.

Fixes #1249

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) force-pushed the agent/fix-requirements-eof-continuation branch from ea1f5cc to 8e23559 Compare October 9, 2026 09:34
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 9, 2026 09:54
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 8e23559. Configure here.

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

Copy link
Copy Markdown
Collaborator Author

Labeled Ready for review by the burn-down agent.

  • Head: 8e23559cf87333aabbad07842185d6a35a507ca8
  • CI: all 512 check runs on this head completed success/skipped/neutral; no merge conflict with main.
  • Bugbot: reviewed this head, no findings; no unresolved review threads.
  • CHANGELOG.md untouched.

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Final review brief (8e23559cf)

What it does: Fixes #1249. A requirements pin on the last line of the file that ends in a dangling \ (six==1.16.0 \ at EOF) kept its backslash, so exact_pin rejected it and scan never sent that purl. pip strips the backslash and installs the pin. logical_lines now strips a continuation that ends the file, unless the line is a comment. physical stays raw, so the vendored writer's recorded original and revert are unchanged.

Risk: low. The functional change is one condition (|| dangling), and it can only fire at EOF, so joins in the middle of a file behave as before. The hosted redirect has its own lexer and still refuses with redirect_requirements_continuation.

Look here:

Verified:

  • I removed || dangling locally and all three new tests failed (the CLI one reports lockfileOnlyPackages 0 instead of 1). With the fix restored they pass.
  • requirements lib tests: 125 pass. The 1 failure, wire_failure_rolls_back_already_written_files, can't pass as root and also fails on main. lock_inventory: 143 pass. pypi_other: 22 pass. scan_requirements_lock_only: 9/9 pass.
  • Edge cases checked: CRLF and no trailing newline (both tested), BOM, a # comment \ at EOF (not stripped, tested), empty file.
  • cargo clippy -p socket-patch-core --all-features -D warnings is clean. fmt --check is clean on the head.
  • CHANGELOG.md untouched. CI 512/512 success/skipped (ci-ok and clippy green), Bugbot success, no review threads, mergeable.

Changes I made: none.

Open questions / non-blocking notes:

  • 18 of the 22 files are whitespace-only rustfmt churn (import order, line wrapping; main currently fails fmt --check). I checked that none of them changes a token, but the description doesn't mention them.
  • six==1.16.0 \ with a trailing space is now accepted as a pin at EOF, while pip wouldn't treat that as a continuation. The lexer already behaved this way in the middle of a file.

Auto-merge is armed, so approving sends it straight to the merge queue.


Generated by Claude Code

@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 9, 2026
Merged via the queue into main with commit 40de3d5 Oct 9, 2026
544 of 545 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-requirements-eof-continuation branch October 9, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

3 participants