Fix: Update snapshots and code

This commit is contained in:
Chandra Kiran G 2025-11-03 15:17:44 +05:30
parent 82675083eb
commit e73b3a52b6
3 changed files with 190 additions and 35 deletions

View File

@ -4,20 +4,20 @@ use anyhow::Result;
use ruff_python_ast::name::Name;
use rustc_hash::FxHashSet;
use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, ViolationMetadata};
use ruff_diagnostics::{Applicability, Edit, Fix};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::{
self as ast, Expr, ExprBinOp, ExprContext, ExprName, ExprSubscript, LiteralExpressionRef,
Operator,
};
use ruff_python_semantic::analyze::typing::traverse_union;
use ruff_python_semantic::SemanticModel;
use ruff_python_semantic::analyze::typing::traverse_union;
use ruff_text_size::{Ranged, TextRange};
use crate::Violation;
use crate::checkers::ast::Checker;
use crate::fix::snippet::SourceCodeSnippet;
use crate::importer::ImportRequest;
use crate::{FixAvailability, Violation};
/// ## What it does
/// Checks for redundant unions between a `Literal` and a builtin supertype of
@ -78,7 +78,7 @@ impl Violation for RedundantLiteralUnion {
match union_kind {
UnionKind::TypingUnion => Some(format!(
"Replace `typing.Union[Literal[{literal}], {builtin_type}]` with `{builtin_type}`"
)),
)),
UnionKind::PEP604 => Some(format!(
"Replace `Literal[{literal}] | {builtin_type}` with `{builtin_type}`"
)),
@ -141,7 +141,7 @@ pub(crate) fn redundant_literal_union<'a>(checker: &Checker, union: &'a Expr) {
return;
};
let mut diagnostics = Vec::new();
let mut diagnostics: Vec<(RedundantLiteralUnion, TextRange)> = Vec::new();
let mut non_redundant_literal_types = Vec::new();
for typing_literal_expr in typing_literal_exprs {
@ -150,7 +150,7 @@ pub(crate) fn redundant_literal_union<'a>(checker: &Checker, union: &'a Expr) {
};
if builtin_types_in_union.contains(&literal_type) {
diagnostics.push(Diagnostic::new(
diagnostics.push((
RedundantLiteralUnion {
literal: SourceCodeSnippet::from_str(
checker.locator().slice(typing_literal_expr),
@ -165,8 +165,10 @@ pub(crate) fn redundant_literal_union<'a>(checker: &Checker, union: &'a Expr) {
}
}
if checker.settings.preview.is_disabled() {
checker.report_diagnostics(diagnostics);
if checker.settings().preview.is_disabled() {
for (kind, range) in diagnostics {
let _ = checker.report_diagnostic(kind, range);
}
return;
}
@ -212,11 +214,13 @@ pub(crate) fn redundant_literal_union<'a>(checker: &Checker, union: &'a Expr) {
}
LiteralExprType::NonRedundantTypes(group) => {
let new_literal_expr = Expr::Subscript(ast::ExprSubscript {
node_index: Default::default(),
value: Box::new(literal_subscript.clone()),
range: TextRange::default(),
ctx: ExprContext::Load,
slice: Box::new(if group.len() > 1 {
Expr::Tuple(ast::ExprTuple {
node_index: Default::default(),
elts: group.into_iter().cloned().collect(),
range: TextRange::default(),
ctx: ExprContext::Load,
@ -240,23 +244,26 @@ pub(crate) fn redundant_literal_union<'a>(checker: &Checker, union: &'a Expr) {
Applicability::Safe
};
for diagnostic in &mut diagnostics {
for (kind, range) in diagnostics {
let mut diagnostic = checker.report_diagnostic(kind, range);
match union_kind {
UnionKind::PEP604 => diagnostic.try_set_optional_fix(|| {
Ok(generate_pep604_fix(
checker,
&new_exprs,
union,
applicability,
))
}),
UnionKind::TypingUnion => diagnostic.try_set_optional_fix(|| {
generate_typing_union_fix(checker, &new_exprs, union, applicability)
}),
UnionKind::PEP604 => {
diagnostic.try_set_optional_fix(|| -> anyhow::Result<Option<Fix>> {
Ok(generate_pep604_fix(
checker,
&new_exprs,
union,
applicability,
))
});
}
UnionKind::TypingUnion => {
diagnostic.try_set_optional_fix(|| -> anyhow::Result<Option<Fix>> {
generate_typing_union_fix(checker, &new_exprs, union, applicability)
});
}
}
}
checker.report_diagnostics(diagnostics);
}
fn generate_pep604_fix(
@ -275,6 +282,7 @@ fn generate_pep604_fix(
let new_expr = new_exprs.iter().fold(None, |acc, right| {
if let Some(left) = acc {
Some(Expr::BinOp(ExprBinOp {
node_index: Default::default(),
left: Box::new(left),
op: Operator::BitOr,
right: Box::new(right.clone()),
@ -305,14 +313,17 @@ fn generate_typing_union_fix(
// Construct the expression as `Subscript[typing.Union, Tuple[expr, [expr, ...]]]`
let new_expr = Expr::Subscript(ExprSubscript {
node_index: Default::default(),
range: TextRange::default(),
value: Box::new(Expr::Name(ExprName {
node_index: Default::default(),
id: Name::new(binding),
ctx: ExprContext::Store,
range: TextRange::default(),
})),
slice: Box::new(if new_exprs.len() > 1 {
Expr::Tuple(ast::ExprTuple {
node_index: Default::default(),
elts: new_exprs.to_vec(),
range: TextRange::default(),
ctx: ExprContext::Load,

View File

@ -11,7 +11,7 @@ PYI051 `Literal["foo"]` is redundant in a union with `str`
5 | B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
|
= help: Replace `Literal["foo"] | str` with `str`
help: Replace `Literal["foo"] | str` with `str`
PYI051 `Literal[b"bar"]` is redundant in a union with `bytes`
--> PYI051.py:5:37
@ -22,7 +22,7 @@ PYI051 `Literal[b"bar"]` is redundant in a union with `bytes`
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
|
= help: Replace `typing.Union[Literal[b"bar"], bytes]` with `bytes`
help: Replace `typing.Union[Literal[b"bar"], bytes]` with `bytes`
PYI051 `Literal[b"foo"]` is redundant in a union with `bytes`
--> PYI051.py:5:45
@ -33,7 +33,7 @@ PYI051 `Literal[b"foo"]` is redundant in a union with `bytes`
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
|
= help: Replace `typing.Union[Literal[b"foo"], bytes]` with `bytes`
help: Replace `typing.Union[Literal[b"foo"], bytes]` with `bytes`
PYI051 `Literal[5]` is redundant in a union with `int`
--> PYI051.py:6:37
@ -45,7 +45,7 @@ PYI051 `Literal[5]` is redundant in a union with `int`
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
= help: Replace `typing.Union[Literal[5], int]` with `int`
help: Replace `typing.Union[Literal[5], int]` with `int`
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.py:6:67
@ -57,7 +57,7 @@ PYI051 `Literal["foo"]` is redundant in a union with `str`
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
= help: Replace `typing.Union[Literal["foo"], str]` with `str`
help: Replace `typing.Union[Literal["foo"], str]` with `str`
PYI051 `Literal[b"str_bytes"]` is redundant in a union with `bytes`
--> PYI051.py:7:37
@ -69,7 +69,7 @@ PYI051 `Literal[b"str_bytes"]` is redundant in a union with `bytes`
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
= help: Replace `typing.Union[Literal[b"str_bytes"], bytes]` with `bytes`
help: Replace `typing.Union[Literal[b"str_bytes"], bytes]` with `bytes`
PYI051 `Literal[42]` is redundant in a union with `int`
--> PYI051.py:7:51
@ -81,7 +81,7 @@ PYI051 `Literal[42]` is redundant in a union with `int`
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
= help: Replace `typing.Union[Literal[42], int]` with `int`
help: Replace `typing.Union[Literal[42], int]` with `int`
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.py:8:76
@ -93,7 +93,7 @@ PYI051 `Literal["foo"]` is redundant in a union with `str`
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
= help: Replace `typing.Union[Literal["foo"], str]` with `str`
help: Replace `typing.Union[Literal["foo"], str]` with `str`
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.py:9:81
@ -104,7 +104,7 @@ PYI051 `Literal["foo"]` is redundant in a union with `str`
| ^^^^^
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
= help: Replace `typing.Union[Literal["foo"], str]` with `str`
help: Replace `typing.Union[Literal["foo"], str]` with `str`
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.py:10:69
@ -116,7 +116,7 @@ PYI051 `Literal["foo"]` is redundant in a union with `str`
11 |
12 | def func(x: complex | Literal[1J], y: Union[Literal[3.14], float]): ...
|
= help: Replace `typing.Union[Literal["foo"], str]` with `str`
help: Replace `typing.Union[Literal["foo"], str]` with `str`
PYI051 `Literal[1J]` is redundant in a union with `complex`
--> PYI051.py:12:31
@ -128,7 +128,7 @@ PYI051 `Literal[1J]` is redundant in a union with `complex`
13 |
14 | # OK
|
= help: Replace `Literal[1J] | complex` with `complex`
help: Replace `Literal[1J] | complex` with `complex`
PYI051 `Literal[3.14]` is redundant in a union with `float`
--> PYI051.py:12:53
@ -140,4 +140,4 @@ PYI051 `Literal[3.14]` is redundant in a union with `float`
13 |
14 | # OK
|
= help: Replace `typing.Union[Literal[3.14], float]` with `float`
help: Replace `typing.Union[Literal[3.14], float]` with `float`

View File

@ -0,0 +1,144 @@
---
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
assertion_line: 137
---
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.pyi:4:18
|
2 | from typing import Literal, TypeAlias, Union
3 |
4 | A: str | Literal["foo"]
| ^^^^^
5 | B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
|
help: Replace `Literal["foo"] | str` with `str`
PYI051 `Literal[b"bar"]` is redundant in a union with `bytes`
--> PYI051.pyi:5:37
|
4 | A: str | Literal["foo"]
5 | B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
| ^^^^^^
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
|
help: Replace `typing.Union[Literal[b"bar"], bytes]` with `bytes`
PYI051 `Literal[b"foo"]` is redundant in a union with `bytes`
--> PYI051.pyi:5:45
|
4 | A: str | Literal["foo"]
5 | B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
| ^^^^^^
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
|
help: Replace `typing.Union[Literal[b"foo"], bytes]` with `bytes`
PYI051 `Literal[5]` is redundant in a union with `int`
--> PYI051.pyi:6:37
|
4 | A: str | Literal["foo"]
5 | B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
| ^
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
help: Replace `typing.Union[Literal[5], int]` with `int`
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.pyi:6:67
|
4 | A: str | Literal["foo"]
5 | B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
| ^^^^^
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
|
help: Replace `typing.Union[Literal["foo"], str]` with `str`
PYI051 `Literal[b"str_bytes"]` is redundant in a union with `bytes`
--> PYI051.pyi:7:37
|
5 | B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
| ^^^^^^^^^^^^
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
help: Replace `typing.Union[Literal[b"str_bytes"], bytes]` with `bytes`
PYI051 `Literal[42]` is redundant in a union with `int`
--> PYI051.pyi:7:51
|
5 | B: TypeAlias = typing.Union[Literal[b"bar", b"foo"], bytes, str]
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
| ^^
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
help: Replace `typing.Union[Literal[42], int]` with `int`
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.pyi:8:76
|
6 | C: TypeAlias = typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
| ^^^^^
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
help: Replace `typing.Union[Literal["foo"], str]` with `str`
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.pyi:9:81
|
7 | D: TypeAlias = typing.Union[Literal[b"str_bytes", 42], bytes, int]
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
| ^^^^^
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
|
help: Replace `typing.Union[Literal["foo"], str]` with `str`
PYI051 `Literal["foo"]` is redundant in a union with `str`
--> PYI051.pyi:10:69
|
8 | E: TypeAlias = typing.Union[typing.Union[typing.Union[typing.Union[Literal["foo"], str]]]]
9 | F: TypeAlias = typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
| ^^^^^
11 |
12 | def func(x: complex | Literal[1J], y: Union[Literal[3.14], float]): ...
|
help: Replace `typing.Union[Literal["foo"], str]` with `str`
PYI051 `Literal[1J]` is redundant in a union with `complex`
--> PYI051.pyi:12:31
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
11 |
12 | def func(x: complex | Literal[1J], y: Union[Literal[3.14], float]): ...
| ^^
13 |
14 | # OK
|
help: Replace `Literal[1J] | complex` with `complex`
PYI051 `Literal[3.14]` is redundant in a union with `float`
--> PYI051.pyi:12:53
|
10 | G: typing.Union[str, typing.Union[typing.Union[typing.Union[Literal["foo"], int]]]]
11 |
12 | def func(x: complex | Literal[1J], y: Union[Literal[3.14], float]): ...
| ^^^^
13 |
14 | # OK
|
help: Replace `typing.Union[Literal[3.14], float]` with `float`