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 选项禁用,则不会发出其诊断信息,也不会提供修复。