python / python/cpython

Error messages for `{}` style formatters for int, float, str, and complex

未關閉
#144,325 6 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

interpreter-core type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

Bug report

Bug description:

The {}-style formatters for int, float, str, and complex have several Unicode handling problems and confusion when generating ValueError messages.

There is an issue #142037 (and PR #142801) that focuses on %-style formatting, but the {}-style formatter has similar problems.

I am drafting a PR to fix the problems in the {} style formatter, and I would like to gather feedback on the proposed changes.


Invalid format specifier string
>>> f"{1:\n\\}"
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    f"{1:\n\\}"
      ^^^^^^^^
ValueError: Invalid format specifier '
\' for object of type 'int'

In the above example, the error message is concatenated (%U) from the specifier string.

Suggestion: Use repr() (%R) to escape special characters.


Invalid type code in format specifier
>>> f"{1:\x7f}"
Traceback (most recent call last):
  File "<python-input-2>", line 1, in <module>
    f"{1:\x7f}"
      ^^^^^^^^
ValueError: Unknown format code '' for object of type 'int'
>>> f"{1:\t}"
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    f"{1:\t}"
      ^^^^^^
ValueError: Unknown format code '\x9' for object of type 'int'
>>> f"{1:🐍}"
Traceback (most recent call last):
  File "<python-input-4>", line 1, in <module>
    f"{1:🐍}"
      ^^^^^^
ValueError: Unknown format code '\x1f40d' for object of type 'int'

The unprintable \x7f is concatenated, and \t and 🐍 are escaped improperly.

Suggestion: Use similar logic as in the %-style formatter in recent PR #142801:

https://github.com/python/cpython/blob/08d7bd28fecca524c648dda240022add704b8f8a/Objects/unicode_format.c#L768-L801


Conversion specifier

Same behavior as above:

>>> "{0!🐍}".format(1)
Traceback (most recent call last):
  File "<python-input-5>", line 1, in <module>
    "{0!🐍}".format(1)
    ~~~~~~~~~~~~~~~^^^
ValueError: Unknown conversion specifier \x1f40d

Suggestion: Apply the same logic as above, and so it is also consistent with the compile-time SyntaxError:

>>> f"{1!🐍}"
  File "<python-input-6>", line 1
    f"{1!🐍}"
         ^^
SyntaxError: invalid character '🐍' (U+1F40D)

Check for fractional part grouping separator

Currently, the check for thousands separator occurs when parsing the format specifier string, but may be omitted for the fractional part, so it passes to format a str (The parser processes the string without knowledge of the object type).

The 1st and 3rd are expected, the 2nd may be not:

>>> f'{123456.123456:.,}'
'123456.123,456'
>>> f'{"x":.,s}'
'x'
>>> f'{"x":,s}'
Traceback (most recent call last):
  File "<python-input-8>", line 1, in <module>
    f'{"x":,s}'
      ^^^^^^^^
ValueError: Cannot specify ',' with 's'.

Suggestion: I didn't find any PEP or document about where we can use the fractional part grouping separator, so I suggest that it can (and only can) be used for e, f, g, E, G, %, and F. For comparison, integer part supports above plus d, b, o, x, and X. None of these five has a fractional part.

Related reference:

  • Thousands separator was added in PEP 378.
  • Fractional part grouping separator was added in issue #87790.

Check type field before thousands separator
>>> f'{100000:+#020,🐍}'
Traceback (most recent call last):
  File "<python-input-10>", line 1, in <module>
    f'{100000:+#020,🐍}'
      ^^^^^^^^^^^^^^^^^
ValueError: Cannot specify ',' with '\x1f40d'.

This should be a type field issue that reports unknown format code, instead of misusing the thousands separator. Also, the character is not escaped properly.

Suggestion: Check the type field is valid first, then check the thousands separator. So we can also avoid repeating the Unicode codepoint logic when forming the error message.


I would appreciate any feedback or suggestions on these proposed changes. Thank you!

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs
  • gh-144326

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

從 Objects/unicode_format.c 開始,特別是查看 PR #142801 中引用的格式化邏輯,並與連結的 PR #144326 進行比較。重現列出的無效格式指定字元和轉換情況,然後驗證 Unicode 是否以一致的方式進行跳脫,以及小數分組和類型欄位驗證是否遵循提議的規則。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
compilers
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。