Skip to content

Commit

Permalink
Move rule to pyupgrade, test based on Python version
Browse files Browse the repository at this point in the history
  • Loading branch information
zanieb committed Aug 3, 2023
1 parent 8fd002c commit fed82c3
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import typing
from typing import TypeAlias

# RUF017
# UP100
x: typing.TypeAlias = int
x: TypeAlias = int


# RUF017 with generics (todo)
# UP100 with generics (todo)
T = typing.TypeVar["T"]
x: typing.TypeAlias = list[T]

Expand Down
4 changes: 2 additions & 2 deletions crates/ruff/src/checkers/ast/analyze/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1376,8 +1376,8 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
stmt,
);
}
if checker.enabled(Rule::TypeAliasAnnotation) {
ruff::rules::type_alias_annotation(checker, assign_stmt);
if checker.enabled(Rule::NonPEP695TypeAlias) {
pyupgrade::rules::non_pep695_type_alias(checker, assign_stmt);
}
if checker.is_stub {
if let Some(value) = value {
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff/src/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Pyupgrade, "037") => (RuleGroup::Unspecified, rules::pyupgrade::rules::QuotedAnnotation),
(Pyupgrade, "038") => (RuleGroup::Unspecified, rules::pyupgrade::rules::NonPEP604Isinstance),
(Pyupgrade, "039") => (RuleGroup::Unspecified, rules::pyupgrade::rules::UnnecessaryClassParentheses),
(Pyupgrade, "100") => (RuleGroup::Unspecified, rules::pyupgrade::rules::NonPEP695TypeAlias),

// pydocstyle
(Pydocstyle, "100") => (RuleGroup::Unspecified, rules::pydocstyle::rules::UndocumentedPublicModule),
Expand Down Expand Up @@ -807,7 +808,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Ruff, "014") => (RuleGroup::Nursery, rules::ruff::rules::UnreachableCode),
(Ruff, "015") => (RuleGroup::Unspecified, rules::ruff::rules::UnnecessaryIterableAllocationForFirstElement),
(Ruff, "016") => (RuleGroup::Unspecified, rules::ruff::rules::InvalidIndexType),
(Ruff, "017") => (RuleGroup::Unspecified, rules::ruff::rules::TypeAliasAnnotation),
(Ruff, "100") => (RuleGroup::Unspecified, rules::ruff::rules::UnusedNOQA),
(Ruff, "200") => (RuleGroup::Unspecified, rules::ruff::rules::InvalidPyprojectToml),

Expand Down
2 changes: 1 addition & 1 deletion crates/ruff/src/rules/pyflakes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3422,7 +3422,7 @@ mod tests {
}

#[test]
fn type_alias_annotations() {
fn use_pep695_type_aliass() {
flakes(
r#"
from typing_extensions import TypeAlias
Expand Down
26 changes: 26 additions & 0 deletions crates/ruff/src/rules/pyupgrade/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,32 @@ mod tests {
Ok(())
}

#[test]
fn non_pep695_type_alias_not_applied_py311() -> Result<()> {
let diagnostics = test_path(
Path::new("pyupgrade/UP100.py"),
&settings::Settings {
target_version: PythonVersion::Py311,
..settings::Settings::for_rule(Rule::NonPEP695TypeAlias)
},
)?;
assert_messages!(diagnostics);
Ok(())
}

#[test]
fn non_pep695_type_alias_py312() -> Result<()> {
let diagnostics = test_path(
Path::new("pyupgrade/UP100.py"),
&settings::Settings {
target_version: PythonVersion::Py312,
..settings::Settings::for_rule(Rule::NonPEP695TypeAlias)
},
)?;
assert_messages!(diagnostics);
Ok(())
}

#[test]
fn future_annotations_keep_runtime_typing_p37() -> Result<()> {
let diagnostics = test_path(
Expand Down
2 changes: 2 additions & 0 deletions crates/ruff/src/rules/pyupgrade/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub(crate) use unpacked_list_comprehension::*;
pub(crate) use use_pep585_annotation::*;
pub(crate) use use_pep604_annotation::*;
pub(crate) use use_pep604_isinstance::*;
pub(crate) use use_pep695_type_alias::*;
pub(crate) use useless_metaclass_type::*;
pub(crate) use useless_object_inheritance::*;
pub(crate) use yield_in_for_loop::*;
Expand Down Expand Up @@ -70,6 +71,7 @@ mod unpacked_list_comprehension;
mod use_pep585_annotation;
mod use_pep604_annotation;
mod use_pep604_isinstance;
mod use_pep695_type_alias;
mod useless_metaclass_type;
mod useless_object_inheritance;
mod yield_in_for_loop;
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@ use crate::checkers::ast::Checker;
/// type ListOfInt = list[int]
/// ```
#[violation]
pub struct TypeAliasAnnotation {
pub struct NonPEP695TypeAlias {
name: String,
}

impl Violation for TypeAliasAnnotation {
impl Violation for NonPEP695TypeAlias {
const AUTOFIX: AutofixKind = AutofixKind::Always;

#[derive_message_formats]
fn message(&self) -> String {
let TypeAliasAnnotation { name } = self;
format!("Type alias `{name}` uses `TypeAlias` annotation instead of the `type` keyword.")
let NonPEP695TypeAlias { name } = self;
format!("Type alias `{name}` uses `TypeAlias` annotation instead of the `type` keyword")
}

fn autofix_title(&self) -> Option<String> {
Some("Use the `type` keyword instead".to_string())
Some("Replace with the `type` keyword".to_string())
}
}

/// RUF017
pub(crate) fn type_alias_annotation(checker: &mut Checker, stmt: &StmtAnnAssign) {
/// UP100
pub(crate) fn non_pep695_type_alias(checker: &mut Checker, stmt: &StmtAnnAssign) {
let StmtAnnAssign {
target,
annotation,
Expand Down Expand Up @@ -71,9 +71,9 @@ pub(crate) fn type_alias_annotation(checker: &mut Checker, stmt: &StmtAnnAssign)
return;
};

// todo(zanie): We should check for generic type variables used in the value and define them
// TODO(zanie): We should check for generic type variables used in the value and define them
// as type params instead
let mut diagnostic = Diagnostic::new(TypeAliasAnnotation { name: name.clone() }, stmt.range());
let mut diagnostic = Diagnostic::new(NonPEP695TypeAlias { name: name.clone() }, stmt.range());
if checker.patch(diagnostic.kind.rule()) {
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
checker.generator().stmt(&Stmt::from(StmtTypeAlias {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
source: crates/ruff/src/rules/pyupgrade/mod.rs
---

Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
source: crates/ruff/src/rules/pyupgrade/mod.rs
---
UP100.py:5:1: UP100 [*] Type alias `x` uses `TypeAlias` annotation instead of the `type` keyword
|
4 | # UP100
5 | x: typing.TypeAlias = int
| ^^^^^^^^^^^^^^^^^^^^^^^^^ UP100
6 | x: TypeAlias = int
|
= help: Replace with the `type` keyword

Fix
2 2 | from typing import TypeAlias
3 3 |
4 4 | # UP100
5 |-x: typing.TypeAlias = int
5 |+type x = int
6 6 | x: TypeAlias = int
7 7 |
8 8 |

UP100.py:6:1: UP100 [*] Type alias `x` uses `TypeAlias` annotation instead of the `type` keyword
|
4 | # UP100
5 | x: typing.TypeAlias = int
6 | x: TypeAlias = int
| ^^^^^^^^^^^^^^^^^^ UP100
|
= help: Replace with the `type` keyword
ℹ Fix
3 3 |
4 4 | # UP100
5 5 | x: typing.TypeAlias = int
6 |-x: TypeAlias = int
6 |+type x = int
7 7 |
8 8 |
9 9 | # UP100 with generics (todo)
UP100.py:11:1: UP100 [*] Type alias `x` uses `TypeAlias` annotation instead of the `type` keyword
|
9 | # UP100 with generics (todo)
10 | T = typing.TypeVar["T"]
11 | x: typing.TypeAlias = list[T]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP100
|
= help: Replace with the `type` keyword
ℹ Fix
8 8 |
9 9 | # UP100 with generics (todo)
10 10 | T = typing.TypeVar["T"]
11 |-x: typing.TypeAlias = list[T]
11 |+type x = list[T]
12 12 |
13 13 |
14 14 | # OK
1 change: 0 additions & 1 deletion crates/ruff/src/rules/ruff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ mod tests {
Path::new("RUF015.py")
)]
#[test_case(Rule::InvalidIndexType, Path::new("RUF016.py"))]
#[test_case(Rule::TypeAliasAnnotation, Path::new("RUF017.py"))]
#[cfg_attr(
feature = "unreachable-code",
test_case(Rule::UnreachableCode, Path::new("RUF014.py"))
Expand Down
2 changes: 0 additions & 2 deletions crates/ruff/src/rules/ruff/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub(crate) use mutable_class_default::*;
pub(crate) use mutable_dataclass_default::*;
pub(crate) use pairwise_over_zipped::*;
pub(crate) use static_key_dict_comprehension::*;
pub(crate) use type_alias_annotation::*;
pub(crate) use unnecessary_iterable_allocation_for_first_element::*;
#[cfg(feature = "unreachable-code")]
pub(crate) use unreachable::*;
Expand All @@ -30,7 +29,6 @@ mod mutable_class_default;
mod mutable_dataclass_default;
mod pairwise_over_zipped;
mod static_key_dict_comprehension;
mod type_alias_annotation;
mod unnecessary_iterable_allocation_for_first_element;
#[cfg(feature = "unreachable-code")]
pub(crate) mod unreachable;
Expand Down
3 changes: 2 additions & 1 deletion ruff.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fed82c3

Please sign in to comment.