mirror of https://github.com/astral-sh/ruff
[ty] Cleanup various APIs
This commit is contained in:
parent
13375d0e42
commit
1a30934c33
|
|
@ -819,17 +819,6 @@ impl<'db> Type<'db> {
|
||||||
.is_some_and(|instance| instance.has_known_class(db, KnownClass::NoneType))
|
.is_some_and(|instance| instance.has_known_class(db, KnownClass::NoneType))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_bool(&self, db: &'db dyn Db) -> bool {
|
|
||||||
self.as_nominal_instance()
|
|
||||||
.is_some_and(|instance| instance.has_known_class(db, KnownClass::Bool))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_enum(&self, db: &'db dyn Db) -> bool {
|
|
||||||
self.as_nominal_instance()
|
|
||||||
.and_then(|instance| crate::types::enums::enum_metadata(db, instance.class_literal(db)))
|
|
||||||
.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return true if this type overrides __eq__ or __ne__ methods
|
/// Return true if this type overrides __eq__ or __ne__ methods
|
||||||
fn overrides_equality(&self, db: &'db dyn Db) -> bool {
|
fn overrides_equality(&self, db: &'db dyn Db) -> bool {
|
||||||
let check_dunder = |dunder_name, allowed_return_value| {
|
let check_dunder = |dunder_name, allowed_return_value| {
|
||||||
|
|
@ -1142,7 +1131,7 @@ impl<'db> Type<'db> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub(crate) fn expect_function_literal(self) -> FunctionType<'db> {
|
pub(crate) const fn expect_function_literal(self) -> FunctionType<'db> {
|
||||||
self.as_function_literal()
|
self.as_function_literal()
|
||||||
.expect("Expected a Type::FunctionLiteral variant")
|
.expect("Expected a Type::FunctionLiteral variant")
|
||||||
}
|
}
|
||||||
|
|
@ -1152,42 +1141,42 @@ impl<'db> Type<'db> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_union_of_single_valued(&self, db: &'db dyn Db) -> bool {
|
pub(crate) fn is_union_of_single_valued(&self, db: &'db dyn Db) -> bool {
|
||||||
self.as_union().is_some_and(|union| {
|
match self {
|
||||||
union.elements(db).iter().all(|ty| {
|
Type::LiteralString => true,
|
||||||
ty.is_single_valued(db)
|
Type::NominalInstance(instance) => {
|
||||||
|| ty.is_bool(db)
|
instance.has_known_class(db, KnownClass::Bool)
|
||||||
|| ty.is_literal_string()
|
|| (enums::enum_metadata(db, instance.class_literal(db)).is_some()
|
||||||
|| (ty.is_enum(db) && !ty.overrides_equality(db))
|
&& !self.overrides_equality(db))
|
||||||
})
|
}
|
||||||
}) || self.is_bool(db)
|
Type::Union(union) => union.elements(db).iter().all(|element| {
|
||||||
|| self.is_literal_string()
|
element.is_single_valued(db) || element.is_union_of_single_valued(db)
|
||||||
|| (self.is_enum(db) && !self.overrides_equality(db))
|
}),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_union_with_single_valued(&self, db: &'db dyn Db) -> bool {
|
pub(crate) fn is_union_with_single_valued(&self, db: &'db dyn Db) -> bool {
|
||||||
self.as_union().is_some_and(|union| {
|
match self {
|
||||||
union.elements(db).iter().any(|ty| {
|
Type::LiteralString => true,
|
||||||
ty.is_single_valued(db)
|
Type::NominalInstance(instance) => {
|
||||||
|| ty.is_bool(db)
|
instance.has_known_class(db, KnownClass::Bool)
|
||||||
|| ty.is_literal_string()
|
|| (enums::enum_metadata(db, instance.class_literal(db)).is_some()
|
||||||
|| (ty.is_enum(db) && !ty.overrides_equality(db))
|
&& !self.overrides_equality(db))
|
||||||
})
|
}
|
||||||
}) || self.is_bool(db)
|
Type::Union(union) => union.elements(db).iter().any(|element| {
|
||||||
|| self.is_literal_string()
|
element.is_single_valued(db) || element.is_union_of_single_valued(db)
|
||||||
|| (self.is_enum(db) && !self.overrides_equality(db))
|
}),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn as_string_literal(self) -> Option<StringLiteralType<'db>> {
|
pub(crate) const fn as_string_literal(self) -> Option<StringLiteralType<'db>> {
|
||||||
match self {
|
match self {
|
||||||
Type::StringLiteral(string_literal) => Some(string_literal),
|
Type::StringLiteral(string_literal) => Some(string_literal),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const fn is_literal_string(&self) -> bool {
|
|
||||||
matches!(self, Type::LiteralString)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn string_literal(db: &'db dyn Db, string: &str) -> Self {
|
pub(crate) fn string_literal(db: &'db dyn Db, string: &str) -> Self {
|
||||||
Self::StringLiteral(StringLiteralType::new(db, string))
|
Self::StringLiteral(StringLiteralType::new(db, string))
|
||||||
}
|
}
|
||||||
|
|
@ -7291,20 +7280,6 @@ impl<'db> Type<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generic_origin(self, db: &'db dyn Db) -> Option<ClassLiteral<'db>> {
|
|
||||||
match self {
|
|
||||||
Type::GenericAlias(generic) => Some(generic.origin(db)),
|
|
||||||
Type::NominalInstance(instance) => {
|
|
||||||
if let ClassType::Generic(generic) = instance.class(db) {
|
|
||||||
Some(generic.origin(db))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn has_divergent_type(self, db: &'db dyn Db, div: Type<'db>) -> bool {
|
pub(super) fn has_divergent_type(self, db: &'db dyn Db, div: Type<'db>) -> bool {
|
||||||
any_over_type(db, self, &|ty| ty == div, false)
|
any_over_type(db, self, &|ty| ty == div, false)
|
||||||
}
|
}
|
||||||
|
|
@ -11138,7 +11113,7 @@ impl<'db> TypeAliasType<'db> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn as_pep_695_type_alias(self) -> Option<PEP695TypeAliasType<'db>> {
|
pub(crate) const fn as_pep_695_type_alias(self) -> Option<PEP695TypeAliasType<'db>> {
|
||||||
match self {
|
match self {
|
||||||
TypeAliasType::PEP695(type_alias) => Some(type_alias),
|
TypeAliasType::PEP695(type_alias) => Some(type_alias),
|
||||||
TypeAliasType::ManualPEP695(_) => None,
|
TypeAliasType::ManualPEP695(_) => None,
|
||||||
|
|
|
||||||
|
|
@ -256,15 +256,14 @@ impl<'a, 'db> FromIterator<(Argument<'a>, Option<Type<'db>>)> for CallArguments<
|
||||||
pub(crate) fn is_expandable_type<'db>(db: &'db dyn Db, ty: Type<'db>) -> bool {
|
pub(crate) fn is_expandable_type<'db>(db: &'db dyn Db, ty: Type<'db>) -> bool {
|
||||||
match ty {
|
match ty {
|
||||||
Type::NominalInstance(instance) => {
|
Type::NominalInstance(instance) => {
|
||||||
let class = instance.class(db);
|
instance.has_known_class(db, KnownClass::Bool)
|
||||||
class.is_known(db, KnownClass::Bool)
|
|
||||||
|| instance.tuple_spec(db).is_some_and(|spec| match &*spec {
|
|| instance.tuple_spec(db).is_some_and(|spec| match &*spec {
|
||||||
Tuple::Fixed(fixed_length_tuple) => fixed_length_tuple
|
Tuple::Fixed(fixed_length_tuple) => fixed_length_tuple
|
||||||
.all_elements()
|
.all_elements()
|
||||||
.any(|element| is_expandable_type(db, *element)),
|
.any(|element| is_expandable_type(db, *element)),
|
||||||
Tuple::Variable(_) => false,
|
Tuple::Variable(_) => false,
|
||||||
})
|
})
|
||||||
|| enum_metadata(db, class.class_literal(db).0).is_some()
|
|| enum_metadata(db, instance.class_literal(db)).is_some()
|
||||||
}
|
}
|
||||||
Type::Union(_) => true,
|
Type::Union(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
@ -278,9 +277,7 @@ fn expand_type<'db>(db: &'db dyn Db, ty: Type<'db>) -> Option<Vec<Type<'db>>> {
|
||||||
// NOTE: Update `is_expandable_type` if this logic changes accordingly.
|
// NOTE: Update `is_expandable_type` if this logic changes accordingly.
|
||||||
match ty {
|
match ty {
|
||||||
Type::NominalInstance(instance) => {
|
Type::NominalInstance(instance) => {
|
||||||
let class = instance.class(db);
|
if instance.has_known_class(db, KnownClass::Bool) {
|
||||||
|
|
||||||
if class.is_known(db, KnownClass::Bool) {
|
|
||||||
return Some(vec![
|
return Some(vec![
|
||||||
Type::BooleanLiteral(true),
|
Type::BooleanLiteral(true),
|
||||||
Type::BooleanLiteral(false),
|
Type::BooleanLiteral(false),
|
||||||
|
|
@ -315,7 +312,7 @@ fn expand_type<'db>(db: &'db dyn Db, ty: Type<'db>) -> Option<Vec<Type<'db>>> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enum_members) = enum_member_literals(db, class.class_literal(db).0, None) {
|
if let Some(enum_members) = enum_member_literals(db, instance.class_literal(db), None) {
|
||||||
return Some(enum_members.collect());
|
return Some(enum_members.collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -377,10 +377,7 @@ impl<'db> ClassType<'db> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn has_pep_695_type_params(self, db: &'db dyn Db) -> bool {
|
pub(super) fn has_pep_695_type_params(self, db: &'db dyn Db) -> bool {
|
||||||
match self {
|
self.class_literal(db).0.has_pep_695_type_params(db)
|
||||||
Self::NonGeneric(class) => class.has_pep_695_type_params(db),
|
|
||||||
Self::Generic(generic) => generic.origin(db).has_pep_695_type_params(db),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the class literal and specialization for this class. For a non-generic class, this
|
/// Returns the class literal and specialization for this class. For a non-generic class, this
|
||||||
|
|
@ -3463,11 +3460,10 @@ impl<'db> ClassLiteral<'db> {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut result = false;
|
let mut result = false;
|
||||||
for explicit_base in class.explicit_bases(db) {
|
for explicit_base in class.explicit_bases(db) {
|
||||||
let explicit_base_class_literal = match explicit_base {
|
let Some(explicit_base) = explicit_base.to_class_type(db) else {
|
||||||
Type::ClassLiteral(class_literal) => *class_literal,
|
continue;
|
||||||
Type::GenericAlias(generic_alias) => generic_alias.origin(db),
|
|
||||||
_ => continue,
|
|
||||||
};
|
};
|
||||||
|
let explicit_base_class_literal = explicit_base.class_literal(db).0;
|
||||||
if !classes_on_stack.insert(explicit_base_class_literal) {
|
if !classes_on_stack.insert(explicit_base_class_literal) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1379,15 +1379,10 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
KnownClass::OrderedDict,
|
KnownClass::OrderedDict,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
ty.as_nominal_instance().is_some_and(|instance| {
|
||||||
SAFE_MUTABLE_CLASSES
|
SAFE_MUTABLE_CLASSES
|
||||||
.iter()
|
.iter()
|
||||||
.map(|class| class.to_instance(db))
|
.any(|known_class| instance.has_known_class(db, *known_class))
|
||||||
.any(|safe_mutable_class| {
|
|
||||||
ty.is_equivalent_to(db, safe_mutable_class)
|
|
||||||
|| ty
|
|
||||||
.generic_origin(db)
|
|
||||||
.zip(safe_mutable_class.generic_origin(db))
|
|
||||||
.is_some_and(|(l, r)| l == r)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -614,9 +614,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
||||||
for element in lhs_union.elements(self.db) {
|
for element in lhs_union.elements(self.db) {
|
||||||
// Keep only the non-single-valued portion of the original type.
|
// Keep only the non-single-valued portion of the original type.
|
||||||
if !element.is_single_valued(self.db)
|
if !element.is_single_valued(self.db)
|
||||||
&& !element.is_literal_string()
|
&& !element.is_union_of_single_valued(self.db)
|
||||||
&& !element.is_bool(self.db)
|
|
||||||
&& (!element.is_enum(self.db) || element.overrides_equality(self.db))
|
|
||||||
{
|
{
|
||||||
builder = builder.add(*element);
|
builder = builder.add(*element);
|
||||||
}
|
}
|
||||||
|
|
@ -650,9 +648,7 @@ impl<'db, 'ast> NarrowingConstraintsBuilder<'db, 'ast> {
|
||||||
if let Some(lhs_union) = lhs_ty.as_union() {
|
if let Some(lhs_union) = lhs_ty.as_union() {
|
||||||
for element in lhs_union.elements(self.db) {
|
for element in lhs_union.elements(self.db) {
|
||||||
if element.is_single_valued(self.db)
|
if element.is_single_valued(self.db)
|
||||||
|| element.is_literal_string()
|
|| element.is_union_of_single_valued(self.db)
|
||||||
|| element.is_bool(self.db)
|
|
||||||
|| (element.is_enum(self.db) && !element.overrides_equality(self.db))
|
|
||||||
{
|
{
|
||||||
single_builder = single_builder.add(*element);
|
single_builder = single_builder.add(*element);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue