non-self-return-type (PYI034)
源自 flake8-pyi 代码检查器。
有时提供修复。
作用
检查使用固定返回类型注释的方法,这些方法应该返回 Self
。
为什么这不好?
如果在运行时通常返回 self
的方法被注释为固定返回类型,并且该类被子类化,则类型检查器将无法推断出正确的返回类型。
例如
class Shape:
def set_scale(self, scale: float) -> Shape:
self.scale = scale
return self
class Circle(Shape):
def set_radius(self, radius: float) -> Circle:
self.radius = radius
return self
# Type checker infers return type as `Shape`, not `Circle`.
Circle().set_scale(0.5)
# Thus, this expression is invalid, as `Shape` has no attribute `set_radius`.
Circle().set_scale(0.5).set_radius(2.7)
具体来说,此检查强制以下方法的返回类型为 Self
- 原地二进制操作的魔术方法,如
__iadd__
、__imul__
等。 __new__
、__enter__
和__aenter__
,如果这些方法返回类名。- 返回
Iterator
的__iter__
方法,即使该类直接继承自Iterator
。 - 返回
AsyncIterator
的__aiter__
方法,即使该类直接继承自AsyncIterator
。
示例
class Foo:
def __new__(cls, *args: Any, **kwargs: Any) -> Foo: ...
def __enter__(self) -> Foo: ...
async def __aenter__(self) -> Foo: ...
def __iadd__(self, other: Foo) -> Foo: ...
建议改为
from typing_extensions import Self
class Foo:
def __new__(cls, *args: Any, **kwargs: Any) -> Self: ...
def __enter__(self) -> Self: ...
async def __aenter__(self) -> Self: ...
def __iadd__(self, other: Foo) -> Self: ...
修复安全性
此规则的修复被标记为不安全,因为它会改变类型注释的含义。
Availability(可用性)
因为此规则依赖于 Python 3.11 之前的第三方 typing_extensions
模块,如果 typing_extensions
导入已被 lint.typing-extensions
linter 选项禁用,则不会发出其诊断信息,也不会提供修复。