python / python/cpython

zipfile.Path.is_symlink() raises KeyError for missing entries

Đang mở
#152,762 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

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

stdlib type-bug
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

Summary

zipfile.Path.is_symlink() raises KeyError for a path that is not present in the archive, while the neighboring path predicates return booleans for the same object. This makes is_symlink() leak ZipFile.getinfo() lookup behavior instead of behaving like a predicate, and it differs from pathlib.Path.is_symlink() on a missing filesystem path.

Code path

  • Lib/zipfile/_path/__init__.py:395-402: Path.is_dir(), Path.is_file(), and Path.exists() use string/path-state checks and return booleans.
  • Lib/zipfile/_path/__init__.py:413-419: Path.is_symlink() calls self.root.getinfo(self.at) directly before checking the mode bits.
  • Lib/zipfile/__init__.py:2126-2133: ZipFile.getinfo() raises KeyError when the member name is absent.

Steps to reproduce

I reproduced this directly on Python 3.13.13 and on a local CPython main checkout built out-of-tree.

Minimal reproducer:

import io
import zipfile

buf = io.BytesIO()
with zipfile.ZipFile(buf, "w") as zf:
    zf.writestr("present.txt", b"x")

buf.seek(0)
with zipfile.ZipFile(buf) as zf:
    p = zipfile.Path(zf) / "missing.txt"
    print(p.exists(), p.is_file(), p.is_dir())
    print(p.is_symlink())

Observed on Python 3.13.13:

python: 3.13.13 | packaged by Anaconda, Inc. | (main, Apr 14 2026, 06:14:06) [Clang 20.1.8 ]
zipfile module: <python-3.13.13-env>/lib/python3.13/zipfile/__init__.py
exists/is_file/is_dir: False False False
is_symlink exception: KeyError: "There is no item named 'missing.txt' in the archive"

Observed on CPython main:

commit: 564c58c718bc3de9cf3d9bc20cdc06317411c1cd
python: 3.16.0a0 (heads/main-dirty:564c58c, Jul  1 2026, 17:29:34) [Clang 21.0.0 (clang-2100.1.1.101)]
zipfile module: <checkout>/Lib/zipfile/__init__.py
exists/is_file/is_dir: False False False
is_symlink exception: KeyError: "There is no item named 'missing.txt' in the archive"

The CPython main result was produced with the interpreter built from that checkout, without monkeypatching or shims.
The source checkout used for the anchors above was clean (git status --short produced no output); build artifacts were kept out-of-tree.

Expected behavior

zipfile.Path.is_symlink() should return False for a path that is not present in the archive. This matches the behavior of pathlib.Path.is_symlink() for a missing filesystem path and the boolean-predicate behavior of zipfile.Path.exists(), zipfile.Path.is_file(), and zipfile.Path.is_dir() on the same missing archive path.

Actual behavior

zipfile.Path.is_symlink() raises:

KeyError: "There is no item named 'missing.txt' in the archive"

Existing coverage

Related but not duplicate:

  • #119588 / #119591 added zipfile.Path.is_symlink(), but did not cover missing archive paths.
  • #133324 discusses broader file type semantics for zipfile.Path, including symlinks and directories, but does not cover this missing-path KeyError root cause.

Suggested fix

Return False before calling getinfo() when the Path does not correspond to an archive member, or otherwise catch the KeyError from getinfo() and convert it to False for this predicate.

Suggested tests

  • Add a zipfile.Path test where Path(zf) / "missing.txt" returns False from is_symlink().
  • Keep coverage that existing symlink entries still return True.
  • Consider also covering the archive root path if it is expected to behave as a non-symlink directory.

Submitted with Codex.

Linked PRs
  • gh-152924

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

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.

Hướng nghiên cứu

Bắt đầu với Lib/zipfile/_path/init.py:413-419 và so sánh is_symlink() với các vị từ liền kề ở dòng 395-402. Xem lại các bài kiểm thử hiện có của zipfile.Path và thêm độ bao phủ cho một member bị thiếu, đồng thời vẫn giữ trường hợp symlink hiện có được bao phủ; hoàn thành nghĩa là các đường dẫn bị thiếu trả về False mà không thay đổi hành vi của symlink hợp lệ.

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

Đánh giá

Công nghệ
python
Lĩnh vực
backend
Loại issue
Lỗi
Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
25/100

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.