Skip to content

Commit 9a3a354

Browse files
dylwil3ntBre
authored andcommitted
[pyupgrade] Stabilize non-pep604-annotation-optional (UP045) and preview behavior for non-pep604-annotation-union (UP007) (#18505)
1 parent b8365e9 commit 9a3a354

8 files changed

+45
-73
lines changed

crates/ruff_linter/src/codes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
549549
(Pyupgrade, "042") => (RuleGroup::Preview, rules::pyupgrade::rules::ReplaceStrEnum),
550550
(Pyupgrade, "043") => (RuleGroup::Stable, rules::pyupgrade::rules::UnnecessaryDefaultTypeArgs),
551551
(Pyupgrade, "044") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP646Unpack),
552-
(Pyupgrade, "045") => (RuleGroup::Preview, rules::pyupgrade::rules::NonPEP604AnnotationOptional),
552+
(Pyupgrade, "045") => (RuleGroup::Stable, rules::pyupgrade::rules::NonPEP604AnnotationOptional),
553553
(Pyupgrade, "046") => (RuleGroup::Preview, rules::pyupgrade::rules::NonPEP695GenericClass),
554554
(Pyupgrade, "047") => (RuleGroup::Preview, rules::pyupgrade::rules::NonPEP695GenericFunction),
555555
(Pyupgrade, "049") => (RuleGroup::Stable, rules::pyupgrade::rules::PrivateTypeParameter),

crates/ruff_linter/src/preview.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,6 @@ pub(crate) const fn is_dunder_init_fix_unused_import_enabled(settings: &LinterSe
6161
settings.preview.is_enabled()
6262
}
6363

