[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`.
This commit is contained in:
David Peter
2025-01-20 10:15:31 +01:00
committed by GitHub
parent 5cd1f79864
commit 912247635d
2 changed files with 101 additions and 100 deletions

View File

@@ -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<Ty>),
Intersection {
pos: Vec<Ty>,
neg: Vec<Ty>,
},
Tuple(Vec<Ty>),
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));
}

View File

@@ -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<Ty>),
Intersection {
pos: Vec<Ty>,
neg: Vec<Ty>,
},
Tuple(Vec<Ty>),
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);)+