mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 18:28:24 +00:00
[flake8-pyi
] Always autofix duplicate-union-members
(PYI016
) (#14270)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz (push) Blocked by required conditions
CI / Fuzz the parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz (push) Blocked by required conditions
CI / Fuzz the parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
This commit is contained in:
parent
0eb36e4345
commit
eb55b9b5a0
3 changed files with 190 additions and 517 deletions
|
@ -1,15 +1,19 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use ruff_python_ast::name::Name;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_diagnostics::{Applicability, Diagnostic, Edit, Fix, FixAvailability, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::comparable::ComparableExpr;
|
||||
use ruff_python_ast::{self as ast, Expr};
|
||||
use ruff_python_ast::{Expr, ExprBinOp, ExprContext, ExprName, ExprSubscript, ExprTuple, Operator};
|
||||
use ruff_python_semantic::analyze::typing::traverse_union;
|
||||
use ruff_text_size::Ranged;
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::importer::ImportRequest;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for duplicate union members.
|
||||
|
@ -27,6 +31,12 @@ use crate::checkers::ast::Checker;
|
|||
/// foo: str
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// This rule's fix is marked as safe unless the union contains comments.
|
||||
///
|
||||
/// For nested union, the fix will flatten type expressions into a single
|
||||
/// top-level union.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `typing.Union`](https://docs.python.org/3/library/typing.html#typing.Union)
|
||||
#[violation]
|
||||
|
@ -53,37 +63,152 @@ impl Violation for DuplicateUnionMember {
|
|||
/// PYI016
|
||||
pub(crate) fn duplicate_union_member<'a>(checker: &mut Checker, expr: &'a Expr) {
|
||||
let mut seen_nodes: HashSet<ComparableExpr<'_>, _> = FxHashSet::default();
|
||||
let mut unique_nodes: Vec<&Expr> = Vec::new();
|
||||
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
||||
|
||||
let mut union_type = UnionKind::TypingUnion;
|
||||
// Adds a member to `literal_exprs` if it is a `Literal` annotation
|
||||
let mut check_for_duplicate_members = |expr: &'a Expr, parent: &'a Expr| {
|
||||
if matches!(parent, Expr::BinOp(_)) {
|
||||
union_type = UnionKind::PEP604;
|
||||
}
|
||||
|
||||
// If we've already seen this union member, raise a violation.
|
||||
if !seen_nodes.insert(expr.into()) {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
if seen_nodes.insert(expr.into()) {
|
||||
unique_nodes.push(expr);
|
||||
} else {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
DuplicateUnionMember {
|
||||
duplicate_name: checker.generator().expr(expr),
|
||||
},
|
||||
expr.range(),
|
||||
);
|
||||
// Delete the "|" character as well as the duplicate value by reconstructing the
|
||||
// parent without the duplicate.
|
||||
|
||||
// If the parent node is not a `BinOp` we will not perform a fix
|
||||
if let Expr::BinOp(ast::ExprBinOp { left, right, .. }) = parent {
|
||||
// Replace the parent with its non-duplicate child.
|
||||
let child = if expr == left.as_ref() { right } else { left };
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
checker.locator().slice(child.as_ref()).to_string(),
|
||||
parent.range(),
|
||||
)));
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
// Traverse the union, collect all diagnostic members
|
||||
traverse_union(&mut check_for_duplicate_members, checker.semantic(), expr);
|
||||
|
||||
if diagnostics.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
if checker.settings.preview.is_enabled() {
|
||||
// Mark [`Fix`] as unsafe when comments are in range.
|
||||
let applicability = if checker.comment_ranges().intersects(expr.range()) {
|
||||
Applicability::Unsafe
|
||||
} else {
|
||||
Applicability::Safe
|
||||
};
|
||||
|
||||
// Generate the flattened fix once.
|
||||
let fix = if let &[edit_expr] = unique_nodes.as_slice() {
|
||||
// Generate a [`Fix`] for a single type expression, e.g. `int`.
|
||||
Some(Fix::applicable_edit(
|
||||
Edit::range_replacement(checker.generator().expr(edit_expr), expr.range()),
|
||||
applicability,
|
||||
))
|
||||
} else {
|
||||
match union_type {
|
||||
// See redundant numeric union
|
||||
UnionKind::PEP604 => Some(generate_pep604_fix(
|
||||
checker,
|
||||
unique_nodes,
|
||||
expr,
|
||||
applicability,
|
||||
)),
|
||||
UnionKind::TypingUnion => {
|
||||
generate_union_fix(checker, unique_nodes, expr, applicability).ok()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(fix) = fix {
|
||||
for diagnostic in &mut diagnostics {
|
||||
diagnostic.set_fix(fix.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add all diagnostics to the checker
|
||||
checker.diagnostics.append(&mut diagnostics);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum UnionKind {
|
||||
/// E.g., `typing.Union[int, str]`
|
||||
TypingUnion,
|
||||
/// E.g., `int | str`
|
||||
PEP604,
|
||||
}
|
||||
|
||||
// Generate a [`Fix`] for two or more type expressions, e.g. `int | float | complex`.
|
||||
fn generate_pep604_fix(
|
||||
checker: &Checker,
|
||||
nodes: Vec<&Expr>,
|
||||
annotation: &Expr,
|
||||
applicability: Applicability,
|
||||
) -> Fix {
|
||||
debug_assert!(nodes.len() >= 2, "At least two nodes required");
|
||||
|
||||
let new_expr = nodes
|
||||
.into_iter()
|
||||
.fold(None, |acc: Option<Expr>, right: &Expr| {
|
||||
if let Some(left) = acc {
|
||||
Some(Expr::BinOp(ExprBinOp {
|
||||
left: Box::new(left),
|
||||
op: Operator::BitOr,
|
||||
right: Box::new(right.clone()),
|
||||
range: TextRange::default(),
|
||||
}))
|
||||
} else {
|
||||
Some(right.clone())
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Fix::applicable_edit(
|
||||
Edit::range_replacement(checker.generator().expr(&new_expr), annotation.range()),
|
||||
applicability,
|
||||
)
|
||||
}
|
||||
|
||||
// Generate a [`Fix`] for two or more type expresisons, e.g. `typing.Union[int, float, complex]`.
|
||||
fn generate_union_fix(
|
||||
checker: &Checker,
|
||||
nodes: Vec<&Expr>,
|
||||
annotation: &Expr,
|
||||
applicability: Applicability,
|
||||
) -> Result<Fix> {
|
||||
debug_assert!(nodes.len() >= 2, "At least two nodes required");
|
||||
|
||||
// Request `typing.Union`
|
||||
let (import_edit, binding) = checker.importer().get_or_import_symbol(
|
||||
&ImportRequest::import_from("typing", "Union"),
|
||||
annotation.start(),
|
||||
checker.semantic(),
|
||||
)?;
|
||||
|
||||
// Construct the expression as `Subscript[typing.Union, Tuple[expr, [expr, ...]]]`
|
||||
let new_expr = Expr::Subscript(ExprSubscript {
|
||||
range: TextRange::default(),
|
||||
value: Box::new(Expr::Name(ExprName {
|
||||
id: Name::new(binding),
|
||||
ctx: ExprContext::Store,
|
||||
range: TextRange::default(),
|
||||
})),
|
||||
slice: Box::new(Expr::Tuple(ExprTuple {
|
||||
elts: nodes.into_iter().cloned().collect(),
|
||||
range: TextRange::default(),
|
||||
ctx: ExprContext::Load,
|
||||
parenthesized: false,
|
||||
})),
|
||||
ctx: ExprContext::Load,
|
||||
});
|
||||
|
||||
Ok(Fix::applicable_edits(
|
||||
Edit::range_replacement(checker.generator().expr(&new_expr), annotation.range()),
|
||||
[import_edit],
|
||||
applicability,
|
||||
))
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI016.py:7:15: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.py:7:15: PYI016 Duplicate union member `str`
|
||||
|
|
||||
6 | # Should emit for duplicate field types.
|
||||
7 | field2: str | str # PYI016: Duplicate union member `str`
|
||||
|
@ -11,17 +11,7 @@ PYI016.py:7:15: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 | field1: str
|
||||
5 5 |
|
||||
6 6 | # Should emit for duplicate field types.
|
||||
7 |-field2: str | str # PYI016: Duplicate union member `str`
|
||||
7 |+field2: str # PYI016: Duplicate union member `str`
|
||||
8 8 |
|
||||
9 9 | # Should emit for union types in arguments.
|
||||
10 10 | def func1(arg1: int | int): # PYI016: Duplicate union member `int`
|
||||
|
||||
PYI016.py:10:23: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:10:23: PYI016 Duplicate union member `int`
|
||||
|
|
||||
9 | # Should emit for union types in arguments.
|
||||
10 | def func1(arg1: int | int): # PYI016: Duplicate union member `int`
|
||||
|
@ -30,17 +20,7 @@ PYI016.py:10:23: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
7 7 | field2: str | str # PYI016: Duplicate union member `str`
|
||||
8 8 |
|
||||
9 9 | # Should emit for union types in arguments.
|
||||
10 |-def func1(arg1: int | int): # PYI016: Duplicate union member `int`
|
||||
10 |+def func1(arg1: int): # PYI016: Duplicate union member `int`
|
||||
11 11 | print(arg1)
|
||||
12 12 |
|
||||
13 13 | # Should emit for unions in return types.
|
||||
|
||||
PYI016.py:14:22: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.py:14:22: PYI016 Duplicate union member `str`
|
||||
|
|
||||
13 | # Should emit for unions in return types.
|
||||
14 | def func2() -> str | str: # PYI016: Duplicate union member `str`
|
||||
|
@ -49,17 +29,7 @@ PYI016.py:14:22: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
11 11 | print(arg1)
|
||||
12 12 |
|
||||
13 13 | # Should emit for unions in return types.
|
||||
14 |-def func2() -> str | str: # PYI016: Duplicate union member `str`
|
||||
14 |+def func2() -> str: # PYI016: Duplicate union member `str`
|
||||
15 15 | return "my string"
|
||||
16 16 |
|
||||
17 17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
|
||||
PYI016.py:18:15: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.py:18:15: PYI016 Duplicate union member `str`
|
||||
|
|
||||
17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
|
@ -69,17 +39,7 @@ PYI016.py:18:15: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
15 15 | return "my string"
|
||||
16 16 |
|
||||
17 17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 |-field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
18 |+field3: str | int # PYI016: Duplicate union member `str`
|
||||
19 19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
20 20 | field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int`
|
||||
|
||||
PYI016.py:19:15: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:19:15: PYI016 Duplicate union member `int`
|
||||
|
|
||||
17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
|
@ -90,17 +50,7 @@ PYI016.py:19:15: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
16 16 |
|
||||
17 17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
19 |-field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
19 |+field4: int | str # PYI016: Duplicate union member `int`
|
||||
20 20 | field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int`
|
||||
22 22 |
|
||||
|
||||
PYI016.py:20:21: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.py:20:21: PYI016 Duplicate union member `str`
|
||||
|
|
||||
18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
|
@ -110,17 +60,7 @@ PYI016.py:20:21: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
17 17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
19 19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
20 |-field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
20 |+field5: str | int # PYI016: Duplicate union member `str`
|
||||
21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int`
|
||||
22 22 |
|
||||
23 23 | # Shouldn't emit for non-type unions.
|
||||
|
||||
PYI016.py:21:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:21:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
20 | field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
|
@ -131,17 +71,7 @@ PYI016.py:21:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
18 18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
19 19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
20 20 | field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
21 |-field6: int | bool | str | int # PYI016: Duplicate union member `int`
|
||||
21 |+field6: int | bool | str # PYI016: Duplicate union member `int`
|
||||
22 22 |
|
||||
23 23 | # Shouldn't emit for non-type unions.
|
||||
24 24 | field7 = str | str
|
||||
|
||||
PYI016.py:27:22: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:27:22: PYI016 Duplicate union member `int`
|
||||
|
|
||||
26 | # Should emit for strangely-bracketed unions.
|
||||
27 | field8: int | (str | int) # PYI016: Duplicate union member `int`
|
||||
|
@ -151,17 +81,7 @@ PYI016.py:27:22: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
24 24 | field7 = str | str
|
||||
25 25 |
|
||||
26 26 | # Should emit for strangely-bracketed unions.
|
||||
27 |-field8: int | (str | int) # PYI016: Duplicate union member `int`
|
||||
27 |+field8: int | (str) # PYI016: Duplicate union member `int`
|
||||
28 28 |
|
||||
29 29 | # Should handle user brackets when fixing.
|
||||
30 30 | field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
|
||||
PYI016.py:30:16: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:30:16: PYI016 Duplicate union member `int`
|
||||
|
|
||||
29 | # Should handle user brackets when fixing.
|
||||
30 | field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
|
@ -170,17 +90,7 @@ PYI016.py:30:16: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
27 27 | field8: int | (str | int) # PYI016: Duplicate union member `int`
|
||||
28 28 |
|
||||
29 29 | # Should handle user brackets when fixing.
|
||||
30 |-field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
30 |+field9: int | (str) # PYI016: Duplicate union member `int`
|
||||
31 31 | field10: (str | int) | str # PYI016: Duplicate union member `str`
|
||||
32 32 |
|
||||
33 33 | # Should emit for nested unions.
|
||||
|
||||
PYI016.py:31:24: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.py:31:24: PYI016 Duplicate union member `str`
|
||||
|
|
||||
29 | # Should handle user brackets when fixing.
|
||||
30 | field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
|
@ -191,17 +101,7 @@ PYI016.py:31:24: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
28 28 |
|
||||
29 29 | # Should handle user brackets when fixing.
|
||||
30 30 | field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
31 |-field10: (str | int) | str # PYI016: Duplicate union member `str`
|
||||
31 |+field10: str | int # PYI016: Duplicate union member `str`
|
||||
32 32 |
|
||||
33 33 | # Should emit for nested unions.
|
||||
34 34 | field11: dict[int | int, str]
|
||||
|
||||
PYI016.py:34:21: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:34:21: PYI016 Duplicate union member `int`
|
||||
|
|
||||
33 | # Should emit for nested unions.
|
||||
34 | field11: dict[int | int, str]
|
||||
|
@ -211,17 +111,7 @@ PYI016.py:34:21: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
31 31 | field10: (str | int) | str # PYI016: Duplicate union member `str`
|
||||
32 32 |
|
||||
33 33 | # Should emit for nested unions.
|
||||
34 |-field11: dict[int | int, str]
|
||||
34 |+field11: dict[int, str]
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 37 | field12: int | int | int # Error
|
||||
|
||||
PYI016.py:37:16: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:37:16: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -230,17 +120,7 @@ PYI016.py:37:16: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
34 34 | field11: dict[int | int, str]
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 |-field12: int | int | int # Error
|
||||
37 |+field12: int | int # Error
|
||||
38 38 | field13: int | int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
|
||||
PYI016.py:37:22: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:37:22: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -249,17 +129,7 @@ PYI016.py:37:22: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
34 34 | field11: dict[int | int, str]
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 |-field12: int | int | int # Error
|
||||
37 |+field12: int | int # Error
|
||||
38 38 | field13: int | int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
|
||||
PYI016.py:38:16: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:38:16: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -270,17 +140,7 @@ PYI016.py:38:16: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 37 | field12: int | int | int # Error
|
||||
38 |-field13: int | int | int | int # Error
|
||||
38 |+field13: int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 41 | field14: int | int | str | int # Error
|
||||
|
||||
PYI016.py:38:22: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:38:22: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -291,17 +151,7 @@ PYI016.py:38:22: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 37 | field12: int | int | int # Error
|
||||
38 |-field13: int | int | int | int # Error
|
||||
38 |+field13: int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 41 | field14: int | int | str | int # Error
|
||||
|
||||
PYI016.py:38:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:38:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -312,17 +162,7 @@ PYI016.py:38:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 37 | field12: int | int | int # Error
|
||||
38 |-field13: int | int | int | int # Error
|
||||
38 |+field13: int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 41 | field14: int | int | str | int # Error
|
||||
|
||||
PYI016.py:41:16: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:41:16: PYI016 Duplicate union member `int`
|
||||
|
|
||||
40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 | field14: int | int | str | int # Error
|
||||
|
@ -332,17 +172,7 @@ PYI016.py:41:16: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
38 38 | field13: int | int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 |-field14: int | int | str | int # Error
|
||||
41 |+field14: int | str | int # Error
|
||||
42 42 |
|
||||
43 43 | # Should emit for duplicate literal types; also covered by PYI030
|
||||
44 44 | field15: typing.Literal[1] | typing.Literal[1] # Error
|
||||
|
||||
PYI016.py:41:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:41:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 | field14: int | int | str | int # Error
|
||||
|
@ -352,17 +182,7 @@ PYI016.py:41:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
38 38 | field13: int | int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 |-field14: int | int | str | int # Error
|
||||
41 |+field14: int | int | str # Error
|
||||
42 42 |
|
||||
43 43 | # Should emit for duplicate literal types; also covered by PYI030
|
||||
44 44 | field15: typing.Literal[1] | typing.Literal[1] # Error
|
||||
|
||||
PYI016.py:44:30: PYI016 [*] Duplicate union member `typing.Literal[1]`
|
||||
PYI016.py:44:30: PYI016 Duplicate union member `typing.Literal[1]`
|
||||
|
|
||||
43 | # Should emit for duplicate literal types; also covered by PYI030
|
||||
44 | field15: typing.Literal[1] | typing.Literal[1] # Error
|
||||
|
@ -372,16 +192,6 @@ PYI016.py:44:30: PYI016 [*] Duplicate union member `typing.Literal[1]`
|
|||
|
|
||||
= help: Remove duplicate union member `typing.Literal[1]`
|
||||
|
||||
ℹ Safe fix
|
||||
41 41 | field14: int | int | str | int # Error
|
||||
42 42 |
|
||||
43 43 | # Should emit for duplicate literal types; also covered by PYI030
|
||||
44 |-field15: typing.Literal[1] | typing.Literal[1] # Error
|
||||
44 |+field15: typing.Literal[1] # Error
|
||||
45 45 |
|
||||
46 46 | # Shouldn't emit if in new parent type
|
||||
47 47 | field16: int | dict[int, str] # OK
|
||||
|
||||
PYI016.py:57:5: PYI016 Duplicate union member `set[int]`
|
||||
|
|
||||
55 | int # foo
|
||||
|
@ -415,7 +225,7 @@ PYI016.py:66:41: PYI016 Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
PYI016.py:69:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:69:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
68 | # Should emit in cases with mixed `typing.Union` and `|`
|
||||
69 | field21: typing.Union[int, int | str] # Error
|
||||
|
@ -425,16 +235,6 @@ PYI016.py:69:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
66 66 | field20: typing.Union[int, typing.Union[int, str]] # Error
|
||||
67 67 |
|
||||
68 68 | # Should emit in cases with mixed `typing.Union` and `|`
|
||||
69 |-field21: typing.Union[int, int | str] # Error
|
||||
69 |+field21: typing.Union[int, str] # Error
|
||||
70 70 |
|
||||
71 71 | # Should emit only once in cases with multiple nested `typing.Union`
|
||||
72 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error
|
||||
|
||||
PYI016.py:72:41: PYI016 Duplicate union member `int`
|
||||
|
|
||||
71 | # Should emit only once in cases with multiple nested `typing.Union`
|
||||
|
@ -465,7 +265,7 @@ PYI016.py:72:64: PYI016 Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
PYI016.py:76:12: PYI016 [*] Duplicate union member `set[int]`
|
||||
PYI016.py:76:12: PYI016 Duplicate union member `set[int]`
|
||||
|
|
||||
74 | # Should emit in cases with newlines
|
||||
75 | field23: set[ # foo
|
||||
|
@ -476,16 +276,6 @@ PYI016.py:76:12: PYI016 [*] Duplicate union member `set[int]`
|
|||
|
|
||||
= help: Remove duplicate union member `set[int]`
|
||||
|
||||
ℹ Safe fix
|
||||
73 73 |
|
||||
74 74 | # Should emit in cases with newlines
|
||||
75 75 | field23: set[ # foo
|
||||
76 |- int] | set[int]
|
||||
76 |+ int]
|
||||
77 77 |
|
||||
78 78 | # Should emit twice (once for each `int` in the nested union, both of which are
|
||||
79 79 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
|
||||
PYI016.py:81:41: PYI016 Duplicate union member `int`
|
||||
|
|
||||
79 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
|
@ -508,7 +298,7 @@ PYI016.py:81:46: PYI016 Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
PYI016.py:86:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:86:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
84 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
85 | # we incorrectly re-checked the nested union).
|
||||
|
@ -517,14 +307,7 @@ PYI016.py:86:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
83 83 | # Should emit twice (once for each `int` in the nested union, both of which are
|
||||
84 84 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
85 85 | # we incorrectly re-checked the nested union).
|
||||
86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`
|
||||
86 |+field25: typing.Union[int, int] # PYI016: Duplicate union member `int`
|
||||
|
||||
PYI016.py:86:34: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.py:86:34: PYI016 Duplicate union member `int`
|
||||
|
|
||||
84 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
85 | # we incorrectly re-checked the nested union).
|
||||
|
@ -532,12 +315,3 @@ PYI016.py:86:34: PYI016 [*] Duplicate union member `int`
|
|||
| ^^^ PYI016
|
||||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
83 83 | # Should emit twice (once for each `int` in the nested union, both of which are
|
||||
84 84 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
85 85 | # we incorrectly re-checked the nested union).
|
||||
86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`
|
||||
86 |+field25: typing.Union[int, int] # PYI016: Duplicate union member `int`
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI016.pyi:7:15: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.pyi:7:15: PYI016 Duplicate union member `str`
|
||||
|
|
||||
6 | # Should emit for duplicate field types.
|
||||
7 | field2: str | str # PYI016: Duplicate union member `str`
|
||||
|
@ -11,17 +11,7 @@ PYI016.pyi:7:15: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 | field1: str
|
||||
5 5 |
|
||||
6 6 | # Should emit for duplicate field types.
|
||||
7 |-field2: str | str # PYI016: Duplicate union member `str`
|
||||
7 |+field2: str # PYI016: Duplicate union member `str`
|
||||
8 8 |
|
||||
9 9 | # Should emit for union types in arguments.
|
||||
10 10 | def func1(arg1: int | int): # PYI016: Duplicate union member `int`
|
||||
|
||||
PYI016.pyi:10:23: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:10:23: PYI016 Duplicate union member `int`
|
||||
|
|
||||
9 | # Should emit for union types in arguments.
|
||||
10 | def func1(arg1: int | int): # PYI016: Duplicate union member `int`
|
||||
|
@ -30,17 +20,7 @@ PYI016.pyi:10:23: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
7 7 | field2: str | str # PYI016: Duplicate union member `str`
|
||||
8 8 |
|
||||
9 9 | # Should emit for union types in arguments.
|
||||
10 |-def func1(arg1: int | int): # PYI016: Duplicate union member `int`
|
||||
10 |+def func1(arg1: int): # PYI016: Duplicate union member `int`
|
||||
11 11 | print(arg1)
|
||||
12 12 |
|
||||
13 13 | # Should emit for unions in return types.
|
||||
|
||||
PYI016.pyi:14:22: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.pyi:14:22: PYI016 Duplicate union member `str`
|
||||
|
|
||||
13 | # Should emit for unions in return types.
|
||||
14 | def func2() -> str | str: # PYI016: Duplicate union member `str`
|
||||
|
@ -49,17 +29,7 @@ PYI016.pyi:14:22: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
11 11 | print(arg1)
|
||||
12 12 |
|
||||
13 13 | # Should emit for unions in return types.
|
||||
14 |-def func2() -> str | str: # PYI016: Duplicate union member `str`
|
||||
14 |+def func2() -> str: # PYI016: Duplicate union member `str`
|
||||
15 15 | return "my string"
|
||||
16 16 |
|
||||
17 17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
|
||||
PYI016.pyi:18:15: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.pyi:18:15: PYI016 Duplicate union member `str`
|
||||
|
|
||||
17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
|
@ -69,17 +39,7 @@ PYI016.pyi:18:15: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
15 15 | return "my string"
|
||||
16 16 |
|
||||
17 17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 |-field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
18 |+field3: str | int # PYI016: Duplicate union member `str`
|
||||
19 19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
20 20 | field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int`
|
||||
|
||||
PYI016.pyi:19:15: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:19:15: PYI016 Duplicate union member `int`
|
||||
|
|
||||
17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
|
@ -90,17 +50,7 @@ PYI016.pyi:19:15: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
16 16 |
|
||||
17 17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
19 |-field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
19 |+field4: int | str # PYI016: Duplicate union member `int`
|
||||
20 20 | field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int`
|
||||
22 22 |
|
||||
|
||||
PYI016.pyi:20:21: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.pyi:20:21: PYI016 Duplicate union member `str`
|
||||
|
|
||||
18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
|
@ -110,17 +60,7 @@ PYI016.pyi:20:21: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
17 17 | # Should emit in longer unions, even if not directly adjacent.
|
||||
18 18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
19 19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
20 |-field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
20 |+field5: str | int # PYI016: Duplicate union member `str`
|
||||
21 21 | field6: int | bool | str | int # PYI016: Duplicate union member `int`
|
||||
22 22 |
|
||||
23 23 | # Shouldn't emit for non-type unions.
|
||||
|
||||
PYI016.pyi:21:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:21:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
20 | field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
|
@ -131,17 +71,7 @@ PYI016.pyi:21:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
18 18 | field3: str | str | int # PYI016: Duplicate union member `str`
|
||||
19 19 | field4: int | int | str # PYI016: Duplicate union member `int`
|
||||
20 20 | field5: str | int | str # PYI016: Duplicate union member `str`
|
||||
21 |-field6: int | bool | str | int # PYI016: Duplicate union member `int`
|
||||
21 |+field6: int | bool | str # PYI016: Duplicate union member `int`
|
||||
22 22 |
|
||||
23 23 | # Shouldn't emit for non-type unions.
|
||||
24 24 | field7 = str | str
|
||||
|
||||
PYI016.pyi:27:22: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:27:22: PYI016 Duplicate union member `int`
|
||||
|
|
||||
26 | # Should emit for strangely-bracketed unions.
|
||||
27 | field8: int | (str | int) # PYI016: Duplicate union member `int`
|
||||
|
@ -151,17 +81,7 @@ PYI016.pyi:27:22: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
24 24 | field7 = str | str
|
||||
25 25 |
|
||||
26 26 | # Should emit for strangely-bracketed unions.
|
||||
27 |-field8: int | (str | int) # PYI016: Duplicate union member `int`
|
||||
27 |+field8: int | (str) # PYI016: Duplicate union member `int`
|
||||
28 28 |
|
||||
29 29 | # Should handle user brackets when fixing.
|
||||
30 30 | field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
|
||||
PYI016.pyi:30:16: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:30:16: PYI016 Duplicate union member `int`
|
||||
|
|
||||
29 | # Should handle user brackets when fixing.
|
||||
30 | field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
|
@ -170,17 +90,7 @@ PYI016.pyi:30:16: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
27 27 | field8: int | (str | int) # PYI016: Duplicate union member `int`
|
||||
28 28 |
|
||||
29 29 | # Should handle user brackets when fixing.
|
||||
30 |-field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
30 |+field9: int | (str) # PYI016: Duplicate union member `int`
|
||||
31 31 | field10: (str | int) | str # PYI016: Duplicate union member `str`
|
||||
32 32 |
|
||||
33 33 | # Should emit for nested unions.
|
||||
|
||||
PYI016.pyi:31:24: PYI016 [*] Duplicate union member `str`
|
||||
PYI016.pyi:31:24: PYI016 Duplicate union member `str`
|
||||
|
|
||||
29 | # Should handle user brackets when fixing.
|
||||
30 | field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
|
@ -191,17 +101,7 @@ PYI016.pyi:31:24: PYI016 [*] Duplicate union member `str`
|
|||
|
|
||||
= help: Remove duplicate union member `str`
|
||||
|
||||
ℹ Safe fix
|
||||
28 28 |
|
||||
29 29 | # Should handle user brackets when fixing.
|
||||
30 30 | field9: int | (int | str) # PYI016: Duplicate union member `int`
|
||||
31 |-field10: (str | int) | str # PYI016: Duplicate union member `str`
|
||||
31 |+field10: str | int # PYI016: Duplicate union member `str`
|
||||
32 32 |
|
||||
33 33 | # Should emit for nested unions.
|
||||
34 34 | field11: dict[int | int, str]
|
||||
|
||||
PYI016.pyi:34:21: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:34:21: PYI016 Duplicate union member `int`
|
||||
|
|
||||
33 | # Should emit for nested unions.
|
||||
34 | field11: dict[int | int, str]
|
||||
|
@ -211,17 +111,7 @@ PYI016.pyi:34:21: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
31 31 | field10: (str | int) | str # PYI016: Duplicate union member `str`
|
||||
32 32 |
|
||||
33 33 | # Should emit for nested unions.
|
||||
34 |-field11: dict[int | int, str]
|
||||
34 |+field11: dict[int, str]
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 37 | field12: int | int | int # Error
|
||||
|
||||
PYI016.pyi:37:16: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:37:16: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -230,17 +120,7 @@ PYI016.pyi:37:16: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
34 34 | field11: dict[int | int, str]
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 |-field12: int | int | int # Error
|
||||
37 |+field12: int | int # Error
|
||||
38 38 | field13: int | int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
|
||||
PYI016.pyi:37:22: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:37:22: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -249,17 +129,7 @@ PYI016.pyi:37:22: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
34 34 | field11: dict[int | int, str]
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 |-field12: int | int | int # Error
|
||||
37 |+field12: int | int # Error
|
||||
38 38 | field13: int | int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
|
||||
PYI016.pyi:38:16: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:38:16: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -270,17 +140,7 @@ PYI016.pyi:38:16: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 37 | field12: int | int | int # Error
|
||||
38 |-field13: int | int | int | int # Error
|
||||
38 |+field13: int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 41 | field14: int | int | str | int # Error
|
||||
|
||||
PYI016.pyi:38:22: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:38:22: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -291,17 +151,7 @@ PYI016.pyi:38:22: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 37 | field12: int | int | int # Error
|
||||
38 |-field13: int | int | int | int # Error
|
||||
38 |+field13: int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 41 | field14: int | int | str | int # Error
|
||||
|
||||
PYI016.pyi:38:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:38:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
36 | # Should emit for unions with more than two cases
|
||||
37 | field12: int | int | int # Error
|
||||
|
@ -312,17 +162,7 @@ PYI016.pyi:38:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
35 35 |
|
||||
36 36 | # Should emit for unions with more than two cases
|
||||
37 37 | field12: int | int | int # Error
|
||||
38 |-field13: int | int | int | int # Error
|
||||
38 |+field13: int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 41 | field14: int | int | str | int # Error
|
||||
|
||||
PYI016.pyi:41:16: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:41:16: PYI016 Duplicate union member `int`
|
||||
|
|
||||
40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 | field14: int | int | str | int # Error
|
||||
|
@ -332,17 +172,7 @@ PYI016.pyi:41:16: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
38 38 | field13: int | int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 |-field14: int | int | str | int # Error
|
||||
41 |+field14: int | str | int # Error
|
||||
42 42 |
|
||||
43 43 | # Should emit for duplicate literal types; also covered by PYI030
|
||||
44 44 | field15: typing.Literal[1] | typing.Literal[1] # Error
|
||||
|
||||
PYI016.pyi:41:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:41:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 | field14: int | int | str | int # Error
|
||||
|
@ -352,17 +182,7 @@ PYI016.pyi:41:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
38 38 | field13: int | int | int | int # Error
|
||||
39 39 |
|
||||
40 40 | # Should emit for unions with more than two cases, even if not directly adjacent
|
||||
41 |-field14: int | int | str | int # Error
|
||||
41 |+field14: int | int | str # Error
|
||||
42 42 |
|
||||
43 43 | # Should emit for duplicate literal types; also covered by PYI030
|
||||
44 44 | field15: typing.Literal[1] | typing.Literal[1] # Error
|
||||
|
||||
PYI016.pyi:44:30: PYI016 [*] Duplicate union member `typing.Literal[1]`
|
||||
PYI016.pyi:44:30: PYI016 Duplicate union member `typing.Literal[1]`
|
||||
|
|
||||
43 | # Should emit for duplicate literal types; also covered by PYI030
|
||||
44 | field15: typing.Literal[1] | typing.Literal[1] # Error
|
||||
|
@ -372,16 +192,6 @@ PYI016.pyi:44:30: PYI016 [*] Duplicate union member `typing.Literal[1]`
|
|||
|
|
||||
= help: Remove duplicate union member `typing.Literal[1]`
|
||||
|
||||
ℹ Safe fix
|
||||
41 41 | field14: int | int | str | int # Error
|
||||
42 42 |
|
||||
43 43 | # Should emit for duplicate literal types; also covered by PYI030
|
||||
44 |-field15: typing.Literal[1] | typing.Literal[1] # Error
|
||||
44 |+field15: typing.Literal[1] # Error
|
||||
45 45 |
|
||||
46 46 | # Shouldn't emit if in new parent type
|
||||
47 47 | field16: int | dict[int, str] # OK
|
||||
|
||||
PYI016.pyi:57:5: PYI016 Duplicate union member `set[int]`
|
||||
|
|
||||
55 | int # foo
|
||||
|
@ -415,7 +225,7 @@ PYI016.pyi:66:41: PYI016 Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
PYI016.pyi:69:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:69:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
68 | # Should emit in cases with mixed `typing.Union` and `|`
|
||||
69 | field21: typing.Union[int, int | str] # Error
|
||||
|
@ -425,16 +235,6 @@ PYI016.pyi:69:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
66 66 | field20: typing.Union[int, typing.Union[int, str]] # Error
|
||||
67 67 |
|
||||
68 68 | # Should emit in cases with mixed `typing.Union` and `|`
|
||||
69 |-field21: typing.Union[int, int | str] # Error
|
||||
69 |+field21: typing.Union[int, str] # Error
|
||||
70 70 |
|
||||
71 71 | # Should emit only once in cases with multiple nested `typing.Union`
|
||||
72 72 | field22: typing.Union[int, typing.Union[int, typing.Union[int, int]]] # Error
|
||||
|
||||
PYI016.pyi:72:41: PYI016 Duplicate union member `int`
|
||||
|
|
||||
71 | # Should emit only once in cases with multiple nested `typing.Union`
|
||||
|
@ -465,7 +265,7 @@ PYI016.pyi:72:64: PYI016 Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
PYI016.pyi:76:12: PYI016 [*] Duplicate union member `set[int]`
|
||||
PYI016.pyi:76:12: PYI016 Duplicate union member `set[int]`
|
||||
|
|
||||
74 | # Should emit in cases with newlines
|
||||
75 | field23: set[ # foo
|
||||
|
@ -476,16 +276,6 @@ PYI016.pyi:76:12: PYI016 [*] Duplicate union member `set[int]`
|
|||
|
|
||||
= help: Remove duplicate union member `set[int]`
|
||||
|
||||
ℹ Safe fix
|
||||
73 73 |
|
||||
74 74 | # Should emit in cases with newlines
|
||||
75 75 | field23: set[ # foo
|
||||
76 |- int] | set[int]
|
||||
76 |+ int]
|
||||
77 77 |
|
||||
78 78 | # Should emit twice (once for each `int` in the nested union, both of which are
|
||||
79 79 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
|
||||
PYI016.pyi:81:41: PYI016 Duplicate union member `int`
|
||||
|
|
||||
79 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
|
@ -508,7 +298,7 @@ PYI016.pyi:81:46: PYI016 Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
PYI016.pyi:86:28: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:86:28: PYI016 Duplicate union member `int`
|
||||
|
|
||||
84 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
85 | # we incorrectly re-checked the nested union).
|
||||
|
@ -517,14 +307,7 @@ PYI016.pyi:86:28: PYI016 [*] Duplicate union member `int`
|
|||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
83 83 | # Should emit twice (once for each `int` in the nested union, both of which are
|
||||
84 84 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
85 85 | # we incorrectly re-checked the nested union).
|
||||
86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`
|
||||
86 |+field25: typing.Union[int, int] # PYI016: Duplicate union member `int`
|
||||
|
||||
PYI016.pyi:86:34: PYI016 [*] Duplicate union member `int`
|
||||
PYI016.pyi:86:34: PYI016 Duplicate union member `int`
|
||||
|
|
||||
84 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
85 | # we incorrectly re-checked the nested union).
|
||||
|
@ -532,12 +315,3 @@ PYI016.pyi:86:34: PYI016 [*] Duplicate union member `int`
|
|||
| ^^^ PYI016
|
||||
|
|
||||
= help: Remove duplicate union member `int`
|
||||
|
||||
ℹ Safe fix
|
||||
83 83 | # Should emit twice (once for each `int` in the nested union, both of which are
|
||||
84 84 | # duplicates of the outer `int`), but not three times (which would indicate that
|
||||
85 85 | # we incorrectly re-checked the nested union).
|
||||
86 |-field25: typing.Union[int, int | int] # PYI016: Duplicate union member `int`
|
||||
86 |+field25: typing.Union[int, int] # PYI016: Duplicate union member `int`
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue