Compare commits
1 Commits
jack/loop-
...
dcreager/s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9eff2734bb |
@@ -659,6 +659,7 @@ impl<'db> Type<'db> {
|
|||||||
.to_instance(db)
|
.to_instance(db)
|
||||||
.is_subtype_of(db, target)
|
.is_subtype_of(db, target)
|
||||||
}
|
}
|
||||||
|
(Type::Callable(CallableType::SpecializedGetitem), _) => self == target,
|
||||||
|
|
||||||
(
|
(
|
||||||
Type::Callable(CallableType::General(self_callable)),
|
Type::Callable(CallableType::General(self_callable)),
|
||||||
@@ -1053,7 +1054,8 @@ impl<'db> Type<'db> {
|
|||||||
| Type::Callable(
|
| Type::Callable(
|
||||||
CallableType::BoundMethod(..)
|
CallableType::BoundMethod(..)
|
||||||
| CallableType::MethodWrapperDunderGet(..)
|
| CallableType::MethodWrapperDunderGet(..)
|
||||||
| CallableType::WrapperDescriptorDunderGet,
|
| CallableType::WrapperDescriptorDunderGet
|
||||||
|
| CallableType::SpecializedGetitem,
|
||||||
)
|
)
|
||||||
| Type::ModuleLiteral(..)
|
| Type::ModuleLiteral(..)
|
||||||
| Type::ClassLiteral(..)
|
| Type::ClassLiteral(..)
|
||||||
@@ -1067,7 +1069,8 @@ impl<'db> Type<'db> {
|
|||||||
| Type::Callable(
|
| Type::Callable(
|
||||||
CallableType::BoundMethod(..)
|
CallableType::BoundMethod(..)
|
||||||
| CallableType::MethodWrapperDunderGet(..)
|
| CallableType::MethodWrapperDunderGet(..)
|
||||||
| CallableType::WrapperDescriptorDunderGet,
|
| CallableType::WrapperDescriptorDunderGet
|
||||||
|
| CallableType::SpecializedGetitem,
|
||||||
)
|
)
|
||||||
| Type::ModuleLiteral(..)
|
| Type::ModuleLiteral(..)
|
||||||
| Type::ClassLiteral(..)
|
| Type::ClassLiteral(..)
|
||||||
@@ -1267,6 +1270,9 @@ impl<'db> Type<'db> {
|
|||||||
Type::Callable(CallableType::WrapperDescriptorDunderGet),
|
Type::Callable(CallableType::WrapperDescriptorDunderGet),
|
||||||
) => !KnownClass::WrapperDescriptorType.is_subclass_of(db, class),
|
) => !KnownClass::WrapperDescriptorType.is_subclass_of(db, class),
|
||||||
|
|
||||||
|
(Type::Callable(CallableType::SpecializedGetitem), Type::Instance(_))
|
||||||
|
| (Type::Instance(_), Type::Callable(CallableType::SpecializedGetitem)) => true,
|
||||||
|
|
||||||
(Type::ModuleLiteral(..), other @ Type::Instance(..))
|
(Type::ModuleLiteral(..), other @ Type::Instance(..))
|
||||||
| (other @ Type::Instance(..), Type::ModuleLiteral(..)) => {
|
| (other @ Type::Instance(..), Type::ModuleLiteral(..)) => {
|
||||||
// Modules *can* actually be instances of `ModuleType` subclasses
|
// Modules *can* actually be instances of `ModuleType` subclasses
|
||||||
@@ -1321,7 +1327,8 @@ impl<'db> Type<'db> {
|
|||||||
| Type::Callable(
|
| Type::Callable(
|
||||||
CallableType::BoundMethod(_)
|
CallableType::BoundMethod(_)
|
||||||
| CallableType::MethodWrapperDunderGet(_)
|
| CallableType::MethodWrapperDunderGet(_)
|
||||||
| CallableType::WrapperDescriptorDunderGet,
|
| CallableType::WrapperDescriptorDunderGet
|
||||||
|
| CallableType::SpecializedGetitem,
|
||||||
)
|
)
|
||||||
| Type::ModuleLiteral(..)
|
| Type::ModuleLiteral(..)
|
||||||
| Type::IntLiteral(_)
|
| Type::IntLiteral(_)
|
||||||
@@ -1391,7 +1398,8 @@ impl<'db> Type<'db> {
|
|||||||
| Type::Callable(
|
| Type::Callable(
|
||||||
CallableType::BoundMethod(_)
|
CallableType::BoundMethod(_)
|
||||||
| CallableType::MethodWrapperDunderGet(_)
|
| CallableType::MethodWrapperDunderGet(_)
|
||||||
| CallableType::WrapperDescriptorDunderGet,
|
| CallableType::WrapperDescriptorDunderGet
|
||||||
|
| CallableType::SpecializedGetitem,
|
||||||
)
|
)
|
||||||
| Type::ClassLiteral(..)
|
| Type::ClassLiteral(..)
|
||||||
| Type::ModuleLiteral(..)
|
| Type::ModuleLiteral(..)
|
||||||
@@ -1440,7 +1448,8 @@ impl<'db> Type<'db> {
|
|||||||
| Type::Callable(
|
| Type::Callable(
|
||||||
CallableType::BoundMethod(..)
|
CallableType::BoundMethod(..)
|
||||||
| CallableType::MethodWrapperDunderGet(..)
|
| CallableType::MethodWrapperDunderGet(..)
|
||||||
| CallableType::WrapperDescriptorDunderGet,
|
| CallableType::WrapperDescriptorDunderGet
|
||||||
|
| CallableType::SpecializedGetitem,
|
||||||
)
|
)
|
||||||
| Type::ModuleLiteral(..)
|
| Type::ModuleLiteral(..)
|
||||||
| Type::ClassLiteral(..)
|
| Type::ClassLiteral(..)
|
||||||
@@ -1513,6 +1522,7 @@ impl<'db> Type<'db> {
|
|||||||
// Hard code this knowledge, as we look up `__set__` and `__delete__` on `FunctionType` often.
|
// Hard code this knowledge, as we look up `__set__` and `__delete__` on `FunctionType` often.
|
||||||
Some(Symbol::Unbound.into())
|
Some(Symbol::Unbound.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// We currently hard-code the knowledge that the following known classes are not
|
// We currently hard-code the knowledge that the following known classes are not
|
||||||
// descriptors, i.e. that they have no `__get__` method. This is not wrong and
|
// descriptors, i.e. that they have no `__get__` method. This is not wrong and
|
||||||
@@ -1652,7 +1662,8 @@ impl<'db> Type<'db> {
|
|||||||
.to_instance(db)
|
.to_instance(db)
|
||||||
.instance_member(db, name)
|
.instance_member(db, name)
|
||||||
}
|
}
|
||||||
Type::Callable(CallableType::General(_)) => {
|
Type::Callable(CallableType::SpecializedGetitem)
|
||||||
|
| Type::Callable(CallableType::General(_)) => {
|
||||||
KnownClass::Object.to_instance(db).instance_member(db, name)
|
KnownClass::Object.to_instance(db).instance_member(db, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2006,22 +2017,32 @@ impl<'db> Type<'db> {
|
|||||||
.to_instance(db)
|
.to_instance(db)
|
||||||
.member(db, &name)
|
.member(db, &name)
|
||||||
}
|
}
|
||||||
Type::Callable(CallableType::General(_)) => {
|
Type::Callable(CallableType::SpecializedGetitem)
|
||||||
|
| Type::Callable(CallableType::General(_)) => {
|
||||||
KnownClass::Object.to_instance(db).member(db, &name)
|
KnownClass::Object.to_instance(db).member(db, &name)
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Instance(InstanceType { class })
|
Type::Instance(InstanceType { class })
|
||||||
if matches!(name.as_str(), "major" | "minor")
|
if matches!(name_str, "__getitem__" | "major" | "minor")
|
||||||
&& class.is_known(db, KnownClass::VersionInfo) =>
|
&& class.is_known(db, KnownClass::VersionInfo) =>
|
||||||
{
|
{
|
||||||
|
match name_str {
|
||||||
|
"__getitem__" => {
|
||||||
|
Symbol::bound(Type::Callable(CallableType::SpecializedGetitem)).into()
|
||||||
|
}
|
||||||
|
"major" => {
|
||||||
let python_version = Program::get(db).python_version(db);
|
let python_version = Program::get(db).python_version(db);
|
||||||
let segment = if name == "major" {
|
let segment = python_version.major;
|
||||||
python_version.major
|
|
||||||
} else {
|
|
||||||
python_version.minor
|
|
||||||
};
|
|
||||||
Symbol::bound(Type::IntLiteral(segment.into())).into()
|
Symbol::bound(Type::IntLiteral(segment.into())).into()
|
||||||
}
|
}
|
||||||
|
"minor" => {
|
||||||
|
let python_version = Program::get(db).python_version(db);
|
||||||
|
let segment = python_version.minor;
|
||||||
|
Symbol::bound(Type::IntLiteral(segment.into())).into()
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Type::IntLiteral(_) if matches!(name_str, "real" | "numerator") => {
|
Type::IntLiteral(_) if matches!(name_str, "real" | "numerator") => {
|
||||||
Symbol::bound(self).into()
|
Symbol::bound(self).into()
|
||||||
@@ -2455,6 +2476,20 @@ impl<'db> Type<'db> {
|
|||||||
Signatures::single(signature)
|
Signatures::single(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type::Callable(CallableType::SpecializedGetitem) => {
|
||||||
|
let signature = CallableSignature::from_overloads(
|
||||||
|
self,
|
||||||
|
[Signature::new(
|
||||||
|
Parameters::new([Parameter::positional_only(Some(Name::new_static(
|
||||||
|
"slice",
|
||||||
|
)))
|
||||||
|
.with_annotated_type(KnownClass::Int.to_instance(db))]),
|
||||||
|
None,
|
||||||
|
)],
|
||||||
|
);
|
||||||
|
Signatures::single(signature)
|
||||||
|
}
|
||||||
|
|
||||||
Type::FunctionLiteral(function_type) => match function_type.known(db) {
|
Type::FunctionLiteral(function_type) => match function_type.known(db) {
|
||||||
Some(
|
Some(
|
||||||
KnownFunction::IsEquivalentTo
|
KnownFunction::IsEquivalentTo
|
||||||
@@ -3170,7 +3205,8 @@ impl<'db> Type<'db> {
|
|||||||
Type::Callable(CallableType::WrapperDescriptorDunderGet) => {
|
Type::Callable(CallableType::WrapperDescriptorDunderGet) => {
|
||||||
KnownClass::WrapperDescriptorType.to_class_literal(db)
|
KnownClass::WrapperDescriptorType.to_class_literal(db)
|
||||||
}
|
}
|
||||||
Type::Callable(CallableType::General(_)) => KnownClass::Type.to_instance(db),
|
Type::Callable(CallableType::SpecializedGetitem)
|
||||||
|
| Type::Callable(CallableType::General(_)) => KnownClass::Type.to_instance(db),
|
||||||
Type::ModuleLiteral(_) => KnownClass::ModuleType.to_class_literal(db),
|
Type::ModuleLiteral(_) => KnownClass::ModuleType.to_class_literal(db),
|
||||||
Type::Tuple(_) => KnownClass::Tuple.to_class_literal(db),
|
Type::Tuple(_) => KnownClass::Tuple.to_class_literal(db),
|
||||||
Type::ClassLiteral(ClassLiteralType { class }) => class.metaclass(db),
|
Type::ClassLiteral(ClassLiteralType { class }) => class.metaclass(db),
|
||||||
@@ -4857,6 +4893,9 @@ pub enum CallableType<'db> {
|
|||||||
/// type. We currently add this as a separate variant because `FunctionType.__get__`
|
/// type. We currently add this as a separate variant because `FunctionType.__get__`
|
||||||
/// is an overloaded method and we do not support `@overload` yet.
|
/// is an overloaded method and we do not support `@overload` yet.
|
||||||
WrapperDescriptorDunderGet,
|
WrapperDescriptorDunderGet,
|
||||||
|
|
||||||
|
/// Represents specialized `__getitem__` methods
|
||||||
|
SpecializedGetitem,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[salsa::interned(debug)]
|
#[salsa::interned(debug)]
|
||||||
|
|||||||
@@ -110,6 +110,9 @@ impl Display for DisplayRepresentation<'_> {
|
|||||||
Type::Callable(CallableType::WrapperDescriptorDunderGet) => {
|
Type::Callable(CallableType::WrapperDescriptorDunderGet) => {
|
||||||
f.write_str("<wrapper-descriptor `__get__` of `function` objects>")
|
f.write_str("<wrapper-descriptor `__get__` of `function` objects>")
|
||||||
}
|
}
|
||||||
|
Type::Callable(CallableType::SpecializedGetitem) => {
|
||||||
|
f.write_str("<specialized `__getitem__`>")
|
||||||
|
}
|
||||||
Type::Union(union) => union.display(self.db).fmt(f),
|
Type::Union(union) => union.display(self.db).fmt(f),
|
||||||
Type::Intersection(intersection) => intersection.display(self.db).fmt(f),
|
Type::Intersection(intersection) => intersection.display(self.db).fmt(f),
|
||||||
Type::IntLiteral(n) => n.fmt(f),
|
Type::IntLiteral(n) => n.fmt(f),
|
||||||
|
|||||||
@@ -5543,20 +5543,6 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||||||
slice_ty: Type<'db>,
|
slice_ty: Type<'db>,
|
||||||
) -> Type<'db> {
|
) -> Type<'db> {
|
||||||
match (value_ty, slice_ty) {
|
match (value_ty, slice_ty) {
|
||||||
(
|
|
||||||
Type::Instance(instance),
|
|
||||||
Type::IntLiteral(_) | Type::BooleanLiteral(_) | Type::SliceLiteral(_),
|
|
||||||
) if instance
|
|
||||||
.class()
|
|
||||||
.is_known(self.db(), KnownClass::VersionInfo) =>
|
|
||||||
{
|
|
||||||
self.infer_subscript_expression_types(
|
|
||||||
value_node,
|
|
||||||
Type::version_info_tuple(self.db()),
|
|
||||||
slice_ty,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ex) Given `("a", "b", "c", "d")[1]`, return `"b"`
|
// Ex) Given `("a", "b", "c", "d")[1]`, return `"b"`
|
||||||
(Type::Tuple(tuple_ty), Type::IntLiteral(int)) if i32::try_from(int).is_ok() => {
|
(Type::Tuple(tuple_ty), Type::IntLiteral(int)) if i32::try_from(int).is_ok() => {
|
||||||
let elements = tuple_ty.elements(self.db());
|
let elements = tuple_ty.elements(self.db());
|
||||||
@@ -5698,6 +5684,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
|||||||
return err.fallback_return_type(self.db());
|
return err.fallback_return_type(self.db());
|
||||||
}
|
}
|
||||||
Err(CallDunderError::CallError(_, bindings)) => {
|
Err(CallDunderError::CallError(_, bindings)) => {
|
||||||
|
bindings.report_diagnostics(&self.context, value_node.into());
|
||||||
self.context.report_lint(
|
self.context.report_lint(
|
||||||
&CALL_NON_CALLABLE,
|
&CALL_NON_CALLABLE,
|
||||||
value_node,
|
value_node,
|
||||||
|
|||||||
@@ -83,6 +83,13 @@ pub(super) fn union_or_intersection_elements_ordering<'db>(
|
|||||||
(Type::Callable(CallableType::WrapperDescriptorDunderGet), _) => Ordering::Less,
|
(Type::Callable(CallableType::WrapperDescriptorDunderGet), _) => Ordering::Less,
|
||||||
(_, Type::Callable(CallableType::WrapperDescriptorDunderGet)) => Ordering::Greater,
|
(_, Type::Callable(CallableType::WrapperDescriptorDunderGet)) => Ordering::Greater,
|
||||||
|
|
||||||
|
(
|
||||||
|
Type::Callable(CallableType::SpecializedGetitem),
|
||||||
|
Type::Callable(CallableType::SpecializedGetitem),
|
||||||
|
) => Ordering::Equal,
|
||||||
|
(Type::Callable(CallableType::SpecializedGetitem), _) => Ordering::Less,
|
||||||
|
(_, Type::Callable(CallableType::SpecializedGetitem)) => Ordering::Greater,
|
||||||
|
|
||||||
(Type::Callable(CallableType::General(_)), Type::Callable(CallableType::General(_))) => {
|
(Type::Callable(CallableType::General(_)), Type::Callable(CallableType::General(_))) => {
|
||||||
Ordering::Equal
|
Ordering::Equal
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user