64-
// https://github.com/astral-sh/ruff/pull/15313
65-
pub(crate) const fn is_defer_optional_to_up045_enabled(settings: &LinterSettings) -> bool {
66-
settings.preview.is_enabled()
67-
}
68-
6964
// https://github.com/astral-sh/ruff/pull/8473
7065
pub(crate) const fn is_unicode_to_unicode_confusables_enabled(settings: &LinterSettings) -> bool {
7166
settings.preview.is_enabled()

crates/ruff_linter/src/rules/pyupgrade/mod.rs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ mod tests {
1515

1616
use crate::registry::Rule;
1717
use crate::rules::pyupgrade;
18-
use crate::settings::types::PreviewMode;
18+
1919
use crate::test::test_path;
2020
use crate::{assert_messages, settings};
2121

@@ -43,7 +43,7 @@ mod tests {
4343
#[test_case(Rule::NonPEP585Annotation, Path::new("UP006_2.py"))]
4444
#[test_case(Rule::NonPEP585Annotation, Path::new("UP006_3.py"))]
4545
#[test_case(Rule::NonPEP604AnnotationUnion, Path::new("UP007.py"))]
46-
#[test_case(Rule::NonPEP604AnnotationUnion, Path::new("UP045.py"))]
46+
#[test_case(Rule::NonPEP604AnnotationOptional, Path::new("UP045.py"))]
4747
#[test_case(Rule::NonPEP604Isinstance, Path::new("UP038.py"))]
4848
#[test_case(Rule::OSErrorAlias, Path::new("UP024_0.py"))]
4949
#[test_case(Rule::OSErrorAlias, Path::new("UP024_1.py"))]
@@ -122,19 +122,6 @@ mod tests {
122122
Ok(())
123123
}
124124

125-
#[test]
126-
fn up007_preview() -> Result<()> {
127-
let diagnostics = test_path(
128-
Path::new("pyupgrade/UP045.py"),
129-
&settings::LinterSettings {
130-
preview: PreviewMode::Enabled,
131-
..settings::LinterSettings::for_rule(Rule::NonPEP604AnnotationUnion)
132-
},
133-
)?;
134-
assert_messages!(diagnostics);
135-
Ok(())
136-
}
137-
138125
#[test]
139126
fn async_timeout_error_alias_not_applied_py310() -> Result<()> {
140127
let diagnostics = test_path(

crates/ruff_linter/src/rules/pyupgrade/rules/use_pep604_annotation.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use ruff_text_size::Ranged;
88
use crate::checkers::ast::Checker;
99
use crate::codes::Rule;
1010
use crate::fix::edits::pad;
11-
use crate::preview::is_defer_optional_to_up045_enabled;
1211
use crate::{Applicability, Edit, Fix, FixAvailability, Violation};
1312

1413
/// ## What it does
@@ -39,8 +38,7 @@ use crate::{Applicability, Edit, Fix, FixAvailability, Violation};
3938
/// foo: int | str = 1
4039
/// ```
4140
///
42-
/// ## Preview
43-
/// In preview mode, this rule only checks for usages of `typing.Union`,
41+
/// Note that this rule only checks for usages of `typing.Union`,
4442
/// while `UP045` checks for `typing.Optional`.
4543
///
4644
/// ## Fix safety
@@ -149,11 +147,8 @@ pub(crate) fn non_pep604_annotation(
149147

150148
match operator {
151149
Pep604Operator::Optional => {
152-
let guard = if is_defer_optional_to_up045_enabled(checker.settings) {
153-
checker.report_diagnostic_if_enabled(NonPEP604AnnotationOptional, expr.range())
154-
} else {
155-
checker.report_diagnostic_if_enabled(NonPEP604AnnotationUnion, expr.range())
156-
};
150+
let guard =
151+
checker.report_diagnostic_if_enabled(NonPEP604AnnotationOptional, expr.range());
157152

158153
let Some(mut diagnostic) = guard else {
159154
return;
Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
22
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
33
---
4-
UP045.py:5:10: UP007 [*] Use `X | Y` for type annotations
4+
UP045.py:5:10: UP045 [*] Use `X | None` for type annotations
55
|
66
5 | def f(x: Optional[str]) -> None:
7-
| ^^^^^^^^^^^^^ UP007
7+
| ^^^^^^^^^^^^^ UP045
88
6 | ...
99
|
10-
= help: Convert to `X | Y`
10+
= help: Convert to `X | None`
1111

1212
Safe fix
1313
2 2 | from typing import Optional
@@ -19,13 +19,13 @@ UP045.py:5:10: UP007 [*] Use `X | Y` for type annotations
1919
7 7 |
2020
8 8 |
2121

22-
UP045.py:9:10: UP007 [*] Use `X | Y` for type annotations
22+
UP045.py:9:10: UP045 [*] Use `X | None` for type annotations
2323
|
2424
9 | def f(x: typing.Optional[str]) -> None:
25-
| ^^^^^^^^^^^^^^^^^^^^ UP007
25+
| ^^^^^^^^^^^^^^^^^^^^ UP045
2626
10 | ...
2727
|
28-
= help: Convert to `X | Y`
28+
= help: Convert to `X | None`
2929

3030
Safe fix
3131
6 6 | ...
@@ -37,14 +37,14 @@ UP045.py:9:10: UP007 [*] Use `X | Y` for type annotations
3737
11 11 |
3838
12 12 |
3939

40-
UP045.py:14:8: UP007 [*] Use `X | Y` for type annotations
40+
UP045.py:14:8: UP045 [*] Use `X | None` for type annotations
4141
|
4242
13 | def f() -> None:
4343
14 | x: Optional[str]
44-
| ^^^^^^^^^^^^^ UP007
44+
| ^^^^^^^^^^^^^ UP045
4545
15 | x = Optional[str]
4646
|
47-
= help: Convert to `X | Y`
47+
= help: Convert to `X | None`
4848

4949
Safe fix
5050
11 11 |
@@ -56,22 +56,22 @@ UP045.py:14:8: UP007 [*] Use `X | Y` for type annotations
5656
16 16 |
5757
17 17 |
5858

59-
UP045.py:15:9: UP007 Use `X | Y` for type annotations
59+
UP045.py:15:9: UP045 Use `X | None` for type annotations
6060
|
6161
13 | def f() -> None:
6262
14 | x: Optional[str]
6363
15 | x = Optional[str]
64-
| ^^^^^^^^^^^^^ UP007
64+
| ^^^^^^^^^^^^^ UP045
6565
|
66-
= help: Convert to `X | Y`
66+
= help: Convert to `X | None`
6767

68-
UP045.py:18:15: UP007 [*] Use `X | Y` for type annotations
68+
UP045.py:18:15: UP045 [*] Use `X | None` for type annotations
6969
|
7070
18 | def f(x: list[Optional[int]]) -> None:
71-
| ^^^^^^^^^^^^^ UP007
71+
| ^^^^^^^^^^^^^ UP045
7272
19 | ...
7373
|
74-
= help: Convert to `X | Y`
74+
= help: Convert to `X | None`
7575

7676
Safe fix
7777
15 15 | x = Optional[str]
@@ -83,31 +83,31 @@ UP045.py:18:15: UP007 [*] Use `X | Y` for type annotations
8383
20 20 |
8484
21 21 |
8585

86-
UP045.py:22:10: UP007 Use `X | Y` for type annotations
86+
UP045.py:22:10: UP045 Use `X | None` for type annotations
8787
|
8888
22 | def f(x: Optional[int : float]) -> None:
89-
| ^^^^^^^^^^^^^^^^^^^^^ UP007
89+
| ^^^^^^^^^^^^^^^^^^^^^ UP045
9090
23 | ...
9191
|
92-
= help: Convert to `X | Y`
92+
= help: Convert to `X | None`
9393

94-
UP045.py:26:10: UP007 Use `X | Y` for type annotations
94+
UP045.py:26:10: UP045 Use `X | None` for type annotations
9595
|
9696
26 | def f(x: Optional[str, int : float]) -> None:
97-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP007
97+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP045
9898
27 | ...
9999
|
100-
= help: Convert to `X | Y`
100+
= help: Convert to `X | None`
101101

102-
UP045.py:30:10: UP007 Use `X | Y` for type annotations
102+
UP045.py:30:10: UP045 Use `X | None` for type annotations
103103
|
104104
30 | def f(x: Optional[int, float]) -> None:
105-
| ^^^^^^^^^^^^^^^^^^^^ UP007
105+
| ^^^^^^^^^^^^^^^^^^^^ UP045
106106
31 | ...
107107
|
108-
= help: Convert to `X | Y`
108+
= help: Convert to `X | None`
109109

110-
UP045.py:36:28: UP007 [*] Use `X | Y` for type annotations
110+
UP045.py:36:28: UP045 [*] Use `X | None` for type annotations
111111
|
112112
34 | # Regression test for: https://github.com/astral-sh/ruff/issues/7131
113113
35 | class ServiceRefOrValue:
@@ -116,9 +116,9 @@ UP045.py:36:28: UP007 [*] Use `X | Y` for type annotations
116116
37 | | list[ServiceSpecificationRef]
117117
38 | | | list[ServiceSpecification]
118118
39 | | ] = None
119-
| |_____^ UP007
119+
| |_____^ UP045
120120
|
121-
= help: Convert to `X | Y`
121+
= help: Convert to `X | None`
122122

123123
Safe fix
124124
33 33 |
@@ -133,14 +133,14 @@ UP045.py:36:28: UP007 [*] Use `X | Y` for type annotations
133133
41 38 |
134134
42 39 | # Regression test for: https://github.com/astral-sh/ruff/issues/7201
135135

136-
UP045.py:44:28: UP007 [*] Use `X | Y` for type annotations
136+
UP045.py:44:28: UP045 [*] Use `X | None` for type annotations
137137
|
138138
42 | # Regression test for: https://github.com/astral-sh/ruff/issues/7201
139139
43 | class ServiceRefOrValue:
140140
44 | service_specification: Optional[str]is not True = None
141-
| ^^^^^^^^^^^^^ UP007
141+
| ^^^^^^^^^^^^^ UP045
142142
|
143-
= help: Convert to `X | Y`
143+
= help: Convert to `X | None`
144144

145145
Safe fix
146146
41 41 |
@@ -152,11 +152,11 @@ UP045.py:44:28: UP007 [*] Use `X | Y` for type annotations
152152
46 46 |
153153
47 47 | # Test for: https://github.com/astral-sh/ruff/issues/18508
154154

155-
UP045.py:49:6: UP007 Use `X | Y` for type annotations
155+
UP045.py:49:6: UP045 Use `X | None` for type annotations
156156
|
157157
47 | # Test for: https://github.com/astral-sh/ruff/issues/18508
158158
48 | # Optional[None] should not be offered a fix
159159
49 | foo: Optional[None] = None
160-
| ^^^^^^^^^^^^^^ UP007
160+
| ^^^^^^^^^^^^^^ UP045
161161
|
162-
= help: Convert to `X | Y`
162+
= help: Convert to `X | None`

crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__future_annotations_pep_604_p37.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
22
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
33
---
4-
future_annotations.py:40:4: UP007 [*] Use `X | Y` for type annotations
4+
future_annotations.py:40:4: UP045 [*] Use `X | None` for type annotations
55
|
66
40 | x: Optional[int] = None
7-
| ^^^^^^^^^^^^^ UP007
7+
| ^^^^^^^^^^^^^ UP045
88
41 |
99
42 | MyList: TypeAlias = Union[List[int], List[str]]
1010
|
11-
= help: Convert to `X | Y`
11+
= help: Convert to `X | None`
1212

1313
Unsafe fix
1414
37 37 | return y

crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__future_annotations_pep_604_py310.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
22
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
33
---
4-
future_annotations.py:40:4: UP007 [*] Use `X | Y` for type annotations
4+
future_annotations.py:40:4: UP045 [*] Use `X | None` for type annotations
55
|
66
40 | x: Optional[int] = None
7-
| ^^^^^^^^^^^^^ UP007
7+
| ^^^^^^^^^^^^^ UP045
88
41 |
99
42 | MyList: TypeAlias = Union[List[int], List[str]]
1010
|
11-
= help: Convert to `X | Y`
11+
= help: Convert to `X | None`
1212

1313
Safe fix
1414
37 37 | return y

crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__up007_preview.snap

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)