mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:25:17 +00:00
[red-knot] follow-ups to typevar types (#14232)
This commit is contained in:
parent
c7d48e10e6
commit
a7e9f0c4b9
2 changed files with 30 additions and 22 deletions
|
@ -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();
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue