mirror of https://github.com/astral-sh/ruff
[ty] Fix #1607
This commit is contained in:
parent
8c80d76d6e
commit
2e6a64ada5
|
|
@ -392,8 +392,8 @@ TransparentAlias = T
|
||||||
MyOptional = T | None
|
MyOptional = T | None
|
||||||
|
|
||||||
# TODO: Consider displaying this as `<class 'list[T]'>`, … instead? (and similar for some others below)
|
# TODO: Consider displaying this as `<class 'list[T]'>`, … instead? (and similar for some others below)
|
||||||
reveal_type(MyList) # revealed: <class 'list[typing.TypeVar]'>
|
reveal_type(MyList) # revealed: <class 'list[T]'>
|
||||||
reveal_type(MyDict) # revealed: <class 'dict[typing.TypeVar, typing.TypeVar]'>
|
reveal_type(MyDict) # revealed: <class 'dict[T, U]'>
|
||||||
reveal_type(MyType) # revealed: GenericAlias
|
reveal_type(MyType) # revealed: GenericAlias
|
||||||
reveal_type(IntAndType) # revealed: <class 'tuple[int, typing.TypeVar]'>
|
reveal_type(IntAndType) # revealed: <class 'tuple[int, typing.TypeVar]'>
|
||||||
reveal_type(Pair) # revealed: <class 'tuple[typing.TypeVar, typing.TypeVar]'>
|
reveal_type(Pair) # revealed: <class 'tuple[typing.TypeVar, typing.TypeVar]'>
|
||||||
|
|
@ -445,7 +445,7 @@ U = TypeVar("U")
|
||||||
|
|
||||||
DictStrTo = MyDict[str, U]
|
DictStrTo = MyDict[str, U]
|
||||||
|
|
||||||
reveal_type(DictStrTo) # revealed: <class 'dict[str, typing.TypeVar]'>
|
reveal_type(DictStrTo) # revealed: <class 'dict[str, U]'>
|
||||||
|
|
||||||
def _(
|
def _(
|
||||||
dict_str_to_int: DictStrTo[int],
|
dict_str_to_int: DictStrTo[int],
|
||||||
|
|
@ -480,7 +480,7 @@ A generic implicit type alias can also be used in another generic implicit type
|
||||||
```py
|
```py
|
||||||
MyOtherList = MyList[T]
|
MyOtherList = MyList[T]
|
||||||
|
|
||||||
reveal_type(MyOtherList) # revealed: <class 'list[typing.TypeVar]'>
|
reveal_type(MyOtherList) # revealed: <class 'list[T]'>
|
||||||
|
|
||||||
def _(
|
def _(
|
||||||
list_of_ints: MyOtherList[int],
|
list_of_ints: MyOtherList[int],
|
||||||
|
|
@ -498,9 +498,9 @@ def _(
|
||||||
my_callable: MyCallable,
|
my_callable: MyCallable,
|
||||||
):
|
):
|
||||||
# TODO: Should be `list[Unknown]`
|
# TODO: Should be `list[Unknown]`
|
||||||
reveal_type(my_list) # revealed: list[typing.TypeVar]
|
reveal_type(my_list) # revealed: list[T]
|
||||||
# TODO: Should be `dict[Unknown, Unknown]`
|
# TODO: Should be `dict[Unknown, Unknown]`
|
||||||
reveal_type(my_dict) # revealed: dict[typing.TypeVar, typing.TypeVar]
|
reveal_type(my_dict) # revealed: dict[T, U]
|
||||||
# TODO: Should be `(...) -> Unknown`
|
# TODO: Should be `(...) -> Unknown`
|
||||||
reveal_type(my_callable) # revealed: (...) -> typing.TypeVar
|
reveal_type(my_callable) # revealed: (...) -> typing.TypeVar
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -7250,6 +7250,8 @@ impl<'db> Type<'db> {
|
||||||
instance.apply_type_mapping_impl(db, type_mapping, tcx, visitor)
|
instance.apply_type_mapping_impl(db, type_mapping, tcx, visitor)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Type::NewTypeInstance(_) if matches!(type_mapping, TypeMapping::BindLegacyTypevars(_)) => self,
|
||||||
|
|
||||||
Type::NewTypeInstance(newtype) => visitor.visit(self, || {
|
Type::NewTypeInstance(newtype) => visitor.visit(self, || {
|
||||||
Type::NewTypeInstance(newtype.map_base_class_type(db, |class_type| {
|
Type::NewTypeInstance(newtype.map_base_class_type(db, |class_type| {
|
||||||
class_type.apply_type_mapping_impl(db, type_mapping, tcx, visitor)
|
class_type.apply_type_mapping_impl(db, type_mapping, tcx, visitor)
|
||||||
|
|
@ -7328,6 +7330,8 @@ impl<'db> Type<'db> {
|
||||||
// TODO(jelle): Materialize should be handled differently, since TypeIs is invariant
|
// TODO(jelle): Materialize should be handled differently, since TypeIs is invariant
|
||||||
Type::TypeIs(type_is) => type_is.with_type(db, type_is.return_type(db).apply_type_mapping(db, type_mapping, tcx)),
|
Type::TypeIs(type_is) => type_is.with_type(db, type_is.return_type(db).apply_type_mapping(db, type_mapping, tcx)),
|
||||||
|
|
||||||
|
Type::TypeAlias(_) if matches!(type_mapping, TypeMapping::BindLegacyTypevars(_)) => self,
|
||||||
|
|
||||||
Type::TypeAlias(alias) => {
|
Type::TypeAlias(alias) => {
|
||||||
// Do not call `value_type` here. `value_type` does the specialization internally, so `apply_type_mapping` is performed without `visitor` inheritance.
|
// Do not call `value_type` here. `value_type` does the specialization internally, so `apply_type_mapping` is performed without `visitor` inheritance.
|
||||||
// In the case of recursive type aliases, this leads to infinite recursion.
|
// In the case of recursive type aliases, this leads to infinite recursion.
|
||||||
|
|
|
||||||
|
|
@ -101,14 +101,14 @@ use crate::types::typed_dict::{
|
||||||
};
|
};
|
||||||
use crate::types::visitor::any_over_type;
|
use crate::types::visitor::any_over_type;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
CallDunderError, CallableBinding, CallableType, ClassLiteral, ClassType, DataclassParams,
|
BindingContext, CallDunderError, CallableBinding, CallableType, ClassLiteral, ClassType,
|
||||||
DynamicType, InternedType, IntersectionBuilder, IntersectionType, KnownClass,
|
DataclassParams, DynamicType, InternedType, IntersectionBuilder, IntersectionType, KnownClass,
|
||||||
KnownInstanceType, LintDiagnosticGuard, MemberLookupPolicy, MetaclassCandidate,
|
KnownInstanceType, LintDiagnosticGuard, MemberLookupPolicy, MetaclassCandidate,
|
||||||
PEP695TypeAliasType, Parameter, ParameterForm, Parameters, SpecialFormType, SubclassOfType,
|
PEP695TypeAliasType, Parameter, ParameterForm, Parameters, SpecialFormType, SubclassOfType,
|
||||||
TrackedConstraintSet, Truthiness, Type, TypeAliasType, TypeAndQualifiers, TypeContext,
|
TrackedConstraintSet, Truthiness, Type, TypeAliasType, TypeAndQualifiers, TypeContext,
|
||||||
TypeQualifiers, TypeVarBoundOrConstraintsEvaluation, TypeVarDefaultEvaluation, TypeVarIdentity,
|
TypeMapping, TypeQualifiers, TypeVarBoundOrConstraintsEvaluation, TypeVarDefaultEvaluation,
|
||||||
TypeVarInstance, TypeVarKind, TypeVarVariance, TypedDictType, UnionBuilder, UnionType,
|
TypeVarIdentity, TypeVarInstance, TypeVarKind, TypeVarVariance, TypedDictType, UnionBuilder,
|
||||||
UnionTypeInstance, binding_type, todo_type,
|
UnionType, UnionTypeInstance, binding_type, todo_type,
|
||||||
};
|
};
|
||||||
use crate::types::{ClassBase, add_inferred_python_version_hint_to_diagnostic};
|
use crate::types::{ClassBase, add_inferred_python_version_hint_to_diagnostic};
|
||||||
use crate::unpack::{EvaluationMode, UnpackPosition};
|
use crate::unpack::{EvaluationMode, UnpackPosition};
|
||||||
|
|
@ -11051,6 +11051,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
value_ty,
|
value_ty,
|
||||||
generic_context,
|
generic_context,
|
||||||
specialize,
|
specialize,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -11075,6 +11076,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
value_ty,
|
value_ty,
|
||||||
generic_context,
|
generic_context,
|
||||||
specialize,
|
specialize,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -11084,12 +11086,30 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
value_ty: Type<'db>,
|
value_ty: Type<'db>,
|
||||||
generic_context: GenericContext<'db>,
|
generic_context: GenericContext<'db>,
|
||||||
specialize: impl FnOnce(&[Option<Type<'db>>]) -> Type<'db>,
|
specialize: impl FnOnce(&[Option<Type<'db>>]) -> Type<'db>,
|
||||||
|
bind_legacy_typevars: bool,
|
||||||
) -> Type<'db> {
|
) -> Type<'db> {
|
||||||
let slice_node = subscript.slice.as_ref();
|
let slice_node = subscript.slice.as_ref();
|
||||||
|
|
||||||
|
let db = self.db();
|
||||||
|
let do_bind_legacy_typevars = |ty: Type<'db>| {
|
||||||
|
if bind_legacy_typevars {
|
||||||
|
ty.apply_type_mapping(
|
||||||
|
db,
|
||||||
|
&TypeMapping::BindLegacyTypevars(BindingContext::Synthetic),
|
||||||
|
TypeContext::default(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let call_argument_types = match slice_node {
|
let call_argument_types = match slice_node {
|
||||||
ast::Expr::Tuple(tuple) => {
|
ast::Expr::Tuple(tuple) => {
|
||||||
let arguments = CallArguments::positional(
|
let arguments = CallArguments::positional(
|
||||||
tuple.elts.iter().map(|elt| self.infer_type_expression(elt)),
|
tuple
|
||||||
|
.elts
|
||||||
|
.iter()
|
||||||
|
.map(|elt| do_bind_legacy_typevars(self.infer_type_expression(elt))),
|
||||||
);
|
);
|
||||||
self.store_expression_type(
|
self.store_expression_type(
|
||||||
slice_node,
|
slice_node,
|
||||||
|
|
@ -11097,8 +11117,11 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
);
|
);
|
||||||
arguments
|
arguments
|
||||||
}
|
}
|
||||||
_ => CallArguments::positional([self.infer_type_expression(slice_node)]),
|
_ => CallArguments::positional([do_bind_legacy_typevars(
|
||||||
|
self.infer_type_expression(slice_node),
|
||||||
|
)]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let binding = Binding::single(value_ty, generic_context.signature(self.db()));
|
let binding = Binding::single(value_ty, generic_context.signature(self.db()));
|
||||||
let bindings = match Bindings::from(binding)
|
let bindings = match Bindings::from(binding)
|
||||||
.match_parameters(self.db(), &call_argument_types)
|
.match_parameters(self.db(), &call_argument_types)
|
||||||
|
|
|
||||||
|
|
@ -755,6 +755,7 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
||||||
value_ty,
|
value_ty,
|
||||||
generic_context,
|
generic_context,
|
||||||
specialize,
|
specialize,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue