Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Vendored scan of a Pipenv `use_pylock = true` project wires only pylock.toml, but Pipenv installs from Pipfile.lock, so `pipenv sync` / `install --deploy` install the unpatched release after a "success" run

クローズ 初心者向け
#1,122 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

関連するプルリクエストがすでにマージされています。

  • #1193 @mikolalysenko による — マージ済み

評価

難易度
2/5
見積もり時間
1時間未満
初心者へのやさしさ
85/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python, rust
領域
devtools

調査の方向性

不具合はPyPIの種類判定ロジックにあります。crates/socket-patch-core/src/vendor/pypi.rsの251行目付近と、crates/socket-patch-core/src/formats/governing_locks.rsの115行目付近から調べてください。PipfileとともにPipfile.lockとpylock.tomlの両方が存在する場合に、ツールがPipfile.lockを基準となるロックファイルとして選択する(または両方を接続する)よう、ロックファイルの優先順位を調整してください。修正を確認するため、関連するテストを実行してください。

索引モデルが issue の本文から書いたものです。

説明

agent:triaged bug bughunt pm:pipenv priority:p1

[agent] Found by the scheduled Pipenv bug-hunt routine (ledger #313).

Summary

With [pipenv] use_pylock = true in the Pipfile, Pipenv 2026's pipenv lock writes both Pipfile.lock and pylock.toml. The pylock.toml carries [tool.pipenv] generated_from = "Pipfile.lock". When both files are present, Pipenv installs from Pipfile.lock: pipenv sync and pipenv install --deploy take the bytes from Pipfile.lock and ignore pylock.toml. I verified this below on 2026.0.0, 2026.4.0 and 2026.8.0.

scan --mode vendored routes this layout to the standalone python-lock flavor, because detect_pypi_flavor step 2 (a standalone pylock*.toml that contains the package) ranks above step 5 (Pipfile.lock → pipenv). So it rewrites only pylock.toml (archive = { path = ".socket/vendor/pypi/<uuid>/…whl" }) and leaves Pipfile.lock on PyPI. The run reports status: success, exit 0, "Vendored 1 package". Its only warning is pypi_multiple_lockfiles: "wiring pylock.toml; installs driven by Pipfile.lock retain their existing sources".

So every Pipenv install afterwards puts the unpatched upstream release in place. Hosted mode handles the same layout correctly: it pins both files, and pipenv sync gives the patched bytes.

This is distinct from #912. #912 is the pylock-only checkout, where Pipenv reads pylock.toml and drops archive. #912 already notes that with both files present "Pipenv installs from Pipfile.lock", which is exactly why vendoring the pylock alone misses here.

Impact

  • The documented use_pylock = true layout, vendored, never gets the patch in any Pipenv install (CI, Docker, --deploy), although the scan says it vendored the package.
  • The user-visible remedy is awkward. vendor --check (exit 1) says to delete whichever lock the project doesn't install from, but pipenv lock regenerates pylock.toml while use_pylock = true is set, and the next vendored run wires it again.
  • vex refuses, as it should (pkg:pypi/[email protected] is wired … but Pipfile.lock resolves the same version from elsewhere, exit 1). So there's no false attestation. The defect is that the wrong file is chosen as the governing lock.

Repro (Linux; real Pipenv 2026.8.0, py3.11; local mock patch API serving a patched six 1.16.0 wheel)

mkdir app && cd app
cat > Pipfile <<'EOF'
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
six = "==1.16.0"

[requires]
python_version = "3.11"

[pipenv]
use_pylock = true
EOF
pipenv lock                                   # writes Pipfile.lock AND pylock.toml
socket-patch scan --mode vendored --yes       # exit 0, "Vendored 1 package."
                                              # Warning: wiring pylock.toml; installs driven by Pipfile.lock retain their existing sources
grep -c socket/vendor Pipfile.lock            # 0
grep -c socket/vendor pylock.toml             # 1
pipenv --rm; pipenv install --deploy
pipenv run python -c "import six; print('SOCKET-PATCHED' in open(six.__file__).read())"   # False
pipenv --rm; pipenv sync                      # same: False
socket-patch vendor --check                   # exit 1: wiring contested
socket-patch vex --offline --product pkg:pypi/[email protected] -O vex.json   # exit 1, refuses

# Control: the same project, hosted
socket-patch scan --mode hosted --yes         # rewrittenFiles: [Pipfile.lock, pylock.toml]
pipenv --rm; pipenv sync                      # patched
# Which file Pipenv reads: hosted Pipfile.lock + pristine pylock.toml -> sync / --deploy give the PATCHED bytes

scan --mode vendored --dry-run previews the same pylock-only wiring. Reproduced 2/2 on 2026.8.0, plus once each on 2026.0.0 and 2026.4.0.

Expected vs actual

  • Expected: vendored wires the file the project's installer reads. When a Pipfile sits beside both locks (and pylock.toml says generated_from = "Pipfile.lock"), that's Pipfile.lock. The flavor router's own doc says it routes by "this tool manages installs". docs/ecosystems.md lists Pipenv Pipfile.lock vendoring as supported ("every Pipfile.lock category is rewired"). It would also be reasonable to wire both files, as hosted mode does. CLI_CONTRACT.md: "A dep counts as redirected only when its hosted-artifact URL … actually landed in a project file". The vendored analogue is a rewrite the installer honours.
  • Actual: only pylock.toml is wired, and Pipenv ignores it while Pipfile.lock exists. The scan succeeds, and every Pipenv install is unpatched.

OS × version

Pipenv both locks written by pipenv lock vendored wires pipenv sync / --deploy after vendored control: hosted Pipfile.lock + pristine pylock.toml
2026.0.0 yes pylock.toml only UPSTREAM PATCHED
2026.4.0 yes pylock.toml only UPSTREAM PATCHED
2026.8.0 yes pylock.toml only (2/2) UPSTREAM (sync and --deploy) PATCHED
≤ 2025.x n/a (no pylock support)
macOS / Windows not probed (the routing is pure path-presence logic)

First bad version

Not bisected. v4.0.0 has no pylock vendoring, so this is unreleased v5 behaviour on main b96a785. #1044 moved the tool-lock order into formats/governing_locks.rs (PYPI_TOOL_LOCKS), but the standalone-lock branch that wins here sits before that table and predates it.

Suspect code

  • crates/socket-patch-core/src/vendor/pypi.rs:251 (doc, step 2) and :310–:324: if !has_uv_lock && matching_additional_lock { … return Ok((PypiFlavor::PythonLocks, warnings)) }. Any standalone pylock that contains the package beats Pipfile.lock, and nothing checks for a Pipfile or a [tool.pipenv] table in the pylock.
  • crates/socket-patch-core/src/formats/governing_locks.rs:115: PYPI_TOOL_LOCKS doesn't place Pipenv-generated pylocks relative to Pipfile.lock.

Related: #912 (pylock-only Pipenv checkout; Pipenv drops archive), #612 (pypi_multiple_lockfiles for a sibling requirements.txt), #1114 (inventory vs router disagreement on empty poetry / pdm locks).

主要言語
Rust
スター
8
フォーク
1
平均マージ
19時間 1分
マージ済み PR(30日)
473

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

SocketDev/socket-patch のほかの issue

SocketDev/socket-patch の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。