Ruff v.0.0.292 现已发布,并全面支持 Python 3.12。可从 PyPI 或您选择的包管理器安装

pip install --upgrade ruff

友情提醒:Ruff 是一个用 Rust 编写的极速 Python linter。 Ruff 可以替代 Flake8(以及数十个插件)、isort、pydocstyle、pyupgrade 等,其执行速度比任何单个工具快数十倍甚至数百倍。

GitHub 上查看完整的更新日志,或继续阅读亮点内容。

支持 PEP 701

Python 3.12 已于10月2日发布。我们为此版本已准备了相当长一段时间;例如,我们之前宣布了对 PEP 695 的支持,该 PEP 增加了类型声明的新语法。在此版本中,我们很高兴地宣布支持 PEP 701,该 PEP 为 f-string 提供了形式化的语法。

新语法解除了之前对 f-string 的许多限制,如下例所示,这些示例在早期版本的 Python 中都是无效的。

封闭引号的重用

f"text { data["key"] } text"

f-string 的任意嵌套

f"{f"{f"{1 + 1}"}"}"

注意:CPython 将嵌套 f-string 的深度限制为 150,并将 f-string 格式说明符中表达式嵌套的深度限制为 2。

# This is fine...
f"{x:{1:{1}}}"

# ...but this isn't.
f"{x:{1:{1:{1}}}}"
# SyntaxError: f-string: expressions nested too deeply

Ruff 不强制执行上述任何限制。

多行表达式和注释

f"Some random words {", ".join(
    "alpha"  # first word
    "beta"   # second word
)}"

反斜杠和 Unicode 字符

f"Some random words: {"\\n".join(words)}"
f"Alpha: \\N{GREEK SMALL LETTER ALPHA}"

欲了解更多信息,请参阅 PEP 7013.12 发布说明。您可以在 Ruff Playground 上试用上述示例。

PEP 701 规则变更

为了支持 PEP 701,Ruff 的一些现有 lint 规则需要更新。

以下规则已更新,以检测 f-string 表达式中的违规行为

例如,给定以下代码片段

f"outer f-string contains placeholder -> {f"inner one doesn't"}"

Ruff 现在将在内部 f-string 上检测到 F541 违规(缺少占位符的 f-string)。

$ ruff check --select=F541 --show-source example.py
example.py:1:43: F541 [*] f-string without any placeholders
  |
1 | f"outer f-string contains placeholder -> {f"inner one doesn't"}"
  |                                           ^^^^^^^^^^^^^^^^^^^^ F541
  |
  = help: Remove extraneous `f` prefix

Found 1 error.
[*] 1 potentially fixable with the --fix option.

flake8-quotes 规则的独特之处在于,只有当 target-version 为 3.12 或更高版本时,才会报告并修复嵌套 f-string 的诊断信息。目前,只有 avoidable-escaped-quote (Q003) 规则已更新以支持此功能,而 bad-quotes-inline-string (Q000) 和 bad-quotes-multiline-string (Q001) 将仅报告最外层引号的问题。这将在未来的版本中更新。

PEP 701 的支持由 @dhruvmanila 贡献。

规则变更:line-too-long (E501)

line-too-long (E501) 规则现在在计算行长时会忽略尾随的 pragma 注释(如 # type: ignore# noqa)。这类似于 flake8-bugbear 检测过长行的方法,并确保添加诸如 # noqa 之类的 pragma 不会引入额外的 lint 错误。

详情请参阅 #7692

新规则:print-empty-string (FURB105)

作用是什么?

检查 print 调用中将空字符串作为唯一位置参数的情况。

为何重要?

建议直接调用 print 而不带任何位置参数,这效果相同且更简洁。

例如,在以下代码片段中,一个空字符串被传递给 print

print("")

"" 可以省略,效果相同

print()

源自 refurb

@tjkuson 贡献。

新规则:implicit-cwd (FURB177)

作用是什么?

检查使用 Path().resolve() 进行当前目录查找的情况。

为何重要?

在查找当前目录时,建议优先使用 Path.cwd() 而非 Path().resolve(),因为 Path.cwd() 意图更明确。

例如,在以下代码片段中,一个空路径被解析

cwd = Path().resolve()

相反,您应该使用明确的工作目录方法

cwd = Path.cwd()

源自 refurb

@danparizher 贡献。

新规则:weak-cryptographic-key (S505)

作用是什么?

检查使用具有易受攻击密钥大小的加密密钥的情况。

为何重要?

小密钥容易被破解。对于 DSA 和 RSA,密钥长度应至少为 2048 位。对于 EC,密钥长度应至少为 224 位。

例如,在以下代码片段中,密钥大小仅为 512

from cryptography.hazmat.primitives.asymmetric import dsa, ec

dsa.generate_private_key(key_size=512)
ec.generate_private_key(curve=ec.SECT163K1)

相反,应使用更大的密钥大小,例如 4096

from cryptography.hazmat.primitives.asymmetric import dsa, ec

dsa.generate_private_key(key_size=4096)
ec.generate_private_key(curve=ec.SECP384R1)

源自 flake8-bandit

@mkniewallner 贡献。