Nested replacement fields switch f-string lexing out of format-spec mode
Chưa có ai nhận issue này.
- 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
Summary
Closing a nested replacement field inside an f-string format specifier switches the lexer to middle-string mode even though the outer replacement field remains open. Braces that follow the nested field are then parsed as escaped literal content instead of expressions in the format specifier. The shared lexer path also affects t-strings and changes the diagnostic produced for a newline after a nested field.
Reproduction Code
class X:
def __format__(self, spec):
return repr(spec)
x = X()
y = "Y"
z = "Z"
print(f'{x:{{y}}}')
print(f'{x:{y}{{z}}}')
Actual Behavior
"{'Y'}"
'Y{z'}
The second f-string passes Y{z to X.__format__(). repr() returns 'Y{z', and the remaining } is appended as literal f-string content. The corresponding t-string, t'{x:{y}{{z}}}', records Y{z as its interpolation's format specifier and places the remaining } in the following literal string.
Expected Behavior
The second f-string should treat {{z}} as a nested replacement field whose expression is the set literal {z}. It should pass Y{'Z'} to X.__format__() and print:
"{'Y'}"
"Y{'Z'}"
The t-string interpolation should likewise record Y{'Z'} as its format specifier.
Root Cause
begin_ftstring_expr() increments replacement_depth when a replacement field starts. A nested replacement field within a format specifier therefore has a greater replacement depth than its enclosing field.
When the matching } is processed, _PyLexer_close_ftstring_expr() decrements replacement_depth and unconditionally selects FTSTRING_MODE_MIDDLE. After a nested field closes, the remaining non-zero replacement depth represents the still-open outer field, whose format specifier is still being scanned. Losing that state changes how _PyLexer_get_ftstring() handles subsequent braces and
newlines.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
- gh-157492
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Chạy hai ví dụ f-string và so sánh đầu ra của chúng với hành vi mong đợi, bao gồm cả trường hợp t-string tương ứng. Sau đó đọc begin_ftstring_expr() và _PyLexer_close_ftstring_expr(), mà báo cáo xác định là các điểm vào lexer liên quan; được xem là hoàn tất khi các trường lồng nhau vẫn được xử lý đúng trong khi trình chỉ định định dạng bên ngoài đang mở.
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
- compilers
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 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
- 35/100