pylint 错误格式字符串的解释

7 投票
1 回答
2587 浏览
提问于 2025-04-18 15:29

在下面这个文件中:

"""hello I am the module spam.py"""
from __future__ import unicode_literals
'hello {world}'.format(world='potato')

我们遇到了一个pylint的违规提示,提示内容是bad-format-string

wim@SDFA100461C:/tmp$ pylint --reports=n spam.py
No config file found, using default configuration
************* Module spam
W:  3, 0: Invalid format string (bad-format-string)

我不太明白这个建议的意思,pylint的开发者说这个检查是关于PEP 3101风格的,但我在这个PEP文档中没有看到任何被违反的地方。

问题出在哪里?pylint希望我们怎么做呢?

下面是版本号信息。

wim@SDFA100461C:/tmp$ pylint --version
No config file found, using default configuration
pylint 1.3.0, 
astroid 1.2.0, common 0.62.1
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2]

1 个回答

4

这是一个在 pylint 中的错误;它假设所有的字符串格式都是 字节字符串

这个工具会解析格式,然后解析占位符的名字。因为你使用的是 Unicode 字面量,这会产生一个 unicode 名字,但解析器假设它只会遇到字节字符串;如果不是,它就会认为找到了一个整数:

if not isinstance(keyname, str):
    # In Python 2 it will return long which will lead
    # to different output between 2 and 3
    keyname = int(keyname)

这会导致你的格式字符串抛出一个 ValueError 错误,因为 world 被解析成了一个 unicode 值:

>>> import string
>>> formatter = string.Formatter()
>>> parseiterator = formatter.parse(u'hello {world}')
>>> result = next(parseiterator)
>>> result
(u'hello ', u'world', u'', None)
>>> keyname, fielditerator = result[1]._formatter_field_name_split()
>>> keyname
u'world'

然后这个 ValueError 异常会被捕获,并转换成一个 IncompleteFormatString 异常,最终导致出现 W1302 错误代码。

可以查看这个 parse_format_method_string 函数

那里的测试应该改成测试与 format_string 相同类型的内容:

if not isinstance(keyname, type(format_string)):
    # In Python 2 it will return long which will lead
    # to different output between 2 and 3
    keyname = int(keyname)

这样在 Python 2 和 3 中都会正确处理。

撰写回答