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
59 changes: 59 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/pyupgrade/UP043.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from collections.abc import Generator, AsyncGenerator


def func() -> Generator[int, None, None]:
yield 42


def func() -> Generator[int, None]:
yield 42


def func() -> Generator[int]:
yield 42


def func() -> Generator[int, int, int]:
foo = yield 42
return foo


def func() -> Generator[int, int, None]:
_ = yield 42
return None


def func() -> Generator[int, None, int]:
yield 42
return 42


async def func() -> AsyncGenerator[int, None]:
yield 42


async def func() -> AsyncGenerator[int]:
yield 42


async def func() -> AsyncGenerator[int, int]:
foo = yield 42
return foo


from typing import Generator, AsyncGenerator


def func() -> Generator[str, None, None]:
yield "hello"


async def func() -> AsyncGenerator[str, None]:
yield "hello"


async def func() -> AsyncGenerator[ # type: ignore
str,
None
]:
yield "hello"
6 changes: 5 additions & 1 deletion crates/ruff_linter/src/checkers/ast/analyze/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
use crate::preview::{
is_assert_raises_exception_call_enabled, is_optional_as_none_in_union_enabled,
is_unnecessary_default_type_args_stubs_enabled,
};
use crate::registry::Rule;
use crate::rules::{
Expand Down Expand Up @@ -142,7 +143,10 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
}

if checker.is_rule_enabled(Rule::UnnecessaryDefaultTypeArgs) {
if checker.target_version() >= PythonVersion::PY313 {
if checker.target_version() >= PythonVersion::PY313
|| is_unnecessary_default_type_args_stubs_enabled(checker.settings())
&& checker.semantic().in_stub_file()
{
pyupgrade::rules::unnecessary_default_type_args(checker, expr);
}
}
Expand Down
7 changes: 7 additions & 0 deletions crates/ruff_linter/src/preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,10 @@ pub(crate) const fn is_maxsplit_without_separator_fix_enabled(settings: &LinterS
pub(crate) const fn is_bidi_forbid_arabic_letter_mark_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}

// https://github.com/astral-sh/ruff/pull/20027
pub(crate) const fn is_unnecessary_default_type_args_stubs_enabled(
settings: &LinterSettings,
) -> bool {
settings.preview.is_enabled()
}
15 changes: 15 additions & 0 deletions crates/ruff_linter/src/rules/pyupgrade/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,19 @@ mod tests {
2 | from pipes import quote, Template
");
}

#[test]
fn unnecessary_default_type_args_stubs_py312_preview() -> Result<()> {
let snapshot = format!("{}__preview", "UP043.pyi");
let diagnostics = test_path(
Path::new("pyupgrade/UP043.pyi"),
&settings::LinterSettings {
preview: PreviewMode::Enabled,
unresolved_target_version: PythonVersion::PY312.into(),
..settings::LinterSettings::for_rule(Rule::UnnecessaryDefaultTypeArgs)
},
)?;
assert_diagnostics!(snapshot, diagnostics);
Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{AlwaysFixableViolation, Applicability, Edit, Fix};
/// ## What it does
/// Checks for unnecessary default type arguments for `Generator` and
/// `AsyncGenerator` on Python 3.13+.
/// In [preview], this rule will also apply to stub files.
///
/// ## Why is this bad?
/// Python 3.13 introduced the ability for type parameters to specify default
Expand Down Expand Up @@ -59,6 +60,8 @@ use crate::{AlwaysFixableViolation, Applicability, Edit, Fix};
/// - [Annotating generators and coroutines](https://docs.python.org/3/library/typing.html#annotating-generators-and-coroutines)
/// - [Python documentation: `typing.Generator`](https://docs.python.org/3/library/typing.html#typing.Generator)
/// - [Python documentation: `typing.AsyncGenerator`](https://docs.python.org/3/library/typing.html#typing.AsyncGenerator)
///
/// [preview]: https://docs.astral.sh/ruff/preview/
#[derive(ViolationMetadata)]
pub(crate) struct UnnecessaryDefaultTypeArgs;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
---
UP043 [*] Unnecessary default type arguments
--> UP043.pyi:4:15
|
4 | def func() -> Generator[int, None, None]:
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
5 | yield 42
|
help: Remove default type arguments
1 | from collections.abc import Generator, AsyncGenerator
2 |
3 |
- def func() -> Generator[int, None, None]:
4 + def func() -> Generator[int]:
5 | yield 42
6 |
7 |

UP043 [*] Unnecessary default type arguments
--> UP043.pyi:8:15
|
8 | def func() -> Generator[int, None]:
| ^^^^^^^^^^^^^^^^^^^^
9 | yield 42
|
help: Remove default type arguments
5 | yield 42
6 |
7 |
- def func() -> Generator[int, None]:
8 + def func() -> Generator[int]:
9 | yield 42
10 |
11 |

UP043 [*] Unnecessary default type arguments
--> UP043.pyi:21:15
|
21 | def func() -> Generator[int, int, None]:
| ^^^^^^^^^^^^^^^^^^^^^^^^^
22 | _ = yield 42
23 | return None
|
help: Remove default type arguments
18 | return foo
19 |
20 |
- def func() -> Generator[int, int, None]:
21 + def func() -> Generator[int, int]:
22 | _ = yield 42
23 | return None
24 |

UP043 [*] Unnecessary default type arguments
--> UP043.pyi:31:21
|
31 | async def func() -> AsyncGenerator[int, None]:
| ^^^^^^^^^^^^^^^^^^^^^^^^^
32 | yield 42
|
help: Remove default type arguments
28 | return 42
29 |
30 |
- async def func() -> AsyncGenerator[int, None]:
31 + async def func() -> AsyncGenerator[int]:
32 | yield 42
33 |
34 |

UP043 [*] Unnecessary default type arguments
--> UP043.pyi:47:15
|
47 | def func() -> Generator[str, None, None]:
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
48 | yield "hello"
|
help: Remove default type arguments
44 | from typing import Generator, AsyncGenerator
45 |
46 |
- def func() -> Generator[str, None, None]:
47 + def func() -> Generator[str]:
48 | yield "hello"
49 |
50 |

UP043 [*] Unnecessary default type arguments
--> UP043.pyi:51:21
|
51 | async def func() -> AsyncGenerator[str, None]:
| ^^^^^^^^^^^^^^^^^^^^^^^^^
52 | yield "hello"
|
help: Remove default type arguments
48 | yield "hello"
49 |
50 |
- async def func() -> AsyncGenerator[str, None]:
51 + async def func() -> AsyncGenerator[str]:
52 | yield "hello"
53 |
54 |

UP043 [*] Unnecessary default type arguments
--> UP043.pyi:55:21
|
55 | async def func() -> AsyncGenerator[ # type: ignore
| _____________________^
56 | | str,
57 | | None
58 | | ]:
| |_^
59 | yield "hello"
|
help: Remove default type arguments
52 | yield "hello"
53 |
54 |
- async def func() -> AsyncGenerator[ # type: ignore
- str,
- None
- ]:
55 + async def func() -> AsyncGenerator[str]:
56 | yield "hello"
note: This is an unsafe fix and may change runtime behavior