[red-knot] Restrict visibility of more things in `class.rs` (#16346)

This commit is contained in:
Alex Waygood 2025-02-24 14:30:56 +00:00 committed by GitHub
parent 68991d09a8
commit 7059f4249b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 28 deletions

View File

@ -33,7 +33,7 @@ use super::{
pub struct Class<'db> { pub struct Class<'db> {
/// Name of the class at definition /// Name of the class at definition
#[return_ref] #[return_ref]
pub name: ast::name::Name, pub(crate) name: ast::name::Name,
body_scope: ScopeId<'db>, body_scope: ScopeId<'db>,
@ -43,12 +43,12 @@ pub struct Class<'db> {
#[salsa::tracked] #[salsa::tracked]
impl<'db> Class<'db> { impl<'db> Class<'db> {
/// Return `true` if this class represents `known_class` /// Return `true` if this class represents `known_class`
pub fn is_known(self, db: &'db dyn Db, known_class: KnownClass) -> bool { pub(crate) fn is_known(self, db: &'db dyn Db, known_class: KnownClass) -> bool {
self.known(db) == Some(known_class) self.known(db) == Some(known_class)
} }
/// Return `true` if this class represents the builtin class `object` /// Return `true` if this class represents the builtin class `object`
pub fn is_object(self, db: &'db dyn Db) -> bool { pub(crate) fn is_object(self, db: &'db dyn Db) -> bool {
self.is_known(db, KnownClass::Object) self.is_known(db, KnownClass::Object)
} }
@ -156,7 +156,7 @@ impl<'db> Class<'db> {
} }
/// Return `true` if `other` is present in this class's MRO. /// Return `true` if `other` is present in this class's MRO.
pub fn is_subclass_of(self, db: &'db dyn Db, other: Class) -> bool { pub(super) fn is_subclass_of(self, db: &'db dyn Db, other: Class) -> bool {
// `is_subclass_of` is checking the subtype relation, in which gradual types do not // `is_subclass_of` is checking the subtype relation, in which gradual types do not
// participate, so we should not return `True` if we find `Any/Unknown` in the MRO. // participate, so we should not return `True` if we find `Any/Unknown` in the MRO.
self.iter_mro(db).contains(&ClassBase::Class(other)) self.iter_mro(db).contains(&ClassBase::Class(other))
@ -180,14 +180,14 @@ impl<'db> Class<'db> {
} }
/// Return the metaclass of this class, or `type[Unknown]` if the metaclass cannot be inferred. /// Return the metaclass of this class, or `type[Unknown]` if the metaclass cannot be inferred.
pub(crate) fn metaclass(self, db: &'db dyn Db) -> Type<'db> { pub(super) fn metaclass(self, db: &'db dyn Db) -> Type<'db> {
self.try_metaclass(db) self.try_metaclass(db)
.unwrap_or_else(|_| SubclassOfType::subclass_of_unknown()) .unwrap_or_else(|_| SubclassOfType::subclass_of_unknown())
} }
/// Return the metaclass of this class, or an error if the metaclass cannot be inferred. /// Return the metaclass of this class, or an error if the metaclass cannot be inferred.
#[salsa::tracked] #[salsa::tracked]
pub(crate) fn try_metaclass(self, db: &'db dyn Db) -> Result<Type<'db>, MetaclassError<'db>> { pub(super) fn try_metaclass(self, db: &'db dyn Db) -> Result<Type<'db>, MetaclassError<'db>> {
// Identify the class's own metaclass (or take the first base class's metaclass). // Identify the class's own metaclass (or take the first base class's metaclass).
let mut base_classes = self.fully_static_explicit_bases(db).peekable(); let mut base_classes = self.fully_static_explicit_bases(db).peekable();
@ -316,7 +316,9 @@ impl<'db> Class<'db> {
/// Returns the class member of this class named `name`. /// Returns the class member of this class named `name`.
/// ///
/// The member resolves to a member on the class itself or any of its proper superclasses. /// The member resolves to a member on the class itself or any of its proper superclasses.
pub(crate) fn class_member(self, db: &'db dyn Db, name: &str) -> Symbol<'db> { ///
/// TODO: Should this be made private...?
pub(super) fn class_member(self, db: &'db dyn Db, name: &str) -> Symbol<'db> {
if name == "__mro__" { if name == "__mro__" {
let tuple_elements = self.iter_mro(db).map(Type::from); let tuple_elements = self.iter_mro(db).map(Type::from);
return Symbol::bound(TupleType::from_elements(db, tuple_elements)); return Symbol::bound(TupleType::from_elements(db, tuple_elements));
@ -369,7 +371,7 @@ impl<'db> Class<'db> {
/// Returns [`Symbol::Unbound`] if `name` cannot be found in this class's scope /// Returns [`Symbol::Unbound`] if `name` cannot be found in this class's scope
/// directly. Use [`Class::class_member`] if you require a method that will /// directly. Use [`Class::class_member`] if you require a method that will
/// traverse through the MRO until it finds the member. /// traverse through the MRO until it finds the member.
pub(crate) fn own_class_member(self, db: &'db dyn Db, name: &str) -> Symbol<'db> { pub(super) fn own_class_member(self, db: &'db dyn Db, name: &str) -> Symbol<'db> {
let body_scope = self.body_scope(db); let body_scope = self.body_scope(db);
class_symbol(db, body_scope, name) class_symbol(db, body_scope, name)
} }
@ -380,7 +382,7 @@ impl<'db> Class<'db> {
/// defined attribute that is only present in a method (typically `__init__`). /// defined attribute that is only present in a method (typically `__init__`).
/// ///
/// The attribute might also be defined in a superclass of this class. /// The attribute might also be defined in a superclass of this class.
pub(crate) fn instance_member(self, db: &'db dyn Db, name: &str) -> SymbolAndQualifiers<'db> { pub(super) fn instance_member(self, db: &'db dyn Db, name: &str) -> SymbolAndQualifiers<'db> {
for superclass in self.iter_mro(db) { for superclass in self.iter_mro(db) {
match superclass { match superclass {
ClassBase::Dynamic(_) => { ClassBase::Dynamic(_) => {
@ -611,7 +613,7 @@ pub(super) enum InheritanceCycle {
} }
impl InheritanceCycle { impl InheritanceCycle {
pub(crate) const fn is_participant(self) -> bool { pub(super) const fn is_participant(self) -> bool {
matches!(self, InheritanceCycle::Participant) matches!(self, InheritanceCycle::Participant)
} }
} }
@ -649,7 +651,7 @@ pub struct InstanceType<'db> {
} }
impl<'db> InstanceType<'db> { impl<'db> InstanceType<'db> {
pub(crate) fn class(self) -> Class<'db> { pub(super) fn class(self) -> Class<'db> {
self.class self.class
} }
@ -727,13 +729,13 @@ pub enum KnownClass {
} }
impl<'db> KnownClass { impl<'db> KnownClass {
pub const fn is_bool(self) -> bool { pub(crate) const fn is_bool(self) -> bool {
matches!(self, Self::Bool) matches!(self, Self::Bool)
} }
/// Determine whether instances of this class are always truthy, always falsy, /// Determine whether instances of this class are always truthy, always falsy,
/// or have an ambiguous truthiness. /// or have an ambiguous truthiness.
pub(super) const fn bool(self) -> Truthiness { pub(crate) const fn bool(self) -> Truthiness {
match self { match self {
// N.B. It's only generally safe to infer `Truthiness::AlwaysTrue` for a `KnownClass` // N.B. It's only generally safe to infer `Truthiness::AlwaysTrue` for a `KnownClass`
// variant if the class's `__bool__` method always returns the same thing *and* the // variant if the class's `__bool__` method always returns the same thing *and* the
@ -785,7 +787,7 @@ impl<'db> KnownClass {
} }
} }
pub fn as_str(self, db: &'db dyn Db) -> &'static str { pub(crate) fn as_str(self, db: &'db dyn Db) -> &'static str {
match self { match self {
Self::Bool => "bool", Self::Bool => "bool",
Self::Object => "object", Self::Object => "object",
@ -843,17 +845,17 @@ impl<'db> KnownClass {
} }
} }
pub fn to_instance(self, db: &'db dyn Db) -> Type<'db> { pub(crate) fn to_instance(self, db: &'db dyn Db) -> Type<'db> {
self.to_class_literal(db).to_instance(db) self.to_class_literal(db).to_instance(db)
} }
pub fn to_class_literal(self, db: &'db dyn Db) -> Type<'db> { pub(crate) fn to_class_literal(self, db: &'db dyn Db) -> Type<'db> {
known_module_symbol(db, self.canonical_module(db), self.as_str(db)) known_module_symbol(db, self.canonical_module(db), self.as_str(db))
.ignore_possibly_unbound() .ignore_possibly_unbound()
.unwrap_or(Type::unknown()) .unwrap_or(Type::unknown())
} }
pub fn to_subclass_of(self, db: &'db dyn Db) -> Type<'db> { pub(crate) fn to_subclass_of(self, db: &'db dyn Db) -> Type<'db> {
self.to_class_literal(db) self.to_class_literal(db)
.into_class_literal() .into_class_literal()
.map(|ClassLiteralType { class }| SubclassOfType::from(db, class)) .map(|ClassLiteralType { class }| SubclassOfType::from(db, class))
@ -862,7 +864,7 @@ impl<'db> KnownClass {
/// Return `true` if this symbol can be resolved to a class definition `class` in typeshed, /// Return `true` if this symbol can be resolved to a class definition `class` in typeshed,
/// *and* `class` is a subclass of `other`. /// *and* `class` is a subclass of `other`.
pub fn is_subclass_of(self, db: &'db dyn Db, other: Class<'db>) -> bool { pub(super) fn is_subclass_of(self, db: &'db dyn Db, other: Class<'db>) -> bool {
known_module_symbol(db, self.canonical_module(db), self.as_str(db)) known_module_symbol(db, self.canonical_module(db), self.as_str(db))
.ignore_possibly_unbound() .ignore_possibly_unbound()
.and_then(Type::into_class_literal) .and_then(Type::into_class_literal)
@ -870,7 +872,7 @@ impl<'db> KnownClass {
} }
/// Return the module in which we should look up the definition for this class /// Return the module in which we should look up the definition for this class
pub(crate) fn canonical_module(self, db: &'db dyn Db) -> KnownModule { fn canonical_module(self, db: &'db dyn Db) -> KnownModule {
match self { match self {
Self::Bool Self::Bool
| Self::Object | Self::Object
@ -1348,16 +1350,16 @@ impl<'db> KnownInstanceType<'db> {
/// For example, the symbol `typing.Literal` is an instance of `typing._SpecialForm`, /// For example, the symbol `typing.Literal` is an instance of `typing._SpecialForm`,
/// so `KnownInstanceType::Literal.instance_fallback(db)` /// so `KnownInstanceType::Literal.instance_fallback(db)`
/// returns `Type::Instance(InstanceType { class: <typing._SpecialForm> })`. /// returns `Type::Instance(InstanceType { class: <typing._SpecialForm> })`.
pub(crate) fn instance_fallback(self, db: &dyn Db) -> Type { pub(super) fn instance_fallback(self, db: &dyn Db) -> Type {
self.class().to_instance(db) self.class().to_instance(db)
} }
/// Return `true` if this symbol is an instance of `class`. /// Return `true` if this symbol is an instance of `class`.
pub(crate) fn is_instance_of(self, db: &'db dyn Db, class: Class<'db>) -> bool { pub(super) fn is_instance_of(self, db: &'db dyn Db, class: Class<'db>) -> bool {
self.class().is_subclass_of(db, class) self.class().is_subclass_of(db, class)
} }
pub(crate) fn try_from_file_and_name( pub(super) fn try_from_file_and_name(
db: &'db dyn Db, db: &'db dyn Db,
file: File, file: File,
symbol_name: &str, symbol_name: &str,
@ -1412,7 +1414,7 @@ impl<'db> KnownInstanceType<'db> {
/// ///
/// Most variants can only exist in one module, which is the same as `self.class().canonical_module()`. /// Most variants can only exist in one module, which is the same as `self.class().canonical_module()`.
/// Some variants could validly be defined in either `typing` or `typing_extensions`, however. /// Some variants could validly be defined in either `typing` or `typing_extensions`, however.
pub(crate) fn check_module(self, module: KnownModule) -> bool { fn check_module(self, module: KnownModule) -> bool {
match self { match self {
Self::Any Self::Any
| Self::ClassVar | Self::ClassVar

View File

@ -8,28 +8,28 @@ use itertools::Either;
/// all types that would be invalid to have as a class base are /// all types that would be invalid to have as a class base are
/// transformed into [`ClassBase::unknown`] /// transformed into [`ClassBase::unknown`]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, salsa::Update)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, salsa::Update)]
pub enum ClassBase<'db> { pub(crate) enum ClassBase<'db> {
Dynamic(DynamicType), Dynamic(DynamicType),
Class(Class<'db>), Class(Class<'db>),
} }
impl<'db> ClassBase<'db> { impl<'db> ClassBase<'db> {
pub const fn any() -> Self { pub(crate) const fn any() -> Self {
Self::Dynamic(DynamicType::Any) Self::Dynamic(DynamicType::Any)
} }
pub const fn unknown() -> Self { pub(crate) const fn unknown() -> Self {
Self::Dynamic(DynamicType::Unknown) Self::Dynamic(DynamicType::Unknown)
} }
pub const fn is_dynamic(self) -> bool { pub(crate) const fn is_dynamic(self) -> bool {
match self { match self {
ClassBase::Dynamic(_) => true, ClassBase::Dynamic(_) => true,
ClassBase::Class(_) => false, ClassBase::Class(_) => false,
} }
} }
pub fn display(self, db: &'db dyn Db) -> impl std::fmt::Display + 'db { pub(crate) fn display(self, db: &'db dyn Db) -> impl std::fmt::Display + 'db {
struct Display<'db> { struct Display<'db> {
base: ClassBase<'db>, base: ClassBase<'db>,
db: &'db dyn Db, db: &'db dyn Db,