Ruff ty 类型检查器中的 `typing.Self`:方法签名、属性注解与接收者规则的完整语义指南

发布时间:2026/9/10 11:52:31

Ruff ty 类型检查器中的 `typing.Self`:方法签名、属性注解与接收者规则的完整语义指南 Ruff ty 类型检查器中的typing.Self方法签名、属性注解与接收者规则的完整语义指南【免费下载链接】ruffAn extremely fast Python linter and code formatter, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ru/rufftyping.Self是 Python 3.11 引入的自身类型标注用于表达返回/接收当前类实例的递归类型关系。Ruff 仓库内嵌的类型检查器 ty位于 crates/ty_python_semantic通过 mdtest 测试套件对其进行了极其详尽的语义验证——本文以 crates/ty_python_semantic/resources/mdtest/annotations/self.md 这份 1600 余行的测试文档为骨架系统讲解 ty 中Self的完整行为它如何被建模为绑定到当前类的TypeVar如何作用于实例方法、类方法、属性、泛型类、协议与元类以及哪些位置属于非法用法。Self的本质一个绑定到当前类的类型变量ty 的语义模型将Self视为被绑定到其所在类的TypeVar这一点与TypeVar的约束求解机制完全一致。文档开篇即给出这一核心论断[environment] python-version 3.13from typing import Self class Shape: def set_scale(self: Self, scale: float) - Self: reveal_type(self) # revealed: Selfset_scale return self注意reveal_type(self)的输出是Selfset_scale——这里的set_scale后缀表示该Self类型变量与set_scale方法绑定它是方法级的类型变量而非类级。这一按方法绑定的设计是理解后续所有替换规则的关键。在源码实现上ty 用一个专门的TypeVarKind::TypingSelf来标记这类类型变量。在 crates/ty_python_semantic/src/types/typevar.rs 中可以看到判定逻辑pub(crate) fn is_self(self, db: db dyn Db) - bool { matches!(self.kind(db), TypeVarKind::TypingSelf) }当方法被绑定bound时ty 会把这个Self类型变量替换为具体的实例类型。该替换逻辑集中在 crates/ty_python_semantic/src/types/method.rs 的typing_self_type与map_self_type中前者返回应当替换所有typing.Self注解的类型通常是self/cls的绑定实例类型后者把这一替换映射到方法签名上。一个直观的验证是子类场景Circle继承Shape的set_scale当通过Circle()调用时Self会绑定为Circleclass Circle(Shape): def set_scale(self: Self, scale: float) - Self: reveal_type(self) # revealed: Selfset_scale return self reveal_type(Shape().nested_type()) # revealed: list[Shape] reveal_type(Shape().nested_func()) # revealed: Shape未注解的self参数隐式Self文档强调实例方法中第一个参数无论其名字是什么在未显式注解时默认被推断为typing.Self而classmethod与staticmethod不适用这一规则。self这个名字本身没有任何特殊含义。from typing import Self class A: def __init__(self): reveal_type(self) # revealed: Self__init__ def __init_subclass__(cls, default_name, **kwargs): reveal_type(cls) # revealed: type[Self__init_subclass__] def implicit_self(self) - Self: reveal_type(self) # revealed: Selfimplicit_self return self def implicit_self_genericT - T: reveal_type(self) # revealed: Selfimplicit_self_generic return x注意__init__与__init_subclass__分别属于实例方法和类方法语义__init_subclass__的cls被推断为type[Self__init_subclass__]。对外层作用域的验证如下a A() reveal_type(a.implicit_self()) # revealed: A reveal_type(a.implicit_self) # revealed: bound method A.implicit_self() - A嵌套函数中的self与外层方法的绑定。ty 会追踪嵌套作用域内层函数中出现Self时它绑定到最外层方法的Self而不是内层函数自己class Shape: def nested_func(self: Self) - Self: def inner() - Self: reveal_type(self) # revealed: Selfnested_func return self return inner()显式调用验证第一个参数当以未绑定方式显式调用实例方法时ty 会校验第一个参数的类型A.implicit_self(a) # OK # error: [invalid-argument-type] Argument to function A.implicit_self is incorrect: Argument type Literal[1] does not satisfy upper bound A of type variable Self A.implicit_self(1)从这条错误信息可以看到一个关键实现事实Self在内部被建模为以上界upper bound约束的类型变量其约束上界就是当前类。当传入Literal[1]不满足上界A时约束求解失败并报错。隐式传参即obj.method()形式同样校验from typing import Never, Callable class Strange: def can_not_be_called(self: Never) - None: ... # error: [invalid-argument-type] Argument to bound method Strange.can_not_be_called is incorrect: Expected Never, found Strange Strange().can_not_be_called()类方法 / 静态方法不推断SelfA.a_classmethod() # OK A.a_classmethod(a) # error: [too-many-positional-arguments] A.a_staticmethod(1) # OK a.a_staticmethod(1) # OK A.a_staticmethod(a) # error: [invalid-argument-type]参数名、位置与装饰器都不影响推断第一个参数的判定只看位置不看名字位置限定符、装饰器、property、async等均不影响def some_decorator**P, R - Callable[P, R]: return f class B: def name_does_not_matter(this) - Self: reveal_type(this) # revealed: Selfname_does_not_matter return this def positional_only(self, /, x: int) - Self: ... def keyword_only(self, *, x: int) - Self: ... some_decorator def decorated_method(self) - Self: ... property def a_property(self) - Self: ... async def async_method(self) - Self: ... staticmethod def static_method(self): # 参数可以叫 self但不会被当作 Self reveal_type(self) # revealed: Unknown reveal_type(B().name_does_not_matter()) # revealed: B reveal_type(B().positional_only(1)) # revealed: B reveal_type(B().keyword_only(x1)) # revealed: B reveal_type(B().decorated_method()) # revealed: B reveal_type(B().a_property) # revealed: B async def _(): reveal_type(await B().async_method()) # revealed: B反过来自由函数与普通嵌套函数不使用隐式Selfdef not_a_method(self): reveal_type(self) # revealed: Unknown # error: [invalid-type-form] def does_not_return_self(self) - Self: return self class C: def outer(self) - None: def inner(self): reveal_type(self) # revealed: Unknown reveal_type(not_a_method) # revealed: def not_a_method(self) - Unknown不同位置的Self是不同类型绑定替换只作用于本方法文档用一段专门的章节强调方法 A 签名里的Self与方法 B 签名里的Self是彼此独立的类型变量。当访问绑定方法x.foo时ty 只替换Foo.foo中出现的Selffoo绝不会因为x本身的类型里恰好也含有一个Self例如Foo[Selfbar]而把它牵连进来。from typing import Self class Foo[T]: def foo(self: Self) - T: raise NotImplementedError class Bar: def bar(self: Self, x: Foo[Self]): # revealed: bound method Foo[Selfbar].foo() - Selfbar reveal_type(x.foo) reveal_type(x.foo()) # revealed: Selfbar def fU: Bar: # revealed: bound method Foo[Uf].foo() - Uf reveal_type(x.foo) reveal_type(x.foo()) # revealed: Uf如果 ty 盲目替换所有Self这里x.foo()就会错误地返回Foo[Selfbar]。正确的实现是只替换Foo.foo自身的Self绑定因此返回Selfbar或泛型函数下的Uf。这正是 method.rs 中map_self_type只对本方法签名做替换的原因。类方法中的Self显式接收者cls: type[Self]class Shape: def foo(self: Self) - Self: return self classmethod def bar(cls: type[Self]) - Self: reveal_type(cls) # revealed: type[Selfbar] return cls() class Circle(Shape): ... reveal_type(Shape().foo()) # revealed: Shape reveal_type(Shape.bar()) # revealed: Shape reveal_type(Circle().foo()) # revealed: Circle reveal_type(Circle.bar()) # revealed: Circle隐式接收者未注解的cls在类方法中同样被推断为type[Self]行为与显式版本完全一致class Shape: classmethod def bar(cls) - Self: reveal_type(cls) # revealed: type[Selfbar] return cls()泛型类中的隐式类方法当类本身带类型参数时Self的绑定会保留实例化的类型实参class GenericShape[T]: def foo(self) - Self: ... classmethod def bar(cls) - Self: ... classmethod def bazU - GenericShape[U]: reveal_type(cls) # revealed: type[Selfbaz] # error: [invalid-return-type] return cls() class GenericCircleT: ... reveal_type(GenericShape().foo()) # revealed: GenericShape[Unknown] reveal_type(GenericShape.bar()) # revealed: GenericShape[Unknown] reveal_type(GenericShape[int].bar()) # revealed: GenericShape[int] reveal_type(GenericShape.baz(1)) # revealed: GenericShape[Literal[1]] reveal_type(GenericCircle[int].bar()) # revealed: GenericCircle[int]注意GenericShape().bar()得到GenericShape[Unknown]——未指定类型实参时类型参数被推断为Unknown但Self的绑定机制不变。super()调用保留子类的Self当子类覆盖父类返回Self的方法并调用super().method()时返回类型必须是子类的Self类型变量而不是具体子类类型回归测试对应 ty 的 issue #2122。这对普通方法与类方法均成立class Parent: def copy(self) - Self: return self class Child(Parent): def copy(self) - Self: result super().copy() reveal_type(result) # revealed: Selfcopy return result reveal_type(Child().copy()) # revealed: Child # 类方法版本 class Child2(Parent): classmethod def create(cls) - Self: result super().create() reveal_type(result) # revealed: Selfcreate return result reveal_type(Child2.create()) # revealed: Child2更进一步继承的类方法在通过self实例访问时也必须保留方法自身的Self类型且真值收窄truthiness narrowing不破坏这一绑定from typing import Self, assert_type class Child(Parent): def method(self) - None: assert_type(self.create(), Self) class MaybeEmpty: classmethod def create(cls, other: Self) - Self: return cls() def copy_if_empty(self, other: Self) - Self: if not self: assert_type(self.create(other), Self) return self.create(other) return selfSelf在属性注解中的语义递归数据结构Self最常见的实战价值在于表达递归类型例如链表与树class LinkedList: value: int next_node: Self def next(self: Self) - Self: reveal_type(self.value) # revealed: int return self.next_node reveal_type(LinkedList().next()) # revealed: LinkedListdataclass字段同样支持Selffrom dataclasses import dataclass from typing import Self dataclass class Node: parent: Self | None None Node(Node())类体注解中的Self与方法签名中的Self是同一个逻辑类型变量即使内部绑定上下文不同。因此方法返回类体里用Self注解的属性时两者必须视为同类型class Chain: next: Self value: int def advance(self: Self) - Self: return self.next def advance_twice(self: Self) - Self: return self.advance().advance() class SubChain(Chain): extra: str reveal_type(SubChain().advance()) # revealed: SubChain reveal_type(SubChain().advance_twice()) # revealed: SubChainSelf注解的属性流经泛型容器也正常工作list[Self]、Self | None、循环遍历等场景class TreeNode: children: list[Self] parent: Self | None def first_child(self) - Self | None: if self.children: return self.children[0] return None def all_descendants(self) - list[Self]: result: list[Self] [] for child in self.children: result.append(child) result.extend(child.all_descendants()) return result def root(self) - Self: node self while node.parent is not None: node node.parent return node类型别名保留Self。type Identity[T] T这类别名包裹Self时绑定不会被别名截断type Identity[T] T class AliasedNode: parent: Identity[Self] def __init__(self) - None: self.parent self reveal_type(AliasedNode().parent) # revealed: AliasedNode返回Self的可调用属性属性被注解为Callable[[], Self]时调用结果绑定到具体类from typing import Callable, Self class Factory: maker: Callable[[], Self] def __init__(self) - None: self.maker lambda: self class Sub(Factory): pass def _(s: Sub): reveal_type(s.maker()) # revealed: Sub泛型类与Self保留类型实参from typing import Self, Generic, TypeVar T TypeVar(T) class Container(Generic[T]): value: T def set_value(self: Self, value: T) - Self: return self int_container: Container[int] Container[int]() reveal_type(int_container) # revealed: Container[int] reveal_type(int_container.set_value(1)) # revealed: Container[int]未绑定的继承方法当继承的方法返回Self时其返回类型是传入实例的类型——包括子类及其类型实参即使调用时写的是Child而非Child[int]class Parent[T]: def get_self(self) - Self: return self class ChildU: ... def _(child: Child[int]): reveal_type(Child.get_self(child)) # revealed: Child[int]带约束类型变量的泛型类对带有界的类型参数含NewType派生边界、联合边界的实例调用方法不应产生错误回归测试对应 ty 的 issue #2467from typing import NewType class Base: ... class C[T: Base]: x: T def g(self) - None: pass C[Base]().g() # OK BaseNewType NewType(BaseNewType, Base) C[BaseNewType]().g() # OK K NewType(K, int) K2 NewType(K2, K) class D[T: K]: def h(self) - None: pass D[K]().h() # OK D[K2]().h() # OK泛型参数的默认值带默认类型参数的类Self方法会保留实例化时的类型实参未实例化时使用默认值class Container[T bytes]: def __init__(self: Self, data: T | None None) - None: self.data data reveal_type(Container()) # revealed: Container[bytes] reveal_type(Container(1)) # revealed: Container[int] reveal_type(Container(a)) # revealed: Container[str] reveal_type(Container(ba))# revealed: Container[bytes] class Container2[T bytes]: def method(self) - Self: ... def _(c: Container2[str], d: Container2): reveal_type(c.method()) # revealed: Container2[str] reveal_type(d.method()) # revealed: Container2[bytes]旧的TypeVar(default...)写法回归测试对应 ty 的 issue #1156行为一致T TypeVar(T, defaultbytes) class LegacyContainer(Generic[T]): def method(self) - Self: ... def _(c: LegacyContainer[str], d: LegacyContainer): reveal_type(c.method()) # revealed: LegacyContainer[str] reveal_type(d.method()) # revealed: LegacyContainer[bytes]Self与 Protocol协议中的Self遵循相同的绑定规则Protocol自身被视为一个类方法/属性上的Self会绑定到具体的调用者类型from typing import Self, Protocol class Copyable(Protocol): def copy(self) - Self: ... class Linkable(Protocol): next_node: Self def advance(self) - Self: return self.next_node def _(l: Linkable) - None: reveal_type(l.next_node) # revealed: Linkable class CopyableImpl: def copy(self) - Self: ... class SubCopyable(CopyableImpl): ... def copy_it(x: Copyable) - None: reveal_type(x.copy()) # revealed: Copyable def copy_concrete(x: CopyableImpl) - None: reveal_type(x.copy()) # revealed: CopyableImpl def copy_sub(x: SubCopyable) - None: reveal_type(x.copy()) # revealed: SubCopyable在注解位置例如Self | None使用时同样成立class Shape: def union(self: Self, other: Self | None): reveal_type(other) # revealed: Selfunion | None return self非法用法与错误诊断自由位置函数签名与变量注解Self不能用在自由函数、模块级变量、静态方法或类的基类列表中统一报invalid-type-formfrom typing import Self, Generic, TypeVar T TypeVar(T) # error: [invalid-type-form] def x(s: Self): ... # error: [invalid-type-form] b: Self class Foo: def return_concrete_type(self) - Self: # error: [invalid-return-type] return Foo() staticmethod # error: [invalid-type-form] Self cannot be used in a static method def make() - Self: return Foo() class Bar(Generic[T]): ... # error: [invalid-type-form] class Baz(Bar[Self]): ...静态方法中的全面禁用Self不能出现在静态方法的参数、返回类型、嵌套函数与默认参数值中class StaticMethodTests: staticmethod # error: [invalid-type-form] Self cannot be used in a static method def with_self_return() - Self: ... staticmethod # error: [invalid-type-form] Self cannot be used in a static method def with_self_param(x: Self) - None: ... staticmethod def with_nested_function() - None: # 静态方法内的嵌套函数中使用 Self 同样非法 # 因为 Self 绑定到最外层方法即该静态方法 # error: [invalid-type-form] Self cannot be used in a static method def inner() - Self: ... staticmethod # error: [invalid-type-form] Self cannot be used in a static method def with_self_default(x: int 0, y: Self | None None) - None: ...ty 对静态方法的识别相当健壮别名后的staticmethod装饰器sm staticmethod、完全限定的builtins.staticmethod、以及与泛型装饰器堆叠无论顺序都能被正确识别sm staticmethod class AliasedStaticMethod: sm # error: [invalid-type-form] Self cannot be used in a static method def aliased_static() - Self: ... import builtins class BuiltinsStaticMethod: builtins.staticmethod # error: [invalid-type-form] Self cannot be used in a static method def method() - Self: ...__new__是唯一例外__new__在运行时被解释器特殊处理为类似类方法始终接收cls: type[Self]并返回Self因此允许使用Selfclass WithNew: def __new__(cls) - Self: instance object.__new__(cls) return instance reveal_type(WithNew()) # revealed: WithNew class SubclassWithNew(WithNew): def __new__(cls) - Self: return super().__new__(cls) reveal_type(SubclassWithNew()) # revealed: SubclassWithNew注意在 crates/ty_python_semantic/src/types/infer/builder/function.rs 的源码中STATICMETHOD装饰器与__new__是并列判断的静态方法返回None不推断Self而__new__与is_implicit_classmethod一起归入Self::Class分支。元类中的禁用ty 遵循 typing 规范见文档末尾引用的规范链接禁止在元类中使用Self统一报invalid-type-form错误消息为Selfcannot be used in a metaclassclass MyMetaclass(type): # error: [invalid-type-form] Self cannot be used in a metaclass registry: list[Self] # error: [invalid-type-form] Self cannot be used in a metaclass def __new__(cls, name, bases, dct) - Self: ... # error: [invalid-type-form] Self cannot be used in a metaclass def instance_method(self) - Self: ... classmethod # error: [invalid-type-form] Self cannot be used in a metaclass def metaclass_classmethod(cls) - Self: ... # 元类中的静态方法报的是 static method 错误 staticmethod # error: [invalid-type-form] Self cannot be used in a static method def metaclass_staticmethod() - Self: ...但注意边界情形运行时使用名为self的参数值不报错只有字面Self类型形式被禁止间接继承type的类如继承ABCMeta也是元类而使用元类的类metaclass...本身不是元类Self完全合法class AnnotableMeta(type): def __or__(self, other): return self # 无错误这是运行时的 self不是 Self 类型形式 class SomeMeta(type): ... class UsesMetaclass(metaclassSomeMeta): def method(self) - Self: reveal_type(self) # revealed: Selfmethod return self reveal_type(UsesMetaclass().method()) # revealed: UsesMetaclass嵌套类也遵循该规则元类内的普通嵌套类不是元类合法但嵌套类若继承type则仍是元类非法enum.EnumMeta/enum.EnumType同样是元类继承它的类中Self非法。显式接收者注解何时合法何时冲突文档后半部分系统整理了显式接收者注解的完整规则。ty 的实现位于 crates/ty_python_semantic/src/types/infer/builder/function.rsaccepts_annotation方法定义了严格的白名单实例方法接收者只接受Self即Type::TypeVar且is_self为真类方法接收者只接受type[Self]即SubclassOf内部是Self类型变量其余任何注解都返回false触发invalid-type-form。实例方法class Valid: def implicit(self) - Self: return self def explicit(self: Self) - Self: return self class WithoutSelf: # 签名不使用 Self 时允许其他接收者注解 def method(self: T) - T: return self class Invalid: def type_variable(self: T) - Self: # error: [invalid-type-form] ... def concrete(self: Invalid) - Self: # error: [invalid-type-form] ... def union(self: T | None) - Self: # error: [invalid-type-form] ... def class_object(self: type[Self]) - Self: # error: [invalid-type-form] ...即使接收者非法绑定方法的推断返回类型不受影响reveal_type(Invalid().concrete) # revealed: bound method Invalid.concrete() - Invalid类方法类方法的接收者可无注解或为type[Self]Self不带type包裹或type[T]T不是Self均非法class Valid: classmethod def implicit(cls) - Self: return cls() classmethod def explicit(cls: type[Self]) - Self: return cls() class Invalid: classmethod def instance(cls: Self) - Self: # error: [invalid-type-form] ... classmethod def type_variable(cls: type[T]) - Self: # error: [invalid-type-form] ...收窄与别名不豁免非法性联合即使化简为object也不豁免返回与参数注解均如此类型别名参数中的Self同样不豁免每个Self出现位置各产生一条独立错误Union[Self, Self]会产生两条指向各自位置的错误并可用# ty: ignore[invalid-type-form]单独抑制其中一个class Example: def return_type(self: object) - Self | object: ... # error: [invalid-type-form] def parameter(self: object, value: Self | object) - None: ... # error: [invalid-type-form] type Identity[T] T class Example2: def return_type(self: object) - Identity[Self]: # error: [invalid-type-form] ... class SuppressedReturn: def method(self: object, other: Self) - Self: # other: error: [invalid-type-form] ... # 返回注解可用 # ty: ignore[invalid-type-form] 抑制文档还给出了一条典型快照展示诊断的精确定位能力error[invalid-type-form]: Self requires self: Self or cls: type[Self] for annotated receivers -- src/mdtest_snippet.py:12:43 | 12 | def method(self: object, other: Union[Self, Self]) - None: ... | ^^^^泛型方法与引号包裹的Self方法自身的类型参数不能替代接收者中的Self同时引号包裹from __future__ import annotations或字符串注解不影响规则class Valid: def instanceT - Self: return self classmethod def class_methodT - Self: return cls() class Invalid: def instanceT - Self: # error: [invalid-type-form] ... class ValidQuoted: def instance(self: Self) - Self: return self classmethod def class_method(cls: type[Self]) - Self: return cls()绑定方法固定Self当方法被绑定通过实例或类访问时签名中所有Self都被固定为已知的具体类型class C: def instance_method(self, other: Self) - Self: return self classmethod def class_method(cls) - Self: return cls() # revealed: bound method C.instance_method(other: C) - C reveal_type(C().instance_method) # revealed: bound method class C.class_method() - C reveal_type(C.class_method) class D(C): ... # revealed: bound method D.instance_method(other: D) - D reveal_type(D().instance_method) # revealed: bound method class D.class_method() - D reveal_type(D.class_method)Self的绑定穿透类型别名、嵌套别名与仅参数位置返回类型不含Self时参数中的Self仍会绑定type Identity[T] T class Aliased: def copy(self, other: Identity[Self]) - Identity[Self]: return other # revealed: bound method Aliased.copy(other: Aliased) - Aliased reveal_type(Aliased().copy) class ParameterOnly: def consume(self, other: Identity[Self]) - None: ... # revealed: bound method ParameterOnly.consume(other: ParameterOnly) - None reveal_type(ParameterOnly().consume) ParameterOnly().consume(ParameterOnly()) # OK ParameterOnly().consume(object()) # error: [invalid-argument-type] class NestedChild(NestedAlias): ... # revealed: bound method NestedChild.copy(other: NestedChild) - NestedChild reveal_type(NestedChild().copy)嵌套函数中的Self绑定到方法本身即使Self注解先于方法中的绑定出现也如此ty 内部提供ty_extensions._internal.generic_context与RegularCallableTypeOf来观察这一绑定过程from ty_extensions._internal import generic_context class C[T](): def f(self: Self): def b(x: Self): reveal_type(x) # revealed: Selff reveal_type(generic_context(b)) # revealed: None # revealed: ty_extensions._internal.GenericContext[Selff] reveal_type(generic_context(C.f))非位置首参数与存储的绑定方法如果第一个参数不是位置参数如*args, **kwargs则不绑定selfclass C: def method(*args, **kwargs) - None: ... # revealed: (...) - None reveal_type(c) # c: RegularCallableTypeOf[C().method]其他对象存储为实例属性的绑定方法其签名不受Self绑定影响回归测试针对 jinjaLRUCache等项目的误报from collections import deque class MyClass: def __init__(self) - None: self._queue: deque[int] deque() self._append self._queue.append def add(self, value: int) - None: self._append(value)Django 风格模式类属性中的泛型SelfSelf作为泛型类的类型实参出现在类属性中时类访问与实例访问都应绑定到具体类。这是 Django 风格Manager模式的典型场景from typing import Self, Generic, TypeVar T TypeVar(T) class Manager(Generic[T]): def get(self) - T: raise NotImplementedError class Model: objects: Manager[Self] class Confirmation(Model): expiry_date: int def test() - None: # 类访问Self 绑定到 Confirmation confirmation Confirmation.objects.get() reveal_type(confirmation) # revealed: Confirmation x confirmation.expiry_date # 可用——Confirmation 有 expiry_date # 实例访问Self 同样绑定到 Confirmation instance Confirmation() reveal_type(instance.objects) # revealed: Manager[Confirmation] instance_result instance.objects.get() reveal_type(instance_result) # revealed: Confirmation同样的绑定在涉及描述符的属性中也成立class Descriptor(Generic[T]): def __get__(self, instance, owner) - T: raise NotImplementedError class Base: attr: Descriptor[Self] Descriptor() class Child(Base): ... reveal_type(Child.attr) # revealed: Child reveal_type(Child().attr) # revealed: Child如何运行这些测试self.md属于 ty 的mdtest测试体系以 Markdown 代码块的形式编排类型检查用例代码中reveal_type(x) # revealed: ...声明期望的推断结果# error: [code]声明期望的诊断[environment]TOML 块配置运行环境如python-version。该框架的实现位于 crates/mdtest其中crates/mdtest/src/assertion.rs 负责解析断言语法revealed:、error:、snapshot等crates/mdtest/src/matcher.rs 的match_reveal_type_diagnostic负责把类型检查器产出的reveal_type诊断与期望值逐一比对支持MDTEST_TEST_FILTER环境变量按名称过滤用例。ty 类型检查器本体位于 crates/ty 与 crates/ty_python_semanticSelf相关的核心判定TypeVarKind::TypingSelf、接收者白名单、绑定替换分别落在 crates/ty_python_semantic/src/types/typevar.rs、crates/ty_python_semantic/src/types/infer/builder/function.rs 与 crates/ty_python_semantic/src/types/method.rs 中读者可按图索骥深入研读实现细节。小结typing.Self看似简单实则包含一整套精密的类型语义它内部是一个绑定到当前类的类型变量TypeVarKind::TypingSelf按方法而非类划分绑定作用域实例方法第一个未注解的位置参数隐式获得Self类型绑定方法时Self被固定并替换为具体接收者类型包括泛型实参而静态方法、自由函数与元类中则全面禁止使用。把握住Self是接收者类型的替身 绑定发生在方法层面这两条主线无论是编写递归数据结构、泛型类工厂方法还是排查invalid-type-form诊断都能准确预判 ty 的行为。【免费下载链接】ruffAn extremely fast Python linter and code formatter, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ru/ruff创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/10 11:52:31

