mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:21 +00:00
[red-knot] fix class vs instance (#11175)
## Summary Clarify the type of an exact class object vs the type of instances of that class. ## Test Plan cargo test
This commit is contained in:
parent
2490d2d4af
commit
2d6978f236
2 changed files with 17 additions and 9 deletions
|
@ -22,10 +22,12 @@ pub enum Type {
|
||||||
Unknown,
|
Unknown,
|
||||||
/// name is not bound to any value
|
/// name is not bound to any value
|
||||||
Unbound,
|
Unbound,
|
||||||
/// a specific function
|
/// a specific function object
|
||||||
Function(FunctionTypeId),
|
Function(FunctionTypeId),
|
||||||
/// the set of Python objects with a given class in their __class__'s method resolution order
|
/// a specific class object
|
||||||
Class(ClassTypeId),
|
Class(ClassTypeId),
|
||||||
|
/// the set of Python objects with the given class in their __class__'s method resolution order
|
||||||
|
Instance(ClassTypeId),
|
||||||
Union(UnionTypeId),
|
Union(UnionTypeId),
|
||||||
Intersection(IntersectionTypeId),
|
Intersection(IntersectionTypeId),
|
||||||
// TODO protocols, callable types, overloads, generics, type vars
|
// TODO protocols, callable types, overloads, generics, type vars
|
||||||
|
@ -349,7 +351,13 @@ impl std::fmt::Display for DisplayType<'_> {
|
||||||
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::Unbound => f.write_str("Unbound"),
|
Type::Unbound => f.write_str("Unbound"),
|
||||||
Type::Class(class_id) => f.write_str(self.store.get_class(*class_id).name()),
|
// TODO functions and classes should display using a fully qualified name
|
||||||
|
Type::Class(class_id) => {
|
||||||
|
f.write_str("Literal[")?;
|
||||||
|
f.write_str(self.store.get_class(*class_id).name())?;
|
||||||
|
f.write_str("]")
|
||||||
|
}
|
||||||
|
Type::Instance(class_id) => f.write_str(self.store.get_class(*class_id).name()),
|
||||||
Type::Function(func_id) => f.write_str(self.store.get_function(*func_id).name()),
|
Type::Function(func_id) => f.write_str(self.store.get_function(*func_id).name()),
|
||||||
Type::Union(union_id) => self
|
Type::Union(union_id) => self
|
||||||
.store
|
.store
|
||||||
|
@ -459,8 +467,8 @@ mod tests {
|
||||||
let file_id = files.intern(Path::new("/foo"));
|
let file_id = files.intern(Path::new("/foo"));
|
||||||
let id = store.add_class(file_id, "C");
|
let id = store.add_class(file_id, "C");
|
||||||
assert_eq!(store.get_class(id).name(), "C");
|
assert_eq!(store.get_class(id).name(), "C");
|
||||||
let class = Type::Class(id);
|
let inst = Type::Instance(id);
|
||||||
assert_eq!(format!("{}", class.display(&store)), "C");
|
assert_eq!(format!("{}", inst.display(&store)), "C");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -481,7 +489,7 @@ mod tests {
|
||||||
let file_id = files.intern(Path::new("/foo"));
|
let file_id = files.intern(Path::new("/foo"));
|
||||||
let c1 = store.add_class(file_id, "C1");
|
let c1 = store.add_class(file_id, "C1");
|
||||||
let c2 = store.add_class(file_id, "C2");
|
let c2 = store.add_class(file_id, "C2");
|
||||||
let elems = vec![Type::Class(c1), Type::Class(c2)];
|
let elems = vec![Type::Instance(c1), Type::Instance(c2)];
|
||||||
let id = store.add_union(file_id, &elems);
|
let id = store.add_union(file_id, &elems);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
store.get_union(id).elements,
|
store.get_union(id).elements,
|
||||||
|
@ -499,8 +507,8 @@ mod tests {
|
||||||
let c1 = store.add_class(file_id, "C1");
|
let c1 = store.add_class(file_id, "C1");
|
||||||
let c2 = store.add_class(file_id, "C2");
|
let c2 = store.add_class(file_id, "C2");
|
||||||
let c3 = store.add_class(file_id, "C3");
|
let c3 = store.add_class(file_id, "C3");
|
||||||
let pos = vec![Type::Class(c1), Type::Class(c2)];
|
let pos = vec![Type::Instance(c1), Type::Instance(c2)];
|
||||||
let neg = vec![Type::Class(c3)];
|
let neg = vec![Type::Instance(c3)];
|
||||||
let id = store.add_intersection(file_id, &pos, &neg);
|
let id = store.add_intersection(file_id, &pos, &neg);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
store.get_intersection(id).positive,
|
store.get_intersection(id).positive,
|
||||||
|
|
|
@ -135,7 +135,7 @@ mod tests {
|
||||||
let jar = HasJar::<SemanticJar>::jar(&db);
|
let jar = HasJar::<SemanticJar>::jar(&db);
|
||||||
|
|
||||||
assert!(matches!(ty, Type::Class(_)));
|
assert!(matches!(ty, Type::Class(_)));
|
||||||
assert_eq!(format!("{}", ty.display(&jar.type_store)), "C");
|
assert_eq!(format!("{}", ty.display(&jar.type_store)), "Literal[C]");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue