python / python/cpython

configparser: whitespace-ending delimiter with an empty value cannot be parsed (write() output is unreadable)

Đang mở
#157,456 5 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ả

Bug report

The whitespace-in-delimiters feature added in gh-156353 (3.16) cannot parse an option that has an empty value when the delimiter ends in whitespace — including its own write() output.

_read matches option lines against line.clean, which is val.strip() (both sides) with comments removed. For a whitespace delimiter, the delimiter is the trailing whitespace, so strip() erases it and OPTCRE no longer matches.

Reproduction (on main, 3.16.0a0)

import configparser, io

# (1) plain read — rejected, though the option regex itself matches "key ":
cp = configparser.ConfigParser(delimiters=(' ',))
cp.read_string("[s]\nkey \n")          # -> ParsingError   (expected: {'key': ''})

# (2) round-trip — write() emits a line read_string() then refuses to parse:
w = configparser.ConfigParser(delimiters=(' ',)); w['s'] = {'key': ''}
buf = io.StringIO(); w.write(buf)
print(repr(buf.getvalue()))            # '[s]\nkey   \n\n'
configparser.ConfigParser(delimiters=(' ',)).read_string(buf.getvalue())  # ParsingError

A serializer that cannot read its own output is a clear self-inconsistency. Empty values are a supported, first-class feature for every other delimiter (key=, key:, key->, key|| all read back as {'key': ''}), so whitespace delimiters should behave the same.

Bug class

Any delimiter whose string ends in whitespace combined with an empty (or all-whitespace) value: ' ', '\t', ' ', 'x ', '= ' all raise; delimiters without trailing whitespace ('->', ' x') work.

Why it's not caught

The gh-156353 tests (test_space_delimiter, test_any_delimiter) only use non-empty values, so this edge is unpinned.

Fix

Match the option regex against a form that preserves trailing whitespace (the delimiter). optval is already stripped after the match, so ordinary values keep no trailing whitespace and the other uses of line.clean are unaffected. I have a small patch + tests and will open a PR referencing this issue.

Found with AI assistance; I've reproduced and verified the behaviour and fix on a locally built interpreter and understand them.

Linked PRs
  • gh-157457

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 ConfigParser._read và phạm vi kiểm thử hiện có của test_space_delimiter và test_any_delimiter được mô tả trong issue. Tái hiện các trường hợp giá trị rỗng bằng read_string() và write(), sau đó mở rộng các bài kiểm thử để các dấu phân cách kết thúc bằng khoảng trắng và các giá trị rỗng được phân tích nhất quán, đồng thời round trip thành công.

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
tooling
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
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.