Phase Goal

Phase Goal 【免费下载链接】get-shit-done A light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TCHES. 项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done As a new user, I…

2026/9/10 12:42:40

CANN/GE算子编译注册函数

aclopRegisterCompileFunc 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、…

2026/9/10 12:42:40

工业电参模块设计与应用实战解析

1. 工业电参模块的核心价值与应用场景在工业自动化领域,电能质量监测就像给生产线装上了"心电图仪"。我们团队在去年为某汽车焊接产线改造时,发现传统钳形表抽查方式导致15%的异常工况被遗漏。换上电参模块后,不仅实时捕捉到电压暂…

2026/9/10 12:42:40

51单片机+MAX517实现三路可调波形发生器

简介:本资源是一套基于51单片机的简易波形发生器完整开发包,面向电子类专业学生、嵌入式初学者及单片机课程实践者,解决基础信号源设计与软硬件协同调试的学习需求。资源包含19个文件,总计55KB,涵盖核心C语言源程序&am…

2026/9/10 12:42:40

Linux常用命令速查手册:文件操作、文本处理与系统监控实战指南

Linux 命令这东西,属于典型的“用时方恨少,查完就忘掉”。我日常跟服务器、跟嵌入式设备、跟一堆跑在虚拟环境里的实例打交道,很多命令说实话不是“记不住”,而是“没必要全记在脑子里”。真正高效的用法是脑子里建立一张索引图&a…

