mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-24 13:59:49 +00:00
add GenericContext mdtest class
This commit is contained in:
parent
25631f0f63
commit
2d16039709
13 changed files with 190 additions and 76 deletions
|
|
@ -503,9 +503,11 @@ class C[T]():
|
|||
def f(self: Self):
|
||||
def b(x: Self):
|
||||
reveal_type(x) # revealed: Self@f
|
||||
reveal_type(generic_context(b)) # revealed: None
|
||||
# revealed: None
|
||||
reveal_type(generic_context(b))
|
||||
|
||||
reveal_type(generic_context(C.f)) # revealed: tuple[Self@f]
|
||||
# revealed: ty_extensions.GenericContext[Self@f]
|
||||
reveal_type(generic_context(C.f))
|
||||
```
|
||||
|
||||
Even if the `Self` annotation appears first in the nested function, it is the method that binds
|
||||
|
|
@ -519,9 +521,11 @@ class C:
|
|||
def f(self: "C"):
|
||||
def b(x: Self):
|
||||
reveal_type(x) # revealed: Self@f
|
||||
reveal_type(generic_context(b)) # revealed: None
|
||||
# revealed: None
|
||||
reveal_type(generic_context(b))
|
||||
|
||||
reveal_type(generic_context(C.f)) # revealed: None
|
||||
# revealed: None
|
||||
reveal_type(generic_context(C.f))
|
||||
```
|
||||
|
||||
## Non-positional first parameters
|
||||
|
|
|
|||
|
|
@ -21,14 +21,14 @@ class TypeVarAndParamSpec(Generic[P, T]): ...
|
|||
class SingleTypeVarTuple(Generic[Unpack[Ts]]): ...
|
||||
class TypeVarAndTypeVarTuple(Generic[T, Unpack[Ts]]): ...
|
||||
|
||||
# revealed: tuple[T@SingleTypevar]
|
||||
# revealed: ty_extensions.GenericContext[T@SingleTypevar]
|
||||
reveal_type(generic_context(SingleTypevar))
|
||||
# revealed: tuple[T@MultipleTypevars, S@MultipleTypevars]
|
||||
# revealed: ty_extensions.GenericContext[T@MultipleTypevars, S@MultipleTypevars]
|
||||
reveal_type(generic_context(MultipleTypevars))
|
||||
|
||||
# revealed: tuple[P@SingleParamSpec]
|
||||
# revealed: ty_extensions.GenericContext[P@SingleParamSpec]
|
||||
reveal_type(generic_context(SingleParamSpec))
|
||||
# revealed: tuple[P@TypeVarAndParamSpec, T@TypeVarAndParamSpec]
|
||||
# revealed: ty_extensions.GenericContext[P@TypeVarAndParamSpec, T@TypeVarAndParamSpec]
|
||||
reveal_type(generic_context(TypeVarAndParamSpec))
|
||||
|
||||
# TODO: support `TypeVarTuple` properly (these should not reveal `None`)
|
||||
|
|
@ -66,9 +66,9 @@ class InheritedGeneric(MultipleTypevars[T, S]): ...
|
|||
class InheritedGenericPartiallySpecialized(MultipleTypevars[T, int]): ...
|
||||
class InheritedGenericFullySpecialized(MultipleTypevars[str, int]): ...
|
||||
|
||||
# revealed: tuple[T@InheritedGeneric, S@InheritedGeneric]
|
||||
# revealed: ty_extensions.GenericContext[T@InheritedGeneric, S@InheritedGeneric]
|
||||
reveal_type(generic_context(InheritedGeneric))
|
||||
# revealed: tuple[T@InheritedGenericPartiallySpecialized]
|
||||
# revealed: ty_extensions.GenericContext[T@InheritedGenericPartiallySpecialized]
|
||||
reveal_type(generic_context(InheritedGenericPartiallySpecialized))
|
||||
# revealed: None
|
||||
reveal_type(generic_context(InheritedGenericFullySpecialized))
|
||||
|
|
@ -90,7 +90,7 @@ class OuterClass(Generic[T]):
|
|||
# revealed: None
|
||||
reveal_type(generic_context(InnerClassInMethod))
|
||||
|
||||
# revealed: tuple[T@OuterClass]
|
||||
# revealed: ty_extensions.GenericContext[T@OuterClass]
|
||||
reveal_type(generic_context(OuterClass))
|
||||
```
|
||||
|
||||
|
|
@ -118,11 +118,11 @@ class ExplicitInheritedGenericPartiallySpecializedExtraTypevar(MultipleTypevars[
|
|||
# error: [invalid-generic-class] "`Generic` base class must include all type variables used in other base classes"
|
||||
class ExplicitInheritedGenericPartiallySpecializedMissingTypevar(MultipleTypevars[T, int], Generic[S]): ...
|
||||
|
||||
# revealed: tuple[T@ExplicitInheritedGeneric, S@ExplicitInheritedGeneric]
|
||||
# revealed: ty_extensions.GenericContext[T@ExplicitInheritedGeneric, S@ExplicitInheritedGeneric]
|
||||
reveal_type(generic_context(ExplicitInheritedGeneric))
|
||||
# revealed: tuple[T@ExplicitInheritedGenericPartiallySpecialized]
|
||||
# revealed: ty_extensions.GenericContext[T@ExplicitInheritedGenericPartiallySpecialized]
|
||||
reveal_type(generic_context(ExplicitInheritedGenericPartiallySpecialized))
|
||||
# revealed: tuple[T@ExplicitInheritedGenericPartiallySpecializedExtraTypevar, S@ExplicitInheritedGenericPartiallySpecializedExtraTypevar]
|
||||
# revealed: ty_extensions.GenericContext[T@ExplicitInheritedGenericPartiallySpecializedExtraTypevar, S@ExplicitInheritedGenericPartiallySpecializedExtraTypevar]
|
||||
reveal_type(generic_context(ExplicitInheritedGenericPartiallySpecializedExtraTypevar))
|
||||
```
|
||||
|
||||
|
|
@ -594,18 +594,27 @@ class C(Generic[T]):
|
|||
def generic_method(self, t: T, u: U) -> U:
|
||||
return u
|
||||
|
||||
reveal_type(generic_context(C)) # revealed: tuple[T@C]
|
||||
reveal_type(generic_context(C.method)) # revealed: tuple[Self@method]
|
||||
reveal_type(generic_context(C.generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||
reveal_type(generic_context(C[int])) # revealed: None
|
||||
reveal_type(generic_context(C[int].method)) # revealed: tuple[Self@method]
|
||||
reveal_type(generic_context(C[int].generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||
# revealed: ty_extensions.GenericContext[T@C]
|
||||
reveal_type(generic_context(C))
|
||||
# revealed: ty_extensions.GenericContext[Self@method]
|
||||
reveal_type(generic_context(C.method))
|
||||
# revealed: ty_extensions.GenericContext[Self@generic_method, U@generic_method]
|
||||
reveal_type(generic_context(C.generic_method))
|
||||
# revealed: None
|
||||
reveal_type(generic_context(C[int]))
|
||||
# revealed: ty_extensions.GenericContext[Self@method]
|
||||
reveal_type(generic_context(C[int].method))
|
||||
# revealed: ty_extensions.GenericContext[Self@generic_method, U@generic_method]
|
||||
reveal_type(generic_context(C[int].generic_method))
|
||||
|
||||
c: C[int] = C[int]()
|
||||
reveal_type(c.generic_method(1, "string")) # revealed: Literal["string"]
|
||||
reveal_type(generic_context(c)) # revealed: None
|
||||
reveal_type(generic_context(c.method)) # revealed: tuple[Self@method]
|
||||
reveal_type(generic_context(c.generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||
# revealed: None
|
||||
reveal_type(generic_context(c))
|
||||
# revealed: ty_extensions.GenericContext[Self@method]
|
||||
reveal_type(generic_context(c.method))
|
||||
# revealed: ty_extensions.GenericContext[Self@generic_method, U@generic_method]
|
||||
reveal_type(generic_context(c.generic_method))
|
||||
```
|
||||
|
||||
## Specializations propagate
|
||||
|
|
|
|||
|
|
@ -20,17 +20,21 @@ type TypeVarAndParamSpec[T, **P] = ...
|
|||
type SingleTypeVarTuple[*Ts] = ...
|
||||
type TypeVarAndTypeVarTuple[T, *Ts] = ...
|
||||
|
||||
# revealed: tuple[T@SingleTypevar]
|
||||
# revealed: ty_extensions.GenericContext[T@SingleTypevar]
|
||||
reveal_type(generic_context(SingleTypevar))
|
||||
# revealed: tuple[T@MultipleTypevars, S@MultipleTypevars]
|
||||
# revealed: ty_extensions.GenericContext[T@MultipleTypevars, S@MultipleTypevars]
|
||||
reveal_type(generic_context(MultipleTypevars))
|
||||
|
||||
# TODO: support `ParamSpec`/`TypeVarTuple` properly
|
||||
# (these should include the `ParamSpec`s and `TypeVarTuple`s in their generic contexts)
|
||||
reveal_type(generic_context(SingleParamSpec)) # revealed: tuple[()]
|
||||
reveal_type(generic_context(TypeVarAndParamSpec)) # revealed: tuple[T@TypeVarAndParamSpec]
|
||||
reveal_type(generic_context(SingleTypeVarTuple)) # revealed: tuple[()]
|
||||
reveal_type(generic_context(TypeVarAndTypeVarTuple)) # revealed: tuple[T@TypeVarAndTypeVarTuple]
|
||||
# revealed: ty_extensions.GenericContext[]
|
||||
reveal_type(generic_context(SingleParamSpec))
|
||||
# revealed: ty_extensions.GenericContext[T@TypeVarAndParamSpec]
|
||||
reveal_type(generic_context(TypeVarAndParamSpec))
|
||||
# revealed: ty_extensions.GenericContext[]
|
||||
reveal_type(generic_context(SingleTypeVarTuple))
|
||||
# revealed: ty_extensions.GenericContext[T@TypeVarAndTypeVarTuple]
|
||||
reveal_type(generic_context(TypeVarAndTypeVarTuple))
|
||||
```
|
||||
|
||||
You cannot use the same typevar more than once.
|
||||
|
|
|
|||
|
|
@ -20,17 +20,21 @@ class TypeVarAndParamSpec[T, **P]: ...
|
|||
class SingleTypeVarTuple[*Ts]: ...
|
||||
class TypeVarAndTypeVarTuple[T, *Ts]: ...
|
||||
|
||||
# revealed: tuple[T@SingleTypevar]
|
||||
# revealed: ty_extensions.GenericContext[T@SingleTypevar]
|
||||
reveal_type(generic_context(SingleTypevar))
|
||||
# revealed: tuple[T@MultipleTypevars, S@MultipleTypevars]
|
||||
# revealed: ty_extensions.GenericContext[T@MultipleTypevars, S@MultipleTypevars]
|
||||
reveal_type(generic_context(MultipleTypevars))
|
||||
|
||||
# TODO: support `ParamSpec`/`TypeVarTuple` properly
|
||||
# (these should include the `ParamSpec`s and `TypeVarTuple`s in their generic contexts)
|
||||
reveal_type(generic_context(SingleParamSpec)) # revealed: tuple[()]
|
||||
reveal_type(generic_context(TypeVarAndParamSpec)) # revealed: tuple[T@TypeVarAndParamSpec]
|
||||
reveal_type(generic_context(SingleTypeVarTuple)) # revealed: tuple[()]
|
||||
reveal_type(generic_context(TypeVarAndTypeVarTuple)) # revealed: tuple[T@TypeVarAndTypeVarTuple]
|
||||
# revealed: ty_extensions.GenericContext[]
|
||||
reveal_type(generic_context(SingleParamSpec))
|
||||
# revealed: ty_extensions.GenericContext[T@TypeVarAndParamSpec]
|
||||
reveal_type(generic_context(TypeVarAndParamSpec))
|
||||
# revealed: ty_extensions.GenericContext[]
|
||||
reveal_type(generic_context(SingleTypeVarTuple))
|
||||
# revealed: ty_extensions.GenericContext[T@TypeVarAndTypeVarTuple]
|
||||
reveal_type(generic_context(TypeVarAndTypeVarTuple))
|
||||
```
|
||||
|
||||
You cannot use the same typevar more than once.
|
||||
|
|
@ -49,9 +53,9 @@ class InheritedGeneric[U, V](MultipleTypevars[U, V]): ...
|
|||
class InheritedGenericPartiallySpecialized[U](MultipleTypevars[U, int]): ...
|
||||
class InheritedGenericFullySpecialized(MultipleTypevars[str, int]): ...
|
||||
|
||||
# revealed: tuple[U@InheritedGeneric, V@InheritedGeneric]
|
||||
# revealed: ty_extensions.GenericContext[U@InheritedGeneric, V@InheritedGeneric]
|
||||
reveal_type(generic_context(InheritedGeneric))
|
||||
# revealed: tuple[U@InheritedGenericPartiallySpecialized]
|
||||
# revealed: ty_extensions.GenericContext[U@InheritedGenericPartiallySpecialized]
|
||||
reveal_type(generic_context(InheritedGenericPartiallySpecialized))
|
||||
# revealed: None
|
||||
reveal_type(generic_context(InheritedGenericFullySpecialized))
|
||||
|
|
@ -64,7 +68,8 @@ the inheriting class generic.
|
|||
```py
|
||||
class InheritedGenericDefaultSpecialization(MultipleTypevars): ...
|
||||
|
||||
reveal_type(generic_context(InheritedGenericDefaultSpecialization)) # revealed: None
|
||||
# revealed: None
|
||||
reveal_type(generic_context(InheritedGenericDefaultSpecialization))
|
||||
```
|
||||
|
||||
You cannot use PEP-695 syntax and the legacy syntax in the same class definition.
|
||||
|
|
@ -512,18 +517,27 @@ class C[T]:
|
|||
# TODO: error
|
||||
def cannot_shadow_class_typevar[T](self, t: T): ...
|
||||
|
||||
reveal_type(generic_context(C)) # revealed: tuple[T@C]
|
||||
reveal_type(generic_context(C.method)) # revealed: tuple[Self@method]
|
||||
reveal_type(generic_context(C.generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||
reveal_type(generic_context(C[int])) # revealed: None
|
||||
reveal_type(generic_context(C[int].method)) # revealed: tuple[Self@method]
|
||||
reveal_type(generic_context(C[int].generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||
# revealed: ty_extensions.GenericContext[T@C]
|
||||
reveal_type(generic_context(C))
|
||||
# revealed: ty_extensions.GenericContext[Self@method]
|
||||
reveal_type(generic_context(C.method))
|
||||
# revealed: ty_extensions.GenericContext[Self@generic_method, U@generic_method]
|
||||
reveal_type(generic_context(C.generic_method))
|
||||
# revealed: None
|
||||
reveal_type(generic_context(C[int]))
|
||||
# revealed: ty_extensions.GenericContext[Self@method]
|
||||
reveal_type(generic_context(C[int].method))
|
||||
# revealed: ty_extensions.GenericContext[Self@generic_method, U@generic_method]
|
||||
reveal_type(generic_context(C[int].generic_method))
|
||||
|
||||
c: C[int] = C[int]()
|
||||
reveal_type(c.generic_method(1, "string")) # revealed: Literal["string"]
|
||||
reveal_type(generic_context(c)) # revealed: None
|
||||
reveal_type(generic_context(c.method)) # revealed: tuple[Self@method]
|
||||
reveal_type(generic_context(c.generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||
# revealed: None
|
||||
reveal_type(generic_context(c))
|
||||
# revealed: ty_extensions.GenericContext[Self@method]
|
||||
reveal_type(generic_context(c.method))
|
||||
# revealed: ty_extensions.GenericContext[Self@generic_method, U@generic_method]
|
||||
reveal_type(generic_context(c.generic_method))
|
||||
```
|
||||
|
||||
## Specializations propagate
|
||||
|
|
|
|||
|
|
@ -154,8 +154,10 @@ from ty_extensions import generic_context
|
|||
|
||||
legacy.m("string", None) # error: [invalid-argument-type]
|
||||
reveal_type(legacy.m) # revealed: bound method Legacy[int].m[S](x: int, y: S@m) -> S@m
|
||||
reveal_type(generic_context(Legacy)) # revealed: tuple[T@Legacy]
|
||||
reveal_type(generic_context(legacy.m)) # revealed: tuple[Self@m, S@m]
|
||||
# revealed: ty_extensions.GenericContext[T@Legacy]
|
||||
reveal_type(generic_context(Legacy))
|
||||
# revealed: ty_extensions.GenericContext[Self@m, S@m]
|
||||
reveal_type(generic_context(legacy.m))
|
||||
```
|
||||
|
||||
With PEP 695 syntax, it is clearer that the method uses a separate typevar:
|
||||
|
|
|
|||
|
|
@ -6712,6 +6712,10 @@ impl<'db> Type<'db> {
|
|||
invalid_expressions: smallvec::smallvec![InvalidTypeExpression::ConstraintSet],
|
||||
fallback_type: Type::unknown(),
|
||||
}),
|
||||
KnownInstanceType::GenericContext(__call__) => Err(InvalidTypeExpressionError {
|
||||
invalid_expressions: smallvec::smallvec![InvalidTypeExpression::GenericContext],
|
||||
fallback_type: Type::unknown(),
|
||||
}),
|
||||
KnownInstanceType::SubscriptedProtocol(_) => Err(InvalidTypeExpressionError {
|
||||
invalid_expressions: smallvec::smallvec_inline![
|
||||
InvalidTypeExpression::Protocol
|
||||
|
|
@ -7977,6 +7981,10 @@ pub enum KnownInstanceType<'db> {
|
|||
/// `ty_extensions.ConstraintSet`.
|
||||
ConstraintSet(TrackedConstraintSet<'db>),
|
||||
|
||||
/// A generic context, which is exposed in mdtests as an instance of
|
||||
/// `ty_extensions.GenericContext`.
|
||||
GenericContext(GenericContext<'db>),
|
||||
|
||||
/// A single instance of `types.UnionType`, which stores the left- and
|
||||
/// right-hand sides of a PEP 604 union.
|
||||
UnionType(InternedTypes<'db>),
|
||||
|
|
@ -8011,7 +8019,9 @@ fn walk_known_instance_type<'db, V: visitor::TypeVisitor<'db> + ?Sized>(
|
|||
KnownInstanceType::TypeAliasType(type_alias) => {
|
||||
visitor.visit_type_alias_type(db, type_alias);
|
||||
}
|
||||
KnownInstanceType::Deprecated(_) | KnownInstanceType::ConstraintSet(_) => {
|
||||
KnownInstanceType::Deprecated(_)
|
||||
| KnownInstanceType::ConstraintSet(_)
|
||||
| KnownInstanceType::GenericContext(_) => {
|
||||
// Nothing to visit
|
||||
}
|
||||
KnownInstanceType::Field(field) => {
|
||||
|
|
@ -8061,15 +8071,7 @@ impl<'db> KnownInstanceType<'db> {
|
|||
Self::TypeAliasType(type_alias) => {
|
||||
Self::TypeAliasType(type_alias.normalized_impl(db, visitor))
|
||||
}
|
||||
Self::Deprecated(deprecated) => {
|
||||
// Nothing to normalize
|
||||
Self::Deprecated(deprecated)
|
||||
}
|
||||
Self::Field(field) => Self::Field(field.normalized_impl(db, visitor)),
|
||||
Self::ConstraintSet(set) => {
|
||||
// Nothing to normalize
|
||||
Self::ConstraintSet(set)
|
||||
}
|
||||
Self::UnionType(list) => Self::UnionType(list.normalized_impl(db, visitor)),
|
||||
Self::Literal(ty) => Self::Literal(ty.normalized_impl(db, visitor)),
|
||||
Self::Annotated(ty) => Self::Annotated(ty.normalized_impl(db, visitor)),
|
||||
|
|
@ -8078,6 +8080,10 @@ impl<'db> KnownInstanceType<'db> {
|
|||
newtype
|
||||
.map_base_class_type(db, |class_type| class_type.normalized_impl(db, visitor)),
|
||||
),
|
||||
Self::Deprecated(_) | Self::ConstraintSet(_) | Self::GenericContext(_) => {
|
||||
// Nothing to normalize
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8095,6 +8101,7 @@ impl<'db> KnownInstanceType<'db> {
|
|||
Self::Deprecated(_) => KnownClass::Deprecated,
|
||||
Self::Field(_) => KnownClass::Field,
|
||||
Self::ConstraintSet(_) => KnownClass::ConstraintSet,
|
||||
Self::GenericContext(_) => KnownClass::GenericContext,
|
||||
Self::UnionType(_) => KnownClass::UnionType,
|
||||
Self::Literal(_) | Self::Annotated(_) | Self::TypeGenericAlias(_) => {
|
||||
KnownClass::GenericAlias
|
||||
|
|
@ -8179,6 +8186,13 @@ impl<'db> KnownInstanceType<'db> {
|
|||
constraints.display(self.db)
|
||||
)
|
||||
}
|
||||
KnownInstanceType::GenericContext(generic_context) => {
|
||||
write!(
|
||||
f,
|
||||
"ty_extensions.GenericContext{}",
|
||||
generic_context.display_full(self.db)
|
||||
)
|
||||
}
|
||||
KnownInstanceType::UnionType(_) => f.write_str("types.UnionType"),
|
||||
KnownInstanceType::Literal(_) => f.write_str("<typing.Literal special form>"),
|
||||
KnownInstanceType::Annotated(_) => {
|
||||
|
|
@ -8423,6 +8437,8 @@ enum InvalidTypeExpression<'db> {
|
|||
Field,
|
||||
/// Same for `ty_extensions.ConstraintSet`
|
||||
ConstraintSet,
|
||||
/// Same for `ty_extensions.GenericContext`
|
||||
GenericContext,
|
||||
/// Same for `typing.TypedDict`
|
||||
TypedDict,
|
||||
/// Type qualifiers are always invalid in *type expressions*,
|
||||
|
|
@ -8475,6 +8491,9 @@ impl<'db> InvalidTypeExpression<'db> {
|
|||
InvalidTypeExpression::ConstraintSet => {
|
||||
f.write_str("`ty_extensions.ConstraintSet` is not allowed in type expressions")
|
||||
}
|
||||
InvalidTypeExpression::GenericContext => {
|
||||
f.write_str("`ty_extensions.GenericContext` is not allowed in type expressions")
|
||||
}
|
||||
InvalidTypeExpression::TypedDict => {
|
||||
f.write_str(
|
||||
"The special form `typing.TypedDict` is not allowed in type expressions. \
|
||||
|
|
|
|||
|
|
@ -782,6 +782,12 @@ impl<'db> Bindings<'db> {
|
|||
|
||||
Some(KnownFunction::GenericContext) => {
|
||||
if let [Some(ty)] = overload.parameter_types() {
|
||||
let wrap_generic_context = |generic_context| {
|
||||
Type::KnownInstance(KnownInstanceType::GenericContext(
|
||||
generic_context,
|
||||
))
|
||||
};
|
||||
|
||||
let function_generic_context = |function: FunctionType<'db>| {
|
||||
let union = UnionType::from_elements(
|
||||
db,
|
||||
|
|
@ -790,7 +796,7 @@ impl<'db> Bindings<'db> {
|
|||
.overloads
|
||||
.iter()
|
||||
.filter_map(|signature| signature.generic_context)
|
||||
.map(|generic_context| generic_context.as_tuple(db)),
|
||||
.map(wrap_generic_context),
|
||||
);
|
||||
if union.is_never() {
|
||||
Type::none(db)
|
||||
|
|
@ -804,7 +810,7 @@ impl<'db> Bindings<'db> {
|
|||
overload.set_return_type(match ty {
|
||||
Type::ClassLiteral(class) => class
|
||||
.generic_context(db)
|
||||
.map(|generic_context| generic_context.as_tuple(db))
|
||||
.map(wrap_generic_context)
|
||||
.unwrap_or_else(|| Type::none(db)),
|
||||
|
||||
Type::FunctionLiteral(function) => {
|
||||
|
|
@ -819,7 +825,7 @@ impl<'db> Bindings<'db> {
|
|||
TypeAliasType::PEP695(alias),
|
||||
)) => alias
|
||||
.generic_context(db)
|
||||
.map(|generic_context| generic_context.as_tuple(db))
|
||||
.map(wrap_generic_context)
|
||||
.unwrap_or_else(|| Type::none(db)),
|
||||
|
||||
_ => Type::none(db),
|
||||
|
|
|
|||
|
|
@ -3956,6 +3956,7 @@ pub enum KnownClass {
|
|||
Path,
|
||||
// ty_extensions
|
||||
ConstraintSet,
|
||||
GenericContext,
|
||||
}
|
||||
|
||||
impl KnownClass {
|
||||
|
|
@ -4059,6 +4060,7 @@ impl KnownClass {
|
|||
| Self::NamedTupleFallback
|
||||
| Self::NamedTupleLike
|
||||
| Self::ConstraintSet
|
||||
| Self::GenericContext
|
||||
| Self::ProtocolMeta
|
||||
| Self::TypedDictFallback => Some(Truthiness::Ambiguous),
|
||||
|
||||
|
|
@ -4142,6 +4144,7 @@ impl KnownClass {
|
|||
| KnownClass::NamedTupleFallback
|
||||
| KnownClass::NamedTupleLike
|
||||
| KnownClass::ConstraintSet
|
||||
| KnownClass::GenericContext
|
||||
| KnownClass::TypedDictFallback
|
||||
| KnownClass::BuiltinFunctionType
|
||||
| KnownClass::ProtocolMeta
|
||||
|
|
@ -4225,6 +4228,7 @@ impl KnownClass {
|
|||
| KnownClass::NamedTupleFallback
|
||||
| KnownClass::NamedTupleLike
|
||||
| KnownClass::ConstraintSet
|
||||
| KnownClass::GenericContext
|
||||
| KnownClass::TypedDictFallback
|
||||
| KnownClass::BuiltinFunctionType
|
||||
| KnownClass::ProtocolMeta
|
||||
|
|
@ -4308,6 +4312,7 @@ impl KnownClass {
|
|||
| KnownClass::NamedTupleLike
|
||||
| KnownClass::NamedTupleFallback
|
||||
| KnownClass::ConstraintSet
|
||||
| KnownClass::GenericContext
|
||||
| KnownClass::BuiltinFunctionType
|
||||
| KnownClass::ProtocolMeta
|
||||
| KnownClass::Template
|
||||
|
|
@ -4402,6 +4407,7 @@ impl KnownClass {
|
|||
| Self::InitVar
|
||||
| Self::NamedTupleFallback
|
||||
| Self::ConstraintSet
|
||||
| Self::GenericContext
|
||||
| Self::TypedDictFallback
|
||||
| Self::BuiltinFunctionType
|
||||
| Self::ProtocolMeta
|
||||
|
|
@ -4491,6 +4497,7 @@ impl KnownClass {
|
|||
| KnownClass::Template
|
||||
| KnownClass::Path
|
||||
| KnownClass::ConstraintSet
|
||||
| KnownClass::GenericContext
|
||||
| KnownClass::InitVar => false,
|
||||
KnownClass::NamedTupleFallback | KnownClass::TypedDictFallback => true,
|
||||
}
|
||||
|
|
@ -4599,6 +4606,7 @@ impl KnownClass {
|
|||
Self::NamedTupleFallback => "NamedTupleFallback",
|
||||
Self::NamedTupleLike => "NamedTupleLike",
|
||||
Self::ConstraintSet => "ConstraintSet",
|
||||
Self::GenericContext => "GenericContext",
|
||||
Self::TypedDictFallback => "TypedDictFallback",
|
||||
Self::Template => "Template",
|
||||
Self::Path => "Path",
|
||||
|
|
@ -4910,7 +4918,9 @@ impl KnownClass {
|
|||
| Self::OrderedDict => KnownModule::Collections,
|
||||
Self::Field | Self::KwOnly | Self::InitVar => KnownModule::Dataclasses,
|
||||
Self::NamedTupleFallback | Self::TypedDictFallback => KnownModule::TypeCheckerInternals,
|
||||
Self::NamedTupleLike | Self::ConstraintSet => KnownModule::TyExtensions,
|
||||
Self::NamedTupleLike | Self::ConstraintSet | Self::GenericContext => {
|
||||
KnownModule::TyExtensions
|
||||
}
|
||||
Self::Template => KnownModule::Templatelib,
|
||||
Self::Path => KnownModule::Pathlib,
|
||||
}
|
||||
|
|
@ -4993,6 +5003,7 @@ impl KnownClass {
|
|||
| Self::NamedTupleFallback
|
||||
| Self::NamedTupleLike
|
||||
| Self::ConstraintSet
|
||||
| Self::GenericContext
|
||||
| Self::TypedDictFallback
|
||||
| Self::BuiltinFunctionType
|
||||
| Self::ProtocolMeta
|
||||
|
|
@ -5081,6 +5092,7 @@ impl KnownClass {
|
|||
| Self::NamedTupleFallback
|
||||
| Self::NamedTupleLike
|
||||
| Self::ConstraintSet
|
||||
| Self::GenericContext
|
||||
| Self::TypedDictFallback
|
||||
| Self::BuiltinFunctionType
|
||||
| Self::ProtocolMeta
|
||||
|
|
@ -5184,6 +5196,7 @@ impl KnownClass {
|
|||
"NamedTupleFallback" => &[Self::NamedTupleFallback],
|
||||
"NamedTupleLike" => &[Self::NamedTupleLike],
|
||||
"ConstraintSet" => &[Self::ConstraintSet],
|
||||
"GenericContext" => &[Self::GenericContext],
|
||||
"TypedDictFallback" => &[Self::TypedDictFallback],
|
||||
"Template" => &[Self::Template],
|
||||
"Path" => &[Self::Path],
|
||||
|
|
@ -5261,6 +5274,7 @@ impl KnownClass {
|
|||
| Self::ExtensionsTypeVar
|
||||
| Self::NamedTupleLike
|
||||
| Self::ConstraintSet
|
||||
| Self::GenericContext
|
||||
| Self::Awaitable
|
||||
| Self::Generator
|
||||
| Self::Template
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ impl<'db> ClassBase<'db> {
|
|||
| KnownInstanceType::Deprecated(_)
|
||||
| KnownInstanceType::Field(_)
|
||||
| KnownInstanceType::ConstraintSet(_)
|
||||
| KnownInstanceType::GenericContext(_)
|
||||
| KnownInstanceType::UnionType(_)
|
||||
| KnownInstanceType::Literal(_)
|
||||
// A class inheriting from a newtype would make intuitive sense, but newtype
|
||||
|
|
|
|||
|
|
@ -892,6 +892,16 @@ impl<'db> GenericContext<'db> {
|
|||
pub fn display(&'db self, db: &'db dyn Db) -> DisplayGenericContext<'db> {
|
||||
Self::display_with(self, db, DisplaySettings::default())
|
||||
}
|
||||
|
||||
pub fn display_full(&'db self, db: &'db dyn Db) -> DisplayGenericContext<'db> {
|
||||
DisplayGenericContext {
|
||||
generic_context: self,
|
||||
db,
|
||||
settings: DisplaySettings::default(),
|
||||
full: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_with(
|
||||
&'db self,
|
||||
db: &'db dyn Db,
|
||||
|
|
@ -901,6 +911,7 @@ impl<'db> GenericContext<'db> {
|
|||
generic_context: self,
|
||||
db,
|
||||
settings,
|
||||
full: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -914,12 +925,9 @@ struct DisplayOptionalGenericContext<'db> {
|
|||
impl Display for DisplayOptionalGenericContext<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
if let Some(generic_context) = self.generic_context {
|
||||
DisplayGenericContext {
|
||||
generic_context,
|
||||
db: self.db,
|
||||
settings: self.settings.clone(),
|
||||
}
|
||||
.fmt(f)
|
||||
generic_context
|
||||
.display_with(self.db, self.settings.clone())
|
||||
.fmt(f)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -931,10 +939,11 @@ pub struct DisplayGenericContext<'db> {
|
|||
db: &'db dyn Db,
|
||||
#[expect(dead_code)]
|
||||
settings: DisplaySettings<'db>,
|
||||
full: bool,
|
||||
}
|
||||
|
||||
impl Display for DisplayGenericContext<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
impl DisplayGenericContext<'_> {
|
||||
fn fmt_normal(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let variables = self.generic_context.variables(self.db);
|
||||
|
||||
let non_implicit_variables: Vec<_> = variables
|
||||
|
|
@ -954,6 +963,28 @@ impl Display for DisplayGenericContext<'_> {
|
|||
}
|
||||
f.write_char(']')
|
||||
}
|
||||
|
||||
fn fmt_full(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let variables = self.generic_context.variables(self.db);
|
||||
f.write_char('[')?;
|
||||
for (idx, bound_typevar) in variables.enumerate() {
|
||||
if idx > 0 {
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
bound_typevar.identity(self.db).display(self.db).fmt(f)?;
|
||||
}
|
||||
f.write_char(']')
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for DisplayGenericContext<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
if self.full {
|
||||
self.fmt_full(f)
|
||||
} else {
|
||||
self.fmt_normal(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'db> Specialization<'db> {
|
||||
|
|
|
|||
|
|
@ -474,11 +474,6 @@ impl<'db> GenericContext<'db> {
|
|||
self.specialize(db, types.into())
|
||||
}
|
||||
|
||||
/// Returns a tuple type of the typevars introduced by this generic context.
|
||||
pub(crate) fn as_tuple(self, db: &'db dyn Db) -> Type<'db> {
|
||||
Type::heterogeneous_tuple(db, self.variables(db).map(Type::TypeVar))
|
||||
}
|
||||
|
||||
pub(crate) fn is_subset_of(self, db: &'db dyn Db, other: GenericContext<'db>) -> bool {
|
||||
let other_variables = other.variables_inner(db);
|
||||
self.variables(db)
|
||||
|
|
|
|||
|
|
@ -783,6 +783,15 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
|||
}
|
||||
Type::unknown()
|
||||
}
|
||||
KnownInstanceType::GenericContext(_) => {
|
||||
self.infer_type_expression(slice);
|
||||
if let Some(builder) = self.context.report_lint(&INVALID_TYPE_FORM, subscript) {
|
||||
builder.into_diagnostic(format_args!(
|
||||
"`ty_extensions.GenericContext` is not allowed in type expressions",
|
||||
));
|
||||
}
|
||||
Type::unknown()
|
||||
}
|
||||
KnownInstanceType::TypeVar(_) => {
|
||||
self.infer_type_expression(slice);
|
||||
todo_type!("TypeVar annotations")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue