mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 05:45:24 +00:00
[red-knot] Migrate bool
/str
/repr
unit tests to Markdown tests (#15534)
## Summary Part of #15397. ## Test Plan Markdown tests.
This commit is contained in:
parent
e2da33a45c
commit
2e6729d900
6 changed files with 104 additions and 65 deletions
|
@ -100,7 +100,7 @@ def _(flag: bool):
|
||||||
foo_3: LiteralString = "foo" * 1_000_000_000
|
foo_3: LiteralString = "foo" * 1_000_000_000
|
||||||
bar_3: str = foo_2 # fine
|
bar_3: str = foo_2 # fine
|
||||||
|
|
||||||
baz_1: str = str()
|
baz_1: str = repr(object())
|
||||||
qux_1: LiteralString = baz_1 # error: [invalid-assignment]
|
qux_1: LiteralString = baz_1 # error: [invalid-assignment]
|
||||||
|
|
||||||
baz_2: LiteralString = "baz" * 1_000_000_000
|
baz_2: LiteralString = "baz" * 1_000_000_000
|
||||||
|
|
|
@ -3,17 +3,16 @@
|
||||||
## Expression
|
## Expression
|
||||||
|
|
||||||
```py
|
```py
|
||||||
x = 0
|
from typing_extensions import Literal
|
||||||
y = str()
|
|
||||||
z = False
|
|
||||||
|
|
||||||
reveal_type(f"hello") # revealed: Literal["hello"]
|
def _(x: Literal[0], y: str, z: Literal[False]):
|
||||||
reveal_type(f"h {x}") # revealed: Literal["h 0"]
|
reveal_type(f"hello") # revealed: Literal["hello"]
|
||||||
reveal_type("one " f"single " f"literal") # revealed: Literal["one single literal"]
|
reveal_type(f"h {x}") # revealed: Literal["h 0"]
|
||||||
reveal_type("first " f"second({x})" f" third") # revealed: Literal["first second(0) third"]
|
reveal_type("one " f"single " f"literal") # revealed: Literal["one single literal"]
|
||||||
reveal_type(f"-{y}-") # revealed: str
|
reveal_type("first " f"second({x})" f" third") # revealed: Literal["first second(0) third"]
|
||||||
reveal_type(f"-{y}-" f"--" "--") # revealed: str
|
reveal_type(f"-{y}-") # revealed: str
|
||||||
reveal_type(f"{z} == {False} is {True}") # revealed: Literal["False == False is True"]
|
reveal_type(f"-{y}-" f"--" "--") # revealed: str
|
||||||
|
reveal_type(f"{z} == {False} is {True}") # revealed: Literal["False == False is True"]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Conversion Flags
|
## Conversion Flags
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# `__str__` and `__repr__`
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing_extensions import Literal, LiteralString
|
||||||
|
|
||||||
|
def _(
|
||||||
|
a: Literal[1],
|
||||||
|
b: Literal[True],
|
||||||
|
c: Literal[False],
|
||||||
|
d: Literal["ab'cd"],
|
||||||
|
e: LiteralString,
|
||||||
|
f: int,
|
||||||
|
):
|
||||||
|
reveal_type(str(a)) # revealed: Literal["1"]
|
||||||
|
reveal_type(str(b)) # revealed: Literal["True"]
|
||||||
|
reveal_type(str(c)) # revealed: Literal["False"]
|
||||||
|
reveal_type(str(d)) # revealed: Literal["ab'cd"]
|
||||||
|
reveal_type(str(e)) # revealed: LiteralString
|
||||||
|
reveal_type(str(f)) # revealed: str
|
||||||
|
|
||||||
|
reveal_type(repr(a)) # revealed: Literal["1"]
|
||||||
|
reveal_type(repr(b)) # revealed: Literal["True"]
|
||||||
|
reveal_type(repr(c)) # revealed: Literal["False"]
|
||||||
|
reveal_type(repr(d)) # revealed: Literal["'ab\\'cd'"]
|
||||||
|
reveal_type(repr(e)) # revealed: LiteralString
|
||||||
|
reveal_type(repr(f)) # revealed: str
|
||||||
|
```
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Truthiness
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing_extensions import Literal, LiteralString
|
||||||
|
from knot_extensions import AlwaysFalsy, AlwaysTruthy
|
||||||
|
|
||||||
|
def _(
|
||||||
|
a: Literal[1],
|
||||||
|
b: Literal[-1],
|
||||||
|
c: Literal["foo"],
|
||||||
|
d: tuple[Literal[0]],
|
||||||
|
e: Literal[1, 2],
|
||||||
|
f: AlwaysTruthy,
|
||||||
|
):
|
||||||
|
reveal_type(bool(a)) # revealed: Literal[True]
|
||||||
|
reveal_type(bool(b)) # revealed: Literal[True]
|
||||||
|
reveal_type(bool(c)) # revealed: Literal[True]
|
||||||
|
reveal_type(bool(d)) # revealed: Literal[True]
|
||||||
|
reveal_type(bool(e)) # revealed: Literal[True]
|
||||||
|
reveal_type(bool(f)) # revealed: Literal[True]
|
||||||
|
|
||||||
|
def _(
|
||||||
|
a: tuple[()],
|
||||||
|
b: Literal[0],
|
||||||
|
c: Literal[""],
|
||||||
|
d: Literal[b""],
|
||||||
|
e: Literal[0, 0],
|
||||||
|
f: AlwaysFalsy,
|
||||||
|
):
|
||||||
|
reveal_type(bool(a)) # revealed: Literal[False]
|
||||||
|
reveal_type(bool(b)) # revealed: Literal[False]
|
||||||
|
reveal_type(bool(c)) # revealed: Literal[False]
|
||||||
|
reveal_type(bool(d)) # revealed: Literal[False]
|
||||||
|
reveal_type(bool(e)) # revealed: Literal[False]
|
||||||
|
reveal_type(bool(f)) # revealed: Literal[False]
|
||||||
|
|
||||||
|
def _(
|
||||||
|
a: str,
|
||||||
|
b: Literal[1, 0],
|
||||||
|
c: str | Literal[0],
|
||||||
|
d: str | Literal[1],
|
||||||
|
):
|
||||||
|
reveal_type(bool(a)) # revealed: bool
|
||||||
|
reveal_type(bool(b)) # revealed: bool
|
||||||
|
reveal_type(bool(c)) # revealed: bool
|
||||||
|
reveal_type(bool(d)) # revealed: bool
|
||||||
|
```
|
|
@ -2013,6 +2013,14 @@ impl<'db> Type<'db> {
|
||||||
CallOutcome::callable(binding)
|
CallOutcome::callable(binding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(KnownFunction::Repr) => {
|
||||||
|
if let Some(first_arg) = binding.one_parameter_ty() {
|
||||||
|
binding.set_return_ty(first_arg.repr(db));
|
||||||
|
};
|
||||||
|
|
||||||
|
CallOutcome::callable(binding)
|
||||||
|
}
|
||||||
|
|
||||||
Some(KnownFunction::AssertType) => {
|
Some(KnownFunction::AssertType) => {
|
||||||
let Some((_, asserted_ty)) = binding.two_parameter_tys() else {
|
let Some((_, asserted_ty)) = binding.two_parameter_tys() else {
|
||||||
return CallOutcome::callable(binding);
|
return CallOutcome::callable(binding);
|
||||||
|
@ -2050,6 +2058,12 @@ impl<'db> Type<'db> {
|
||||||
.first_argument()
|
.first_argument()
|
||||||
.map(|arg| arg.bool(db).into_type(db))
|
.map(|arg| arg.bool(db).into_type(db))
|
||||||
.unwrap_or(Type::BooleanLiteral(false)),
|
.unwrap_or(Type::BooleanLiteral(false)),
|
||||||
|
|
||||||
|
Some(KnownClass::Str) => arguments
|
||||||
|
.first_argument()
|
||||||
|
.map(|arg| arg.str(db))
|
||||||
|
.unwrap_or(Type::string_literal(db, "")),
|
||||||
|
|
||||||
_ => Type::Instance(InstanceType { class }),
|
_ => Type::Instance(InstanceType { class }),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -3389,6 +3403,8 @@ pub enum KnownFunction {
|
||||||
RevealType,
|
RevealType,
|
||||||
/// `builtins.len`
|
/// `builtins.len`
|
||||||
Len,
|
Len,
|
||||||
|
/// `builtins.repr`
|
||||||
|
Repr,
|
||||||
/// `typing(_extensions).final`
|
/// `typing(_extensions).final`
|
||||||
Final,
|
Final,
|
||||||
|
|
||||||
|
@ -3436,6 +3452,7 @@ impl KnownFunction {
|
||||||
"issubclass" => Self::ConstraintFunction(KnownConstraintFunction::IsSubclass),
|
"issubclass" => Self::ConstraintFunction(KnownConstraintFunction::IsSubclass),
|
||||||
"reveal_type" => Self::RevealType,
|
"reveal_type" => Self::RevealType,
|
||||||
"len" => Self::Len,
|
"len" => Self::Len,
|
||||||
|
"repr" => Self::Repr,
|
||||||
"final" => Self::Final,
|
"final" => Self::Final,
|
||||||
"no_type_check" => Self::NoTypeCheck,
|
"no_type_check" => Self::NoTypeCheck,
|
||||||
"assert_type" => Self::AssertType,
|
"assert_type" => Self::AssertType,
|
||||||
|
@ -3464,7 +3481,7 @@ impl KnownFunction {
|
||||||
module.is_builtins()
|
module.is_builtins()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Self::Len => module.is_builtins(),
|
Self::Len | Self::Repr => module.is_builtins(),
|
||||||
Self::AssertType | Self::Cast | Self::RevealType | Self::Final | Self::NoTypeCheck => {
|
Self::AssertType | Self::Cast | Self::RevealType | Self::Final | Self::NoTypeCheck => {
|
||||||
matches!(module, KnownModule::Typing | KnownModule::TypingExtensions)
|
matches!(module, KnownModule::Typing | KnownModule::TypingExtensions)
|
||||||
}
|
}
|
||||||
|
@ -3496,6 +3513,7 @@ impl KnownFunction {
|
||||||
|
|
||||||
Self::ConstraintFunction(_)
|
Self::ConstraintFunction(_)
|
||||||
| Self::Len
|
| Self::Len
|
||||||
|
| Self::Repr
|
||||||
| Self::Final
|
| Self::Final
|
||||||
| Self::NoTypeCheck
|
| Self::NoTypeCheck
|
||||||
| Self::RevealType
|
| Self::RevealType
|
||||||
|
@ -4625,58 +4643,6 @@ pub(crate) mod tests {
|
||||||
assert!(!b.is_gradual_equivalent_to(&db, a));
|
assert!(!b.is_gradual_equivalent_to(&db, a));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case(Ty::IntLiteral(1); "is_int_literal_truthy")]
|
|
||||||
#[test_case(Ty::IntLiteral(-1))]
|
|
||||||
#[test_case(Ty::StringLiteral("foo"))]
|
|
||||||
#[test_case(Ty::Tuple(vec![Ty::IntLiteral(0)]))]
|
|
||||||
#[test_case(Ty::Union(vec![Ty::IntLiteral(1), Ty::IntLiteral(2)]))]
|
|
||||||
fn is_truthy(ty: Ty) {
|
|
||||||
let db = setup_db();
|
|
||||||
assert_eq!(ty.into_type(&db).bool(&db), Truthiness::AlwaysTrue);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case(Ty::Tuple(vec![]))]
|
|
||||||
#[test_case(Ty::IntLiteral(0))]
|
|
||||||
#[test_case(Ty::StringLiteral(""))]
|
|
||||||
#[test_case(Ty::Union(vec![Ty::IntLiteral(0), Ty::IntLiteral(0)]))]
|
|
||||||
fn is_falsy(ty: Ty) {
|
|
||||||
let db = setup_db();
|
|
||||||
assert_eq!(ty.into_type(&db).bool(&db), Truthiness::AlwaysFalse);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case(Ty::BuiltinInstance("str"))]
|
|
||||||
#[test_case(Ty::Union(vec![Ty::IntLiteral(1), Ty::IntLiteral(0)]))]
|
|
||||||
#[test_case(Ty::Union(vec![Ty::BuiltinInstance("str"), Ty::IntLiteral(0)]))]
|
|
||||||
#[test_case(Ty::Union(vec![Ty::BuiltinInstance("str"), Ty::IntLiteral(1)]))]
|
|
||||||
fn boolean_value_is_unknown(ty: Ty) {
|
|
||||||
let db = setup_db();
|
|
||||||
assert_eq!(ty.into_type(&db).bool(&db), Truthiness::Ambiguous);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case(Ty::IntLiteral(1), Ty::StringLiteral("1"))]
|
|
||||||
#[test_case(Ty::BooleanLiteral(true), Ty::StringLiteral("True"))]
|
|
||||||
#[test_case(Ty::BooleanLiteral(false), Ty::StringLiteral("False"))]
|
|
||||||
#[test_case(Ty::StringLiteral("ab'cd"), Ty::StringLiteral("ab'cd"))] // no quotes
|
|
||||||
#[test_case(Ty::LiteralString, Ty::LiteralString)]
|
|
||||||
#[test_case(Ty::BuiltinInstance("int"), Ty::BuiltinInstance("str"))]
|
|
||||||
fn has_correct_str(ty: Ty, expected: Ty) {
|
|
||||||
let db = setup_db();
|
|
||||||
|
|
||||||
assert_eq!(ty.into_type(&db).str(&db), expected.into_type(&db));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case(Ty::IntLiteral(1), Ty::StringLiteral("1"))]
|
|
||||||
#[test_case(Ty::BooleanLiteral(true), Ty::StringLiteral("True"))]
|
|
||||||
#[test_case(Ty::BooleanLiteral(false), Ty::StringLiteral("False"))]
|
|
||||||
#[test_case(Ty::StringLiteral("ab'cd"), Ty::StringLiteral("'ab\\'cd'"))] // single quotes
|
|
||||||
#[test_case(Ty::LiteralString, Ty::LiteralString)]
|
|
||||||
#[test_case(Ty::BuiltinInstance("int"), Ty::BuiltinInstance("str"))]
|
|
||||||
fn has_correct_repr(ty: Ty, expected: Ty) {
|
|
||||||
let db = setup_db();
|
|
||||||
|
|
||||||
assert_eq!(ty.into_type(&db).repr(&db), expected.into_type(&db));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn typing_vs_typeshed_no_default() {
|
fn typing_vs_typeshed_no_default() {
|
||||||
let db = TestDbBuilder::new()
|
let db = TestDbBuilder::new()
|
||||||
|
|
|
@ -18,7 +18,7 @@ TypeOf: _SpecialForm
|
||||||
# Ideally, these would be annotated using `TypeForm`, but that has not been
|
# Ideally, these would be annotated using `TypeForm`, but that has not been
|
||||||
# standardized yet (https://peps.python.org/pep-0747).
|
# standardized yet (https://peps.python.org/pep-0747).
|
||||||
def is_equivalent_to(type_a: Any, type_b: Any) -> bool: ...
|
def is_equivalent_to(type_a: Any, type_b: Any) -> bool: ...
|
||||||
def is_subtype_of(type_derived: Any, typ_ebase: Any) -> bool: ...
|
def is_subtype_of(type_derived: Any, type_base: Any) -> bool: ...
|
||||||
def is_assignable_to(type_target: Any, type_source: Any) -> bool: ...
|
def is_assignable_to(type_target: Any, type_source: Any) -> bool: ...
|
||||||
def is_disjoint_from(type_a: Any, type_b: Any) -> bool: ...
|
def is_disjoint_from(type_a: Any, type_b: Any) -> bool: ...
|
||||||
def is_fully_static(type: Any) -> bool: ...
|
def is_fully_static(type: Any) -> bool: ...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue