From 989075dc16fecd87f874d485ddc77952dc78bbde Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Tue, 11 Mar 2025 16:12:44 +0000 Subject: [PATCH] [red-knot] Add tests asserting that `KnownClass::to_instance()` doesn't unexpectedly fallback to `Type::Unknown` with full typeshed stubs (#16608) ## Summary One of the motivations in https://github.com/astral-sh/ruff/pull/16428 for panicking when the `test` or `debug_assertions` features are enabled and a lookup of a `KnownClass` fails is that we've had some latent bugs in our code where certain variants have been silently falling back to `Unknown` in every typeshed lookup without us realising. But that in itself isn't a great motivation for panicking in `KnownClass::to_instance()`, since we can fairly easily add some tests that assert that we don't unexpectedly fallback to `Unknown` for any `KnownClass` variant. This PR adds those tests. ## Test Plan `cargo test -p red_knot_python_semantic` --- .../src/types/class.rs | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/crates/red_knot_python_semantic/src/types/class.rs b/crates/red_knot_python_semantic/src/types/class.rs index 04854b7c2e..a39dd92d9d 100644 --- a/crates/red_knot_python_semantic/src/types/class.rs +++ b/crates/red_knot_python_semantic/src/types/class.rs @@ -995,11 +995,10 @@ impl<'db> KnownClass { | Self::MethodWrapperType | Self::WrapperDescriptorType => KnownModule::Types, Self::NoneType => KnownModule::Typeshed, - Self::SpecialForm - | Self::TypeVar - | Self::TypeAliasType - | Self::StdlibAlias - | Self::SupportsIndex => KnownModule::Typing, + Self::SpecialForm | Self::TypeVar | Self::StdlibAlias | Self::SupportsIndex => { + KnownModule::Typing + } + Self::TypeAliasType => KnownModule::TypingExtensions, Self::NoDefaultType => { let python_version = Program::get(db).python_version(db); @@ -1603,6 +1602,7 @@ mod tests { use super::*; use crate::db::tests::setup_db; use crate::module_resolver::resolve_module; + use salsa::Setter; use strum::IntoEnumIterator; #[test] @@ -1619,4 +1619,44 @@ mod tests { ); } } + + #[test] + fn known_class_doesnt_fallback_to_unknown_unexpectedly_on_latest_version() { + let mut db = setup_db(); + + Program::get(&db) + .set_python_version(&mut db) + .to(PythonVersion::latest()); + + for class in KnownClass::iter() { + assert_ne!( + class.to_instance(&db), + Type::unknown(), + "Unexpectedly fell back to `Unknown` for `{class:?}`" + ); + } + } + + #[test] + fn known_class_doesnt_fallback_to_unknown_unexpectedly_on_low_python_version() { + let mut db = setup_db(); + + for class in KnownClass::iter() { + let version_added = match class { + KnownClass::BaseExceptionGroup => PythonVersion::PY311, + KnownClass::GenericAlias => PythonVersion::PY39, + _ => PythonVersion::PY37, + }; + + Program::get(&db) + .set_python_version(&mut db) + .to(version_added); + + assert_ne!( + class.to_instance(&db), + Type::unknown(), + "Unexpectedly fell back to `Unknown` for `{class:?}` on Python {version_added}" + ); + } + } }