[red-knot] knot_extensions Python API (#15103)

## Summary

Adds a type-check-time Python API that allows us to create and
manipulate types and to test various of their properties. For example,
this can be used to write a Markdown test to make sure that `A & B` is a
subtype of `A` and `B`, but not of an unrelated class `C` (something
that requires quite a bit more code to do in Rust):
```py
from knot_extensions import Intersection, is_subtype_of, static_assert

class A: ...
class B: ...

type AB = Intersection[A, B]

static_assert(is_subtype_of(AB, A))
static_assert(is_subtype_of(AB, B))

class C: ...
static_assert(not is_subtype_of(AB, C))
```

I think this functionality is also helpful for interactive debugging
sessions, in order to query various properties of Red Knot's type
system. Which is something that otherwise requires a custom Rust unit
test, some boilerplate code and constant re-compilation.

## Test Plan

- New Markdown tests
- Tested the modified typeshed_sync workflow locally
This commit is contained in:
David Peter 2025-01-08 12:52:07 +01:00 committed by GitHub
parent 03ff883626
commit 235fdfc57a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 826 additions and 17 deletions

View file

@ -109,6 +109,7 @@ pub enum KnownModule {
#[allow(dead_code)]
Abc, // currently only used in tests
Collections,
KnotExtensions,
}
impl KnownModule {
@ -122,6 +123,7 @@ impl KnownModule {
Self::Sys => "sys",
Self::Abc => "abc",
Self::Collections => "collections",
Self::KnotExtensions => "knot_extensions",
}
}
@ -147,6 +149,7 @@ impl KnownModule {
"sys" => Some(Self::Sys),
"abc" => Some(Self::Abc),
"collections" => Some(Self::Collections),
"knot_extensions" => Some(Self::KnotExtensions),
_ => None,
}
}
@ -154,4 +157,8 @@ impl KnownModule {
pub const fn is_typing(self) -> bool {
matches!(self, Self::Typing)
}
pub const fn is_knot_extensions(self) -> bool {
matches!(self, Self::KnotExtensions)
}
}