mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
[ruff
] Implement redundant-bool-literal
(RUF038
) (#14319)
## Summary Implements `redundant-bool-literal` ## Test Plan <!-- How was it tested? --> `cargo test` The ecosystem results are all correct, but for `Airflow` the rule is not relevant due to the use of overloading (and is marked as unsafe correctly). --------- Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
parent
4dcb7ddafe
commit
1fbed6c325
11 changed files with 421 additions and 1 deletions
|
@ -317,5 +317,6 @@ const KNOWN_FAILURES: &[(&str, bool, bool)] = &[
|
||||||
("crates/ruff_linter/resources/test/fixtures/ruff/RUF013_0.py", true, true),
|
("crates/ruff_linter/resources/test/fixtures/ruff/RUF013_0.py", true, true),
|
||||||
("crates/ruff_linter/resources/test/fixtures/ruff/RUF013_3.py", true, true),
|
("crates/ruff_linter/resources/test/fixtures/ruff/RUF013_3.py", true, true),
|
||||||
("crates/ruff_linter/resources/test/fixtures/ruff/RUF022.py", true, true),
|
("crates/ruff_linter/resources/test/fixtures/ruff/RUF022.py", true, true),
|
||||||
|
("crates/ruff_linter/resources/test/fixtures/ruff/RUF038.py", true, true),
|
||||||
("crates/ruff_python_parser/resources/valid/expressions/f_string.py", true, true),
|
("crates/ruff_python_parser/resources/valid/expressions/f_string.py", true, true),
|
||||||
];
|
];
|
||||||
|
|
33
crates/ruff_linter/resources/test/fixtures/ruff/RUF038.py
vendored
Normal file
33
crates/ruff_linter/resources/test/fixtures/ruff/RUF038.py
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
|
||||||
|
def func1(arg1: Literal[True, False]):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def func2(arg1: Literal[True, False, True]):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def func3() -> Literal[True, False]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def func4(arg1: Literal[True, False] | bool):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def func5(arg1: Literal[False, True]):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def func6(arg1: Literal[True, False, "hello", "world"]):
|
||||||
|
...
|
||||||
|
|
||||||
|
# ok
|
||||||
|
def good_func1(arg1: bool):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def good_func2(arg1: Literal[True]):
|
||||||
|
...
|
20
crates/ruff_linter/resources/test/fixtures/ruff/RUF038.pyi
vendored
Normal file
20
crates/ruff_linter/resources/test/fixtures/ruff/RUF038.pyi
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
|
||||||
|
def func1(arg1: Literal[True, False]): ...
|
||||||
|
|
||||||
|
def func2(arg1: Literal[True, False, True]): ...
|
||||||
|
|
||||||
|
def func3() -> Literal[True, False]: ...
|
||||||
|
|
||||||
|
def func4(arg1: Literal[True, False] | bool): ...
|
||||||
|
|
||||||
|
def func5(arg1: Literal[False, True]): ...
|
||||||
|
|
||||||
|
def func6(arg1: Literal[True, False, "hello", "world"]): ...
|
||||||
|
|
||||||
|
# ok
|
||||||
|
def good_func1(arg1: bool): ...
|
||||||
|
|
||||||
|
def good_func2(arg1: Literal[True]): ...
|
||||||
|
|
|
@ -104,11 +104,18 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ex) Literal[...]
|
// Ex) Literal[...]
|
||||||
if checker.any_enabled(&[Rule::DuplicateLiteralMember, Rule::RedundantNoneLiteral]) {
|
if checker.any_enabled(&[
|
||||||
|
Rule::DuplicateLiteralMember,
|
||||||
|
Rule::RedundantBoolLiteral,
|
||||||
|
Rule::RedundantNoneLiteral,
|
||||||
|
]) {
|
||||||
if !checker.semantic.in_nested_literal() {
|
if !checker.semantic.in_nested_literal() {
|
||||||
if checker.enabled(Rule::DuplicateLiteralMember) {
|
if checker.enabled(Rule::DuplicateLiteralMember) {
|
||||||
flake8_pyi::rules::duplicate_literal_member(checker, expr);
|
flake8_pyi::rules::duplicate_literal_member(checker, expr);
|
||||||
}
|
}
|
||||||
|
if checker.enabled(Rule::RedundantBoolLiteral) {
|
||||||
|
ruff::rules::redundant_bool_literal(checker, expr);
|
||||||
|
}
|
||||||
if checker.enabled(Rule::RedundantNoneLiteral) {
|
if checker.enabled(Rule::RedundantNoneLiteral) {
|
||||||
flake8_pyi::rules::redundant_none_literal(checker, expr);
|
flake8_pyi::rules::redundant_none_literal(checker, expr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -970,6 +970,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||||
(Ruff, "034") => (RuleGroup::Preview, rules::ruff::rules::UselessIfElse),
|
(Ruff, "034") => (RuleGroup::Preview, rules::ruff::rules::UselessIfElse),
|
||||||
(Ruff, "035") => (RuleGroup::Preview, rules::ruff::rules::UnsafeMarkupUse),
|
(Ruff, "035") => (RuleGroup::Preview, rules::ruff::rules::UnsafeMarkupUse),
|
||||||
(Ruff, "036") => (RuleGroup::Preview, rules::ruff::rules::NoneNotAtEndOfUnion),
|
(Ruff, "036") => (RuleGroup::Preview, rules::ruff::rules::NoneNotAtEndOfUnion),
|
||||||
|
(Ruff, "038") => (RuleGroup::Preview, rules::ruff::rules::RedundantBoolLiteral),
|
||||||
(Ruff, "100") => (RuleGroup::Stable, rules::ruff::rules::UnusedNOQA),
|
(Ruff, "100") => (RuleGroup::Stable, rules::ruff::rules::UnusedNOQA),
|
||||||
(Ruff, "101") => (RuleGroup::Stable, rules::ruff::rules::RedirectedNOQA),
|
(Ruff, "101") => (RuleGroup::Stable, rules::ruff::rules::RedirectedNOQA),
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,8 @@ mod tests {
|
||||||
#[test_case(Rule::PostInitDefault, Path::new("RUF033.py"))]
|
#[test_case(Rule::PostInitDefault, Path::new("RUF033.py"))]
|
||||||
#[test_case(Rule::NoneNotAtEndOfUnion, Path::new("RUF036.py"))]
|
#[test_case(Rule::NoneNotAtEndOfUnion, Path::new("RUF036.py"))]
|
||||||
#[test_case(Rule::NoneNotAtEndOfUnion, Path::new("RUF036.pyi"))]
|
#[test_case(Rule::NoneNotAtEndOfUnion, Path::new("RUF036.pyi"))]
|
||||||
|
#[test_case(Rule::RedundantBoolLiteral, Path::new("RUF038.py"))]
|
||||||
|
#[test_case(Rule::RedundantBoolLiteral, Path::new("RUF038.pyi"))]
|
||||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||||
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
|
||||||
let diagnostics = test_path(
|
let diagnostics = test_path(
|
||||||
|
|
|
@ -22,6 +22,7 @@ pub(crate) use parenthesize_logical_operators::*;
|
||||||
pub(crate) use post_init_default::*;
|
pub(crate) use post_init_default::*;
|
||||||
pub(crate) use quadratic_list_summation::*;
|
pub(crate) use quadratic_list_summation::*;
|
||||||
pub(crate) use redirected_noqa::*;
|
pub(crate) use redirected_noqa::*;
|
||||||
|
pub(crate) use redundant_bool_literal::*;
|
||||||
pub(crate) use sort_dunder_all::*;
|
pub(crate) use sort_dunder_all::*;
|
||||||
pub(crate) use sort_dunder_slots::*;
|
pub(crate) use sort_dunder_slots::*;
|
||||||
pub(crate) use static_key_dict_comprehension::*;
|
pub(crate) use static_key_dict_comprehension::*;
|
||||||
|
@ -61,6 +62,7 @@ mod parenthesize_logical_operators;
|
||||||
mod post_init_default;
|
mod post_init_default;
|
||||||
mod quadratic_list_summation;
|
mod quadratic_list_summation;
|
||||||
mod redirected_noqa;
|
mod redirected_noqa;
|
||||||
|
mod redundant_bool_literal;
|
||||||
mod sequence_sorting;
|
mod sequence_sorting;
|
||||||
mod sort_dunder_all;
|
mod sort_dunder_all;
|
||||||
mod sort_dunder_slots;
|
mod sort_dunder_slots;
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||||
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
use ruff_python_ast::Expr;
|
||||||
|
use ruff_python_semantic::analyze::typing::traverse_literal;
|
||||||
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
use bitflags::bitflags;
|
||||||
|
|
||||||
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
|
/// ## What it does
|
||||||
|
/// Checks for `Literal[True, False]` type annotations.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// `Literal[True, False]` can be replaced with `bool` in type annotations,
|
||||||
|
/// which has the same semantic meaning but is more concise and readable.
|
||||||
|
///
|
||||||
|
/// `bool` type has exactly two constant instances: `True` and `False`. Static
|
||||||
|
/// type checkers such as [mypy] treat `Literal[True, False]` as equivalent to
|
||||||
|
/// `bool` in a type annotation.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```python
|
||||||
|
/// from typing import Literal
|
||||||
|
///
|
||||||
|
/// x: Literal[True, False]
|
||||||
|
/// y: Literal[True, False, "hello", "world"]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// from typing import Literal
|
||||||
|
///
|
||||||
|
/// x: bool
|
||||||
|
/// y: Literal["hello", "world"] | bool
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Fix safety
|
||||||
|
/// The fix for this rule is marked as unsafe, as it may change the semantics of the code.
|
||||||
|
/// Specifically:
|
||||||
|
///
|
||||||
|
/// - Type checkers may not treat `bool` as equivalent when overloading boolean arguments
|
||||||
|
/// with `Literal[True]` and `Literal[False]` (see, e.g., [#14764] and [#5421]).
|
||||||
|
/// - `bool` is not strictly equivalent to `Literal[True, False]`, as `bool` is
|
||||||
|
/// a subclass of `int`, and this rule may not apply if the type annotations are used
|
||||||
|
/// in a numeric context.
|
||||||
|
///
|
||||||
|
/// Further, the `Literal` slice may contain trailing-line comments which the fix would remove.
|
||||||
|
///
|
||||||
|
/// ## References
|
||||||
|
/// - [Typing documentation: Legal parameters for `Literal` at type check time](https://typing.readthedocs.io/en/latest/spec/literal.html#legal-parameters-for-literal-at-type-check-time)
|
||||||
|
/// - [Python documentation: Boolean type - `bool`](https://docs.python.org/3/library/stdtypes.html#boolean-type-bool)
|
||||||
|
///
|
||||||
|
/// [mypy]: https://github.com/python/mypy/blob/master/mypy/typeops.py#L985
|
||||||
|
/// [#14764]: https://github.com/python/mypy/issues/14764
|
||||||
|
/// [#5421]: https://github.com/microsoft/pyright/issues/5421
|
||||||
|
#[violation]
|
||||||
|
pub struct RedundantBoolLiteral {
|
||||||
|
seen_others: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Violation for RedundantBoolLiteral {
|
||||||
|
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
|
||||||
|
|
||||||
|
#[derive_message_formats]
|
||||||
|
fn message(&self) -> String {
|
||||||
|
if self.seen_others {
|
||||||
|
"`Literal[True, False, ...]` can be replaced with `Literal[...] | bool`".to_string()
|
||||||
|
} else {
|
||||||
|
"`Literal[True, False]` can be replaced with `bool`".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fix_title(&self) -> Option<String> {
|
||||||
|
Some(if self.seen_others {
|
||||||
|
"Replace with `Literal[...] | bool`".to_string()
|
||||||
|
} else {
|
||||||
|
"Replace with `bool`".to_string()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// RUF038
|
||||||
|
pub(crate) fn redundant_bool_literal<'a>(checker: &mut Checker, literal_expr: &'a Expr) {
|
||||||
|
if !checker.semantic().seen_typing() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut seen_expr = BooleanLiteral::empty();
|
||||||
|
|
||||||
|
let mut find_bools = |expr: &'a Expr, _parent: &'a Expr| {
|
||||||
|
let expr_type = match expr {
|
||||||
|
Expr::BooleanLiteral(boolean_expr) => {
|
||||||
|
if boolean_expr.value {
|
||||||
|
BooleanLiteral::TRUE
|
||||||
|
} else {
|
||||||
|
BooleanLiteral::FALSE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => BooleanLiteral::OTHER,
|
||||||
|
};
|
||||||
|
seen_expr.insert(expr_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
traverse_literal(&mut find_bools, checker.semantic(), literal_expr);
|
||||||
|
|
||||||
|
if !seen_expr.contains(BooleanLiteral::TRUE | BooleanLiteral::FALSE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let seen_others = seen_expr.contains(BooleanLiteral::OTHER);
|
||||||
|
|
||||||
|
let mut diagnostic =
|
||||||
|
Diagnostic::new(RedundantBoolLiteral { seen_others }, literal_expr.range());
|
||||||
|
|
||||||
|
// Provide a [`Fix`] when the complete `Literal` can be replaced. Applying the fix
|
||||||
|
// can leave an unused import to be fixed by the `unused-import` rule.
|
||||||
|
if !seen_others {
|
||||||
|
if checker.semantic().has_builtin_binding("bool") {
|
||||||
|
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
|
||||||
|
"bool".to_string(),
|
||||||
|
literal_expr.range(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checker.diagnostics.push(diagnostic);
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
struct BooleanLiteral: u8 {
|
||||||
|
const TRUE = 1 << 0;
|
||||||
|
const FALSE = 1 << 1;
|
||||||
|
const OTHER = 1 << 2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||||
|
---
|
||||||
|
RUF038.py:4:17: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
4 | def func1(arg1: Literal[True, False]):
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
5 | ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
1 1 | from typing import Literal
|
||||||
|
2 2 |
|
||||||
|
3 3 |
|
||||||
|
4 |-def func1(arg1: Literal[True, False]):
|
||||||
|
4 |+def func1(arg1: bool):
|
||||||
|
5 5 | ...
|
||||||
|
6 6 |
|
||||||
|
7 7 |
|
||||||
|
|
||||||
|
RUF038.py:8:17: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
8 | def func2(arg1: Literal[True, False, True]):
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
9 | ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
5 5 | ...
|
||||||
|
6 6 |
|
||||||
|
7 7 |
|
||||||
|
8 |-def func2(arg1: Literal[True, False, True]):
|
||||||
|
8 |+def func2(arg1: bool):
|
||||||
|
9 9 | ...
|
||||||
|
10 10 |
|
||||||
|
11 11 |
|
||||||
|
|
||||||
|
RUF038.py:12:16: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
12 | def func3() -> Literal[True, False]:
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
13 | ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
9 9 | ...
|
||||||
|
10 10 |
|
||||||
|
11 11 |
|
||||||
|
12 |-def func3() -> Literal[True, False]:
|
||||||
|
12 |+def func3() -> bool:
|
||||||
|
13 13 | ...
|
||||||
|
14 14 |
|
||||||
|
15 15 |
|
||||||
|
|
||||||
|
RUF038.py:16:17: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
16 | def func4(arg1: Literal[True, False] | bool):
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
17 | ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
13 13 | ...
|
||||||
|
14 14 |
|
||||||
|
15 15 |
|
||||||
|
16 |-def func4(arg1: Literal[True, False] | bool):
|
||||||
|
16 |+def func4(arg1: bool | bool):
|
||||||
|
17 17 | ...
|
||||||
|
18 18 |
|
||||||
|
19 19 |
|
||||||
|
|
||||||
|
RUF038.py:20:17: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
20 | def func5(arg1: Literal[False, True]):
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
21 | ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
17 17 | ...
|
||||||
|
18 18 |
|
||||||
|
19 19 |
|
||||||
|
20 |-def func5(arg1: Literal[False, True]):
|
||||||
|
20 |+def func5(arg1: bool):
|
||||||
|
21 21 | ...
|
||||||
|
22 22 |
|
||||||
|
23 23 |
|
||||||
|
|
||||||
|
RUF038.py:24:17: RUF038 `Literal[True, False, ...]` can be replaced with `Literal[...] | bool`
|
||||||
|
|
|
||||||
|
24 | def func6(arg1: Literal[True, False, "hello", "world"]):
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
25 | ...
|
||||||
|
|
|
||||||
|
= help: Replace with `Literal[...] | bool`
|
|
@ -0,0 +1,116 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||||
|
---
|
||||||
|
RUF038.pyi:4:17: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
4 | def func1(arg1: Literal[True, False]): ...
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
5 |
|
||||||
|
6 | def func2(arg1: Literal[True, False, True]): ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
1 1 | from typing import Literal
|
||||||
|
2 2 |
|
||||||
|
3 3 |
|
||||||
|
4 |-def func1(arg1: Literal[True, False]): ...
|
||||||
|
4 |+def func1(arg1: bool): ...
|
||||||
|
5 5 |
|
||||||
|
6 6 | def func2(arg1: Literal[True, False, True]): ...
|
||||||
|
7 7 |
|
||||||
|
|
||||||
|
RUF038.pyi:6:17: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
4 | def func1(arg1: Literal[True, False]): ...
|
||||||
|
5 |
|
||||||
|
6 | def func2(arg1: Literal[True, False, True]): ...
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
7 |
|
||||||
|
8 | def func3() -> Literal[True, False]: ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
3 3 |
|
||||||
|
4 4 | def func1(arg1: Literal[True, False]): ...
|
||||||
|
5 5 |
|
||||||
|
6 |-def func2(arg1: Literal[True, False, True]): ...
|
||||||
|
6 |+def func2(arg1: bool): ...
|
||||||
|
7 7 |
|
||||||
|
8 8 | def func3() -> Literal[True, False]: ...
|
||||||
|
9 9 |
|
||||||
|
|
||||||
|
RUF038.pyi:8:16: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
6 | def func2(arg1: Literal[True, False, True]): ...
|
||||||
|
7 |
|
||||||
|
8 | def func3() -> Literal[True, False]: ...
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
9 |
|
||||||
|
10 | def func4(arg1: Literal[True, False] | bool): ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
5 5 |
|
||||||
|
6 6 | def func2(arg1: Literal[True, False, True]): ...
|
||||||
|
7 7 |
|
||||||
|
8 |-def func3() -> Literal[True, False]: ...
|
||||||
|
8 |+def func3() -> bool: ...
|
||||||
|
9 9 |
|
||||||
|
10 10 | def func4(arg1: Literal[True, False] | bool): ...
|
||||||
|
11 11 |
|
||||||
|
|
||||||
|
RUF038.pyi:10:17: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
8 | def func3() -> Literal[True, False]: ...
|
||||||
|
9 |
|
||||||
|
10 | def func4(arg1: Literal[True, False] | bool): ...
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
11 |
|
||||||
|
12 | def func5(arg1: Literal[False, True]): ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
7 7 |
|
||||||
|
8 8 | def func3() -> Literal[True, False]: ...
|
||||||
|
9 9 |
|
||||||
|
10 |-def func4(arg1: Literal[True, False] | bool): ...
|
||||||
|
10 |+def func4(arg1: bool | bool): ...
|
||||||
|
11 11 |
|
||||||
|
12 12 | def func5(arg1: Literal[False, True]): ...
|
||||||
|
13 13 |
|
||||||
|
|
||||||
|
RUF038.pyi:12:17: RUF038 [*] `Literal[True, False]` can be replaced with `bool`
|
||||||
|
|
|
||||||
|
10 | def func4(arg1: Literal[True, False] | bool): ...
|
||||||
|
11 |
|
||||||
|
12 | def func5(arg1: Literal[False, True]): ...
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
13 |
|
||||||
|
14 | def func6(arg1: Literal[True, False, "hello", "world"]): ...
|
||||||
|
|
|
||||||
|
= help: Replace with `bool`
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
9 9 |
|
||||||
|
10 10 | def func4(arg1: Literal[True, False] | bool): ...
|
||||||
|
11 11 |
|
||||||
|
12 |-def func5(arg1: Literal[False, True]): ...
|
||||||
|
12 |+def func5(arg1: bool): ...
|
||||||
|
13 13 |
|
||||||
|
14 14 | def func6(arg1: Literal[True, False, "hello", "world"]): ...
|
||||||
|
15 15 |
|
||||||
|
|
||||||
|
RUF038.pyi:14:17: RUF038 `Literal[True, False, ...]` can be replaced with `Literal[...] | bool`
|
||||||
|
|
|
||||||
|
12 | def func5(arg1: Literal[False, True]): ...
|
||||||
|
13 |
|
||||||
|
14 | def func6(arg1: Literal[True, False, "hello", "world"]): ...
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF038
|
||||||
|
15 |
|
||||||
|
16 | # ok
|
||||||
|
|
|
||||||
|
= help: Replace with `Literal[...] | bool`
|
1
ruff.schema.json
generated
1
ruff.schema.json
generated
|
@ -3835,6 +3835,7 @@
|
||||||
"RUF034",
|
"RUF034",
|
||||||
"RUF035",
|
"RUF035",
|
||||||
"RUF036",
|
"RUF036",
|
||||||
|
"RUF038",
|
||||||
"RUF1",
|
"RUF1",
|
||||||
"RUF10",
|
"RUF10",
|
||||||
"RUF100",
|
"RUF100",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue