Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở Phù hợp với người mới
#1,122 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
Dưới một giờ
Mức phù hợp với người mới
85/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python, rust
Lĩnh vực
devtools

Hướng nghiên cứu

Lỗi nằm trong logic phát hiện biến thể PyPI. Bắt đầu từ crates/socket-patch-core/src/vendor/pypi.rs quanh dòng 251 và crates/socket-patch-core/src/formats/governing_locks.rs quanh dòng 115. Điều chỉnh thứ hạng các tệp lock để khi có Pipfile cùng với cả Pipfile.lock và pylock.toml, công cụ chọn Pipfile.lock làm tệp lock chi phối (hoặc kết nối cả hai). Chạy các bài kiểm thử liên quan để xác nhận bản sửa.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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).

Ngôn ngữ chính
Rust
Star
8
Fork
0
Merge trung bình
1 ngày 1 giờ
Pull request đã merge (30 ngày)
257

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của SocketDev/socket-patch

Tất cả issue của SocketDev/socket-patch

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.