File tree Expand file tree Collapse file tree 2 files changed +27
-3
lines changed
crates/ty_python_semantic
resources/mdtest/type_properties Expand file tree Collapse file tree 2 files changed +27
-3
lines changed Original file line number Diff line number Diff line change @@ -87,6 +87,25 @@ static_assert(is_disjoint_from(memoryview, Foo))
8787static_assert(is_disjoint_from(type[memoryview ], type[Foo]))
8888```
8989
90+ ## Specialized ` @final ` types
91+
92+ ``` toml
93+ [environment ]
94+ python-version = " 3.12"
95+ ```
96+
97+ ``` py
98+ from typing import final
99+ from ty_extensions import static_assert, is_disjoint_from
100+
101+ @final
102+ class Foo[T]:
103+ def get (self ) -> T:
104+ raise NotImplementedError
105+
106+ static_assert(not is_disjoint_from(Foo[int ], Foo[str ]))
107+ ```
108+
90109## "Disjoint base" builtin types
91110
92111Most other builtins can be subclassed and can even be used in multiple inheritance. However, builtin
Original file line number Diff line number Diff line change @@ -637,12 +637,17 @@ impl<'db> ClassType<'db> {
637637 return true ;
638638 }
639639
640- // Optimisation: if either class is `@final`, we only need to do one `is_subclass_of` call.
641640 if self . is_final ( db) {
642- return self . is_subclass_of ( db, other) ;
641+ return self
642+ . iter_mro ( db)
643+ . filter_map ( ClassBase :: into_class)
644+ . any ( |class| class. class_literal ( db) . 0 == other. class_literal ( db) . 0 ) ;
643645 }
644646 if other. is_final ( db) {
645- return other. is_subclass_of ( db, self ) ;
647+ return other
648+ . iter_mro ( db)
649+ . filter_map ( ClassBase :: into_class)
650+ . any ( |class| class. class_literal ( db) . 0 == self . class_literal ( db) . 0 ) ;
646651 }
647652
648653 // Two disjoint bases can only coexist in an MRO if one is a subclass of the other.
You can’t perform that action at this time.
0 commit comments