Skip to content

Commit 40aaf41

Browse files
committed
[red-knot] Add support for calling type[<dynamic base>]
1 parent 36d12ce commit 40aaf41

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Call `type[...]`
2+
3+
## Dynamic base
4+
5+
```py
6+
from typing import Any
7+
from knot_extensions import Unknown
8+
9+
def _(subclass_of_any: type[Any], subclass_of_unknown: type[Unknown]):
10+
reveal_type(subclass_of_any()) # revealed: Any
11+
reveal_type(subclass_of_unknown()) # revealed: Unknown
12+
```

crates/red_knot_python_semantic/src/types.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2678,6 +2678,12 @@ impl<'db> Type<'db> {
26782678
)))
26792679
}
26802680

2681+
Type::SubclassOf(subclass_of) if subclass_of.is_dynamic() => {
2682+
Ok(CallOutcome::Single(CallBinding::from_return_type(
2683+
Type::Dynamic(subclass_of.into_dynamic().expect("checked above")),
2684+
)))
2685+
}
2686+
26812687
instance_ty @ Type::Instance(_) => {
26822688
instance_ty
26832689
.try_call_dunder(db, "__call__", arguments)

crates/red_knot_python_semantic/src/types/subclass_of.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::symbol::SymbolAndQualifiers;
2+
use crate::types::DynamicType;
23

34
use super::{ClassBase, ClassLiteralType, Db, KnownClass, Type};
45

@@ -62,6 +63,13 @@ impl<'db> SubclassOfType<'db> {
6263
subclass_of.is_dynamic()
6364
}
6465

66+
pub fn into_dynamic(self) -> Option<DynamicType> {
67+
match self.subclass_of {
68+
ClassBase::Dynamic(dynamic) => Some(dynamic),
69+
ClassBase::Class(_) => None,
70+
}
71+
}
72+
6573
pub const fn is_fully_static(self) -> bool {
6674
!self.is_dynamic()
6775
}

0 commit comments

Comments
 (0)