[red-knot] follow-ups to typevar types (#14232)

This commit is contained in:
Carl Meyer 2024-11-09 20:18:32 -08:00 committed by GitHub
parent c7d48e10e6
commit a7e9f0c4b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 22 deletions

View file

@ -690,13 +690,11 @@ impl<'db> Type<'db> {
Type::Instance(InstanceType { class: self_class }), Type::Instance(InstanceType { class: self_class }),
Type::Instance(InstanceType { class: target_class }) Type::Instance(InstanceType { class: target_class })
) )
if ( if {
self_class.is_known(db, KnownClass::NoneType) && let self_known = self_class.known(db);
target_class.is_known(db, KnownClass::NoneType) matches!(self_known, Some(KnownClass::NoneType | KnownClass::NoDefaultType))
) || ( && self_known == target_class.known(db)
self_class.is_known(db, KnownClass::NoDefaultType) && }
target_class.is_known(db, KnownClass::NoDefaultType)
)
) )
} }
@ -937,11 +935,7 @@ impl<'db> Type<'db> {
| Type::ModuleLiteral(..) | Type::ModuleLiteral(..)
| Type::KnownInstance(..) => true, | Type::KnownInstance(..) => true,
Type::Instance(InstanceType { class }) => { Type::Instance(InstanceType { class }) => {
if let Some(known_class) = class.known(db) { class.known(db).is_some_and(KnownClass::is_singleton)
known_class.is_singleton()
} else {
false
}
} }
Type::Tuple(..) => { Type::Tuple(..) => {
// The empty tuple is a singleton on CPython and PyPy, but not on other Python // The empty tuple is a singleton on CPython and PyPy, but not on other Python
@ -1595,6 +1589,9 @@ impl<'db> KnownClass {
Self::NoneType => typeshed_symbol(db, self.as_str()).unwrap_or_unknown(), Self::NoneType => typeshed_symbol(db, self.as_str()).unwrap_or_unknown(),
Self::SpecialForm => typing_symbol(db, self.as_str()).unwrap_or_unknown(), Self::SpecialForm => typing_symbol(db, self.as_str()).unwrap_or_unknown(),
Self::TypeVar => typing_symbol(db, self.as_str()).unwrap_or_unknown(), Self::TypeVar => typing_symbol(db, self.as_str()).unwrap_or_unknown(),
// TODO when we understand sys.version_info, we will need an explicit fallback here,
// because typing_extensions has a 3.13+ re-export for the `typing.NoDefault`
// singleton, but not for `typing._NoDefaultType`
Self::NoDefaultType => typing_extensions_symbol(db, self.as_str()).unwrap_or_unknown(), Self::NoDefaultType => typing_extensions_symbol(db, self.as_str()).unwrap_or_unknown(),
} }
} }
@ -3324,6 +3321,20 @@ mod tests {
assert_eq!(ty.into_type(&db).repr(&db), expected.into_type(&db)); assert_eq!(ty.into_type(&db).repr(&db), expected.into_type(&db));
} }
#[test]
fn typing_vs_typeshed_no_default() {
let db = setup_db();
let typing_no_default = typing_symbol(&db, "NoDefault").expect_type();
let typing_extensions_no_default = typing_extensions_symbol(&db, "NoDefault").expect_type();
assert_eq!(typing_no_default.display(&db).to_string(), "NoDefault");
assert_eq!(
typing_extensions_no_default.display(&db).to_string(),
"NoDefault"
);
}
#[test] #[test]
fn module_type_symbols_includes_declared_types_but_not_referenced_types() { fn module_type_symbols_includes_declared_types_but_not_referenced_types() {
let db = setup_db(); let db = setup_db();

View file

@ -66,15 +66,13 @@ impl Display for DisplayRepresentation<'_> {
Type::Any => f.write_str("Any"), Type::Any => f.write_str("Any"),
Type::Never => f.write_str("Never"), Type::Never => f.write_str("Never"),
Type::Unknown => f.write_str("Unknown"), Type::Unknown => f.write_str("Unknown"),
Type::Instance(InstanceType { class }) Type::Instance(InstanceType { class }) => {
if class.is_known(self.db, KnownClass::NoneType) => let representation = match class.known(self.db) {
{ Some(KnownClass::NoneType) => "None",
f.write_str("None") Some(KnownClass::NoDefaultType) => "NoDefault",
} _ => class.name(self.db),
Type::Instance(InstanceType { class }) };
if class.is_known(self.db, KnownClass::NoDefaultType) => f.write_str(representation)
{
f.write_str("NoDefault")
} }
// `[Type::Todo]`'s display should be explicit that is not a valid display of // `[Type::Todo]`'s display should be explicit that is not a valid display of
// any other type // any other type
@ -87,7 +85,6 @@ impl Display for DisplayRepresentation<'_> {
Type::SubclassOf(SubclassOfType { class }) => { Type::SubclassOf(SubclassOfType { class }) => {
write!(f, "type[{}]", class.name(self.db)) write!(f, "type[{}]", class.name(self.db))
} }
Type::Instance(InstanceType { class }) => f.write_str(class.name(self.db)),
Type::KnownInstance(known_instance) => f.write_str(known_instance.as_str()), Type::KnownInstance(known_instance) => f.write_str(known_instance.as_str()),
Type::FunctionLiteral(function) => f.write_str(function.name(self.db)), Type::FunctionLiteral(function) => f.write_str(function.name(self.db)),
Type::Union(union) => union.display(self.db).fmt(f), Type::Union(union) => union.display(self.db).fmt(f),