2026/9/10 12:42:40

PRI变换、CDIF与SDIF:雷达信号分选算法详解与MATLAB实现

简介:这是一份面向雷达信号处理学习与研究者的MATLAB代码包,聚焦脉冲重复间隔(PRI)变换、CDIF与SDIF三种信号分选方法,帮助解决雷达回波中目标识别与干扰抑制问题。压缩包共8个文件,包含3个.m源码脚本与5个…

2026/9/9 13:11:35

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 0:00:55

目录对比去重实战:用哈希算法精准清理重复文件

我电脑里现在还有一块换了三次机的“数据墓地”硬盘,里面存着2016年以前所有旧笔记本的完整备份。平时不觉得有什么,直到前阵子想把它整理归档,发现同一个安装包、同一批照片、同一份论文草稿,在几个不同的备份目录里反复出现。更…

2026/9/10 0:00:55

Leaflet离线地图完整Demo合集:内网部署与坐标纠偏实战

简介:这是一份面向Web GIS开发者的LeafLet离线地图示例合集,帮助开发者快速掌握离线地图从搭建到交互的完整流程。压缩包共723个文件,大小14.06MB,以319个js脚本、175个html页面和29个css样式文件为主体,配合png/svg图…

2026/9/10 0:00:55

MATLAB读取Rinex 3.02观测文件:多系统GNSS数据解析实战

简介:基于MATLAB开发的Rinex3.02版观测文件(o文件)读取代码包,面向卫星定位导航方向的学习者与研究人员,用于解决新版观测文件的数据解析、历元提取与时间转换问题。压缩包共4个文件,包含两个m脚本、一个19…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/9 10:21:54

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码