Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,12 @@ def func2() -> str | str: # PYI016: Duplicate union member `str`

# Test case for mixed union type
field34: typing.Union[list[int], str] | typing.Union[bytes, list[int]] # Error

field35: "int | str | int" # Error



# Technically, this falls into the domain of the rule but it is an unlikely edge case,
# only works if you have from `__future__ import annotations` at the top of the file,
# and stringified annotations are discouraged in stub files.
field36: "int | str" | int # Ok
Original file line number Diff line number Diff line change
Expand Up @@ -93,40 +93,38 @@ pub(crate) fn duplicate_union_member<'a>(checker: &mut Checker, expr: &'a Expr)
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()),
// Mark [`Fix`] as unsafe when comments are in range.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like #14270 incorrectly removed the fix for non-preview 🤷 So, technically, this PR makes the rule fixable again

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hehe, onwards and upwards!

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,
))
} 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()
}
)),
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());
}
if let Some(fix) = fix {
for diagnostic in &mut diagnostics {
diagnostic.set_fix(fix.clone());
}
}

Expand Down
Loading