From 912247635d302c02eb7a6174f104a3c5cada1a48 Mon Sep 17 00:00:00 2001 From: David Peter Date: Mon, 20 Jan 2025 10:15:31 +0100 Subject: [PATCH] [red-knot] Move `Ty` enum to property tests (#15608) ## Summary Move the `Ty` enum into the `property_tests` module, as it was only used in a single place in `types.rs`. --- crates/red_knot_python_semantic/src/types.rs | 99 +---------------- .../src/types/property_tests.rs | 102 +++++++++++++++++- 2 files changed, 101 insertions(+), 100 deletions(-) diff --git a/crates/red_knot_python_semantic/src/types.rs b/crates/red_knot_python_semantic/src/types.rs index ea6d8ace17..49747b1056 100644 --- a/crates/red_knot_python_semantic/src/types.rs +++ b/crates/red_knot_python_semantic/src/types.rs @@ -4574,7 +4574,7 @@ static_assertions::assert_eq_size!(Type, [u8; 16]); #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::db::tests::{setup_db, TestDb, TestDbBuilder}; + use crate::db::tests::{setup_db, TestDbBuilder}; use crate::stdlib::typing_symbol; use crate::PythonVersion; use ruff_db::files::system_path_to_file; @@ -4584,101 +4584,6 @@ pub(crate) mod tests { use ruff_python_ast as ast; use test_case::test_case; - /// A test representation of a type that can be transformed unambiguously into a real Type, - /// given a db. - #[derive(Debug, Clone, PartialEq)] - pub(crate) enum Ty { - Never, - Unknown, - None, - Any, - IntLiteral(i64), - BooleanLiteral(bool), - StringLiteral(&'static str), - LiteralString, - BytesLiteral(&'static str), - // BuiltinInstance("str") corresponds to an instance of the builtin `str` class - BuiltinInstance(&'static str), - /// Members of the `abc` stdlib module - AbcInstance(&'static str), - AbcClassLiteral(&'static str), - TypingLiteral, - // BuiltinClassLiteral("str") corresponds to the builtin `str` class object itself - BuiltinClassLiteral(&'static str), - KnownClassInstance(KnownClass), - Union(Vec), - Intersection { - pos: Vec, - neg: Vec, - }, - Tuple(Vec), - SubclassOfAny, - SubclassOfBuiltinClass(&'static str), - SubclassOfAbcClass(&'static str), - AlwaysTruthy, - AlwaysFalsy, - } - - impl Ty { - pub(crate) fn into_type(self, db: &TestDb) -> Type<'_> { - match self { - Ty::Never => Type::Never, - Ty::Unknown => Type::unknown(), - Ty::None => Type::none(db), - Ty::Any => Type::any(), - Ty::IntLiteral(n) => Type::IntLiteral(n), - Ty::StringLiteral(s) => Type::string_literal(db, s), - Ty::BooleanLiteral(b) => Type::BooleanLiteral(b), - Ty::LiteralString => Type::LiteralString, - Ty::BytesLiteral(s) => Type::bytes_literal(db, s.as_bytes()), - Ty::BuiltinInstance(s) => builtins_symbol(db, s).expect_type().to_instance(db), - Ty::AbcInstance(s) => known_module_symbol(db, KnownModule::Abc, s) - .expect_type() - .to_instance(db), - Ty::AbcClassLiteral(s) => { - known_module_symbol(db, KnownModule::Abc, s).expect_type() - } - Ty::TypingLiteral => Type::KnownInstance(KnownInstanceType::Literal), - Ty::BuiltinClassLiteral(s) => builtins_symbol(db, s).expect_type(), - Ty::KnownClassInstance(known_class) => known_class.to_instance(db), - Ty::Union(tys) => { - UnionType::from_elements(db, tys.into_iter().map(|ty| ty.into_type(db))) - } - Ty::Intersection { pos, neg } => { - let mut builder = IntersectionBuilder::new(db); - for p in pos { - builder = builder.add_positive(p.into_type(db)); - } - for n in neg { - builder = builder.add_negative(n.into_type(db)); - } - builder.build() - } - Ty::Tuple(tys) => { - let elements = tys.into_iter().map(|ty| ty.into_type(db)); - TupleType::from_elements(db, elements) - } - Ty::SubclassOfAny => SubclassOfType::subclass_of_any(), - Ty::SubclassOfBuiltinClass(s) => SubclassOfType::from( - db, - builtins_symbol(db, s) - .expect_type() - .expect_class_literal() - .class, - ), - Ty::SubclassOfAbcClass(s) => SubclassOfType::from( - db, - known_module_symbol(db, KnownModule::Abc, s) - .expect_type() - .expect_class_literal() - .class, - ), - Ty::AlwaysTruthy => Type::AlwaysTruthy, - Ty::AlwaysFalsy => Type::AlwaysFalsy, - } - } - } - /// Explicitly test for Python version <3.13 and >=3.13, to ensure that /// the fallback to `typing_extensions` is working correctly. /// See [`KnownClass::canonical_module`] for more information. @@ -4690,7 +4595,7 @@ pub(crate) mod tests { .build() .unwrap(); - let no_default = Ty::KnownClassInstance(KnownClass::NoDefaultType).into_type(&db); + let no_default = KnownClass::NoDefaultType.to_instance(&db); assert!(no_default.is_singleton(&db)); } diff --git a/crates/red_knot_python_semantic/src/types/property_tests.rs b/crates/red_knot_python_semantic/src/types/property_tests.rs index c6f3b3a203..4fabc499ba 100644 --- a/crates/red_knot_python_semantic/src/types/property_tests.rs +++ b/crates/red_knot_python_semantic/src/types/property_tests.rs @@ -26,11 +26,107 @@ use std::sync::{Arc, Mutex, MutexGuard, OnceLock}; -use super::tests::Ty; use crate::db::tests::{setup_db, TestDb}; -use crate::types::{IntersectionBuilder, KnownClass, Type, UnionType}; +use crate::types::{ + builtins_symbol, known_module_symbol, IntersectionBuilder, KnownClass, KnownInstanceType, + SubclassOfType, TupleType, Type, UnionType, +}; +use crate::KnownModule; use quickcheck::{Arbitrary, Gen}; +/// A test representation of a type that can be transformed unambiguously into a real Type, +/// given a db. +#[derive(Debug, Clone, PartialEq)] +pub(crate) enum Ty { + Never, + Unknown, + None, + Any, + IntLiteral(i64), + BooleanLiteral(bool), + StringLiteral(&'static str), + LiteralString, + BytesLiteral(&'static str), + // BuiltinInstance("str") corresponds to an instance of the builtin `str` class + BuiltinInstance(&'static str), + /// Members of the `abc` stdlib module + AbcInstance(&'static str), + AbcClassLiteral(&'static str), + TypingLiteral, + // BuiltinClassLiteral("str") corresponds to the builtin `str` class object itself + BuiltinClassLiteral(&'static str), + KnownClassInstance(KnownClass), + Union(Vec), + Intersection { + pos: Vec, + neg: Vec, + }, + Tuple(Vec), + SubclassOfAny, + SubclassOfBuiltinClass(&'static str), + SubclassOfAbcClass(&'static str), + AlwaysTruthy, + AlwaysFalsy, +} + +impl Ty { + pub(crate) fn into_type(self, db: &TestDb) -> Type<'_> { + match self { + Ty::Never => Type::Never, + Ty::Unknown => Type::unknown(), + Ty::None => Type::none(db), + Ty::Any => Type::any(), + Ty::IntLiteral(n) => Type::IntLiteral(n), + Ty::StringLiteral(s) => Type::string_literal(db, s), + Ty::BooleanLiteral(b) => Type::BooleanLiteral(b), + Ty::LiteralString => Type::LiteralString, + Ty::BytesLiteral(s) => Type::bytes_literal(db, s.as_bytes()), + Ty::BuiltinInstance(s) => builtins_symbol(db, s).expect_type().to_instance(db), + Ty::AbcInstance(s) => known_module_symbol(db, KnownModule::Abc, s) + .expect_type() + .to_instance(db), + Ty::AbcClassLiteral(s) => known_module_symbol(db, KnownModule::Abc, s).expect_type(), + Ty::TypingLiteral => Type::KnownInstance(KnownInstanceType::Literal), + Ty::BuiltinClassLiteral(s) => builtins_symbol(db, s).expect_type(), + Ty::KnownClassInstance(known_class) => known_class.to_instance(db), + Ty::Union(tys) => { + UnionType::from_elements(db, tys.into_iter().map(|ty| ty.into_type(db))) + } + Ty::Intersection { pos, neg } => { + let mut builder = IntersectionBuilder::new(db); + for p in pos { + builder = builder.add_positive(p.into_type(db)); + } + for n in neg { + builder = builder.add_negative(n.into_type(db)); + } + builder.build() + } + Ty::Tuple(tys) => { + let elements = tys.into_iter().map(|ty| ty.into_type(db)); + TupleType::from_elements(db, elements) + } + Ty::SubclassOfAny => SubclassOfType::subclass_of_any(), + Ty::SubclassOfBuiltinClass(s) => SubclassOfType::from( + db, + builtins_symbol(db, s) + .expect_type() + .expect_class_literal() + .class, + ), + Ty::SubclassOfAbcClass(s) => SubclassOfType::from( + db, + known_module_symbol(db, KnownModule::Abc, s) + .expect_type() + .expect_class_literal() + .class, + ), + Ty::AlwaysTruthy => Type::AlwaysTruthy, + Ty::AlwaysFalsy => Type::AlwaysFalsy, + } + } +} + fn arbitrary_core_type(g: &mut Gen) -> Ty { // We could select a random integer here, but this would make it much less // likely to explore interesting edge cases: @@ -205,7 +301,7 @@ macro_rules! type_property_test { ($test_name:ident, $db:ident, forall types $($types:ident),+ . $property:expr) => { #[quickcheck_macros::quickcheck] #[ignore] - fn $test_name($($types: crate::types::tests::Ty),+) -> bool { + fn $test_name($($types: super::Ty),+) -> bool { let db_cached = super::get_cached_db(); let $db = &*db_cached; $(let $types = $types.into_type($db);)+