Skip to content

Commit 3728d5b

Browse files
[pyupgrade] Fix UP043 to apply to collections.abc.Generator and collections.abc.AsyncGenerator (#13611)
## Summary fix #13602 Currently, `UP043` only applies to typing.Generator, but it should also support collections.abc.Generator. This update ensures `UP043` correctly handles both `collections.abc.Generator` and `collections.abc.AsyncGenerator` ### UP043 > `UP043` > Python 3.13 introduced the ability for type parameters to specify default values. As such, the default type arguments for some types in the standard library (e.g., Generator, AsyncGenerator) are now optional. > Omitting type parameters that match the default values can make the code more concise and easier to read. ```py Generator[int, None, None] -> Generator[int] ```
1 parent 7e3894f commit 3728d5b

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

Diff for: crates/ruff_linter/resources/test/fixtures/pyupgrade/UP043.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Generator, AsyncGenerator
1+
from collections.abc import Generator, AsyncGenerator
22

33

44
def func() -> Generator[int, None, None]:
@@ -39,3 +39,14 @@ async def func() -> AsyncGenerator[int]:
3939
async def func() -> AsyncGenerator[int, int]:
4040
foo = yield 42
4141
return foo
42+
43+
44+
from typing import Generator, AsyncGenerator
45+
46+
47+
def func() -> Generator[str, None, None]:
48+
yield "hello"
49+
50+
51+
async def func() -> AsyncGenerator[str, None]:
52+
yield "hello"

Diff for: crates/ruff_linter/src/rules/pyupgrade/rules/unnecessary_default_type_args.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::checkers::ast::Checker;
1919
/// ## Examples
2020
///
2121
/// ```python
22-
/// from typing import Generator, AsyncGenerator
22+
/// from collections.abc import Generator, AsyncGenerator
2323
///
2424
///
2525
/// def sync_gen() -> Generator[int, None, None]:
@@ -33,7 +33,7 @@ use crate::checkers::ast::Checker;
3333
/// Use instead:
3434
///
3535
/// ```python
36-
/// from typing import Generator, AsyncGenerator
36+
/// from collections.abc import Generator, AsyncGenerator
3737
///
3838
///
3939
/// def sync_gen() -> Generator[int]:
@@ -47,6 +47,7 @@ use crate::checkers::ast::Checker;
4747
/// ## References
4848
///
4949
/// - [PEP 696 – Type Defaults for Type Parameters](https://peps.python.org/pep-0696/)
50+
/// - [Annotating generators and coroutines](https://docs.python.org/3.13/library/typing.html#annotating-generators-and-coroutines)
5051
/// - [typing.Generator](https://docs.python.org/3.13/library/typing.html#typing.Generator)
5152
/// - [typing.AsyncGenerator](https://docs.python.org/3.13/library/typing.html#typing.AsyncGenerator)
5253
#[violation]
@@ -140,9 +141,20 @@ impl DefaultedTypeAnnotation {
140141
/// includes default type arguments.
141142
fn from_expr(expr: &Expr, semantic: &ruff_python_semantic::SemanticModel) -> Option<Self> {
142143
let qualified_name = semantic.resolve_qualified_name(expr)?;
143-
if semantic.match_typing_qualified_name(&qualified_name, "Generator") {
144+
145+
if semantic.match_typing_qualified_name(&qualified_name, "Generator")
146+
|| matches!(
147+
qualified_name.segments(),
148+
["collections", "abc", "Generator"]
149+
)
150+
{
144151
Some(Self::Generator)
145-
} else if semantic.match_typing_qualified_name(&qualified_name, "AsyncGenerator") {
152+
} else if semantic.match_typing_qualified_name(&qualified_name, "AsyncGenerator")
153+
|| matches!(
154+
qualified_name.segments(),
155+
["collections", "abc", "AsyncGenerator"]
156+
)
157+
{
146158
Some(Self::AsyncGenerator)
147159
} else {
148160
None

Diff for: crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP043.py.snap

+36-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ UP043.py:4:15: UP043 [*] Unnecessary default type arguments
1010
= help: Remove default type arguments
1111

1212
Safe fix
13-
1 1 | from typing import Generator, AsyncGenerator
13+
1 1 | from collections.abc import Generator, AsyncGenerator
1414
2 2 |
1515
3 3 |
1616
4 |-def func() -> Generator[int, None, None]:
@@ -72,4 +72,38 @@ UP043.py:31:21: UP043 [*] Unnecessary default type arguments
7272
31 |+async def func() -> AsyncGenerator[int]:
7373
32 32 | yield 42
7474
33 33 |
75-
34 34 |
75+
34 34 |
76+
77+
UP043.py:47:15: UP043 [*] Unnecessary default type arguments
78+
|
79+
47 | def func() -> Generator[str, None, None]:
80+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP043
81+
48 | yield "hello"
82+
|
83+
= help: Remove default type arguments
84+
85+
Safe fix
86+
44 44 | from typing import Generator, AsyncGenerator
87+
45 45 |
88+
46 46 |
89+
47 |-def func() -> Generator[str, None, None]:
90+
47 |+def func() -> Generator[str]:
91+
48 48 | yield "hello"
92+
49 49 |
93+
50 50 |
94+
95+
UP043.py:51:21: UP043 [*] Unnecessary default type arguments
96+
|
97+
51 | async def func() -> AsyncGenerator[str, None]:
98+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ UP043
99+
52 | yield "hello"
100+
|
101+
= help: Remove default type arguments
102+
103+
Safe fix
104+
48 48 | yield "hello"
105+
49 49 |
106+
50 50 |
107+
51 |-async def func() -> AsyncGenerator[str, None]:
108+
51 |+async def func() -> AsyncGenerator[str]:
109+
52 52 | yield "hello"

0 commit comments

Comments
 (0)