Ruff v0.0.283 现已发布。您可以从 PyPI 或您选择的包管理器进行安装
pip install --upgrade ruff
温馨提示:Ruff 是一个用 Rust 编写的极速 Python linter。 Ruff 可以替代 Flake8(以及数十个插件)、isort、pydocstyle、pyupgrade 等,其执行速度比任何单个工具快数十到数百倍。
在 GitHub 上查看完整的更新日志,或继续阅读以了解亮点。
Ruff 支持 PEP 695 #
随着 Python 3.12 的首个发布候选版本发布,Astral 团队正在准备支持新的 Python 特性。其中一项在 PEP 695 中引入的特性是用于声明类型别名和使用泛型类型参数的新语法。
例如,替代以下写法:
import typing
T = typing.TypeVar("T")
MyList: typing.TypeAlias = list[T]
您可以这样写:
type MyList[T] = list[T]
相同的类型参数语法也可用于函数和类中的泛型类型,例如:
def my_func[T](x: T) -> list[T]:
return [x]
class MyClass[U]:
def method(self) -> U:
...
截至 Ruff v0.0.283,Ruff 的解析器支持所有有效的 PEP 695 语法。
我们还引入了一个新规则(UP040
),通过自动将类型别名声明转换为新语法来简化您的过渡。有关此规则实现的详细信息,请参见 #6289 和 #6314。请注意,此规则仅在您的目标 Python 版本为 3.12+ 时启用。
我们正在寻找有兴趣为更复杂的类型声明添加规则的贡献者。
作为此次更改的一部分,我们为 RustPython 的解析器添加了对解析 PEP 695 语法的支持。感谢 RustPython 团队审阅我们的贡献。
flake8-pyi
规则违规现在会在非 stub Python 文件中被报告 #
以前,flake8-pyi
规则仅限于 .pyi
类型 stub 文件。然而,其中许多规则也适用于普通的 Python (.py
) 文件。现在 flake8-pyi
的大多数规则都已实现,我们启用了其中不特定于类型 stub 的一部分规则。这些规则将帮助您发现 Python 代码中类型注解的误用!
以下规则现在在所有 Python 文件中生效:
PYI013
:非空类体中的省略号
PYI016
:重复的联合成员
PYI018
:未使用的私有类型变量
PYI019
:自定义TypeVar返回类型
PYI024
:collections.namedtuple
PYI025
:未别名的collections.abc.Set导入
PYI030
:不必要的Literal联合
PYI032
:Any类型等/不等注解
PYI034
:非Self返回类型
PYI036
:错误的退出注解
PYI041
:冗余的数字联合
PYI042
:蛇形命名法类型别名
PYI043
:T后缀类型别名
PYI045
:iter方法返回可迭代对象
PYI046
:未使用的私有协议
PYI047
:未使用的私有类型别名
PYI049
:未使用的私有TypedDict
PYI050
:stub中无返回值参数注解
(Python ≥ 3.11)PYI051
:冗余的Literal联合
PYI056
:对all的不支持方法调用
重大变更:Python 3.8 成为默认的 target-python
版本 #
此前,在未指定目标 Python 版本时,Ruff 默认使用 Python 3.10。然而,为了避免假定新功能的可用性,默认使用更旧的 Python 版本更为安全。我们现在默认使用目前支持的最旧 Python 版本,即 Python 3.8。
如果您未指定 target-python
或 project.requires-python
版本,这可能是一个重大变更。
(我们仍然支持 Python 3.7,但由于它已达到生命周期结束 (EOL),我们决定不将其设为默认版本。)
详情请参见 #6397。
新规则:custom-type-var-return-type
(PYI019
) #
作用是什么? #
检查那些为其返回类型注解定义自定义 TypeVar
而非使用 typing.Self
的方法。
为何重要? #
如果某些方法使用自定义 TypeVar
类型进行注解,并且该类被子类化,类型检查器将无法推断出正确的返回类型。
此检查目前适用于返回 self
的实例方法、返回 cls
实例的类方法以及 __new__
方法。
例如,给定以下代码片段
class MyClass:
def __new__(cls: type[_S], *args: str, **kwargs: int) -> _S:
...
def foo(self: _S, arg: bytes) -> _S:
...
@classmethod
def bar(cls: type[_S], arg: int) -> _S:
...
类型变量 _S
应该替换为内置类型 Self
from typing import Self
class MyClass:
def __new__(cls: type[Self], *args: str, **kwargs: int) -> Self:
...
def foo(self: Self, arg: bytes) -> Self:
...
@classmethod
def bar(cls: type[Self], arg: int) -> Self:
...
此规则源自 flake8-pyi。
由 @qdegraaf 贡献。
新规则:redundant-literal-union
(PYI051
) #
作用是什么? #
检查联合类型中是否存在冗余的 Literal
类型和内置超类型。
为何重要? #
Literal
类型与其中一个字面量成员的内置超类型组成联合是冗余的,因为超类型比 Literal
类型更具通用性。
例如,Literal["A"] | str
等效于 str
,而 Literal[1] | int
等效于 int
,因为
例如,在以下代码片段中:
from typing import Literal
A: Literal["x"] | str
B: Literal[1] | int
str
和 int
分别是 "x"
和 1
的超类型,因此与字面值进行联合没有效果。字面值可以省略:
from typing import Literal
A: str
B: int
此规则源自 flake8-pyi。
由 @LaBatata101 贡献。
新规则:unecessary-type-union
(PYI055
) #
作用是什么? #
检查联合类型中是否存在多个 type
用法。
为何重要? #
内置函数 type
接受联合类型,将其明确指定为单个 type
更为清晰。
例如,在以下代码片段中:
field: type[int] | type[float]
将联合类型移入单个 type
中更为简洁:
field: type[int | float]
此规则源自 flake8-pyi。
由 @LaBatata101 贡献。
新规则:bad-string-format-character
(PLE1300
) #
作用是什么? #
检查格式化字符串中是否存在不支持的格式字符代码。
为何重要? #
无效的格式字符串字符将在运行时导致错误。
例如,在以下代码片段中,z
不是有效的格式字符,将在运行时引发错误。
print("%z" % "1")
print("{:z}".format("1"))
此规则源自 pylint。
由 @silvanocerza 贡献。