mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 18:28:24 +00:00
[red-knot] ClassLiteral(<T>)
is not a disjoint type from Instance(<metaclass of T>)
(#14970)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
## Summary A class is an instance of its metaclass, so `ClassLiteral("ABC")` is not disjoint from `Instance("ABCMeta")`. However, we erroneously consider the two types disjoint on the `main` branch. This PR fixes that. This bug was uncovered by adding some more core types to the property tests that provide coverage for classes that have custom metaclasses. The additions to the property tests are included in this PR. ## Test Plan New unit tests and property tests added. Tested with: - `cargo test -p red_knot_python_semantic` - `QUICKCHECK_TESTS=100000 cargo test -p red_knot_python_semantic -- --ignored types::property_tests::stable` The assignability property test fails on this branch, but that's a known issue that exists on `main`, due to https://github.com/astral-sh/ruff/issues/14899.
This commit is contained in:
parent
ac31b26a0e
commit
4d64cdb83c
2 changed files with 24 additions and 4 deletions
|
@ -1157,10 +1157,15 @@ impl<'db> Type<'db> {
|
|||
Some(KnownClass::Slice | KnownClass::Object)
|
||||
),
|
||||
|
||||
(Type::ClassLiteral(..), Type::Instance(InstanceType { class }))
|
||||
| (Type::Instance(InstanceType { class }), Type::ClassLiteral(..)) => {
|
||||
!matches!(class.known(db), Some(KnownClass::Type | KnownClass::Object))
|
||||
}
|
||||
(
|
||||
Type::ClassLiteral(ClassLiteralType { class: class_a }),
|
||||
Type::Instance(InstanceType { class: class_b }),
|
||||
)
|
||||
| (
|
||||
Type::Instance(InstanceType { class: class_b }),
|
||||
Type::ClassLiteral(ClassLiteralType { class: class_a }),
|
||||
) => !class_a.is_instance_of(db, class_b),
|
||||
|
||||
(Type::FunctionLiteral(..), Type::Instance(InstanceType { class }))
|
||||
| (Type::Instance(InstanceType { class }), Type::FunctionLiteral(..)) => !matches!(
|
||||
class.known(db),
|
||||
|
@ -3352,6 +3357,7 @@ pub(crate) mod tests {
|
|||
Tuple(Vec<Ty>),
|
||||
SubclassOfAny,
|
||||
SubclassOfBuiltinClass(&'static str),
|
||||
SubclassOfAbcClass(&'static str),
|
||||
StdlibModule(CoreStdlibModule),
|
||||
SliceLiteral(i32, i32, i32),
|
||||
}
|
||||
|
@ -3404,6 +3410,12 @@ pub(crate) mod tests {
|
|||
.expect_class_literal()
|
||||
.class,
|
||||
),
|
||||
Ty::SubclassOfAbcClass(s) => Type::subclass_of(
|
||||
core_module_symbol(db, CoreStdlibModule::Abc, s)
|
||||
.expect_type()
|
||||
.expect_class_literal()
|
||||
.class,
|
||||
),
|
||||
Ty::StdlibModule(module) => {
|
||||
Type::ModuleLiteral(resolve_module(db, &module.name()).unwrap().file())
|
||||
}
|
||||
|
@ -3744,6 +3756,7 @@ pub(crate) mod tests {
|
|||
#[test_case(Ty::Tuple(vec![Ty::IntLiteral(1), Ty::IntLiteral(2)]), Ty::Tuple(vec![Ty::IntLiteral(1), Ty::BuiltinInstance("int")]))]
|
||||
#[test_case(Ty::BuiltinClassLiteral("str"), Ty::BuiltinInstance("type"))]
|
||||
#[test_case(Ty::BuiltinClassLiteral("str"), Ty::SubclassOfAny)]
|
||||
#[test_case(Ty::AbcClassLiteral("ABC"), Ty::AbcInstance("ABCMeta"))]
|
||||
fn is_not_disjoint_from(a: Ty, b: Ty) {
|
||||
let db = setup_db();
|
||||
let a = a.into_type(&db);
|
||||
|
|
|
@ -65,9 +65,16 @@ fn arbitrary_core_type(g: &mut Gen) -> Ty {
|
|||
Ty::BuiltinClassLiteral("bool"),
|
||||
Ty::BuiltinClassLiteral("object"),
|
||||
Ty::BuiltinInstance("type"),
|
||||
Ty::AbcInstance("ABC"),
|
||||
Ty::AbcInstance("ABCMeta"),
|
||||
Ty::SubclassOfAny,
|
||||
Ty::SubclassOfBuiltinClass("object"),
|
||||
Ty::SubclassOfBuiltinClass("str"),
|
||||
Ty::SubclassOfBuiltinClass("type"),
|
||||
Ty::AbcClassLiteral("ABC"),
|
||||
Ty::AbcClassLiteral("ABCMeta"),
|
||||
Ty::SubclassOfAbcClass("ABC"),
|
||||
Ty::SubclassOfAbcClass("ABCMeta"),
|
||||
])
|
||||
.unwrap()
|
||||
.clone()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue