Skip to content

Commit e9e194a

Browse files
authored
[flake8-pyi] Implement PYI042 and PYI043 (#4214)
1 parent 890e630 commit e9e194a

16 files changed

+283
-2
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import typing
2+
from collections.abc import Mapping
3+
from typing import (
4+
Annotated,
5+
TypeAlias,
6+
Union,
7+
Literal,
8+
)
9+
10+
just_literals_pipe_union: TypeAlias = (
11+
Literal[True] | Literal["idk"]
12+
) # not PYI042 (not a stubfile)
13+
PublicAliasT: TypeAlias = str | int
14+
PublicAliasT2: TypeAlias = Union[str, bytes]
15+
_ABCDEFGHIJKLMNOPQRST: TypeAlias = typing.Any
16+
_PrivateAliasS: TypeAlias = Literal["I", "guess", "this", "is", "okay"]
17+
_PrivateAliasS2: TypeAlias = Annotated[str, "also okay"]
18+
19+
snake_case_alias1: TypeAlias = str | int # not PYI042 (not a stubfile)
20+
_snake_case_alias2: TypeAlias = Literal["whatever"] # not PYI042 (not a stubfile)
21+
Snake_case_alias: TypeAlias = int | float # not PYI042 (not a stubfile)
22+
23+
# check that this edge case doesn't crash
24+
_: TypeAlias = str | int
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import typing
2+
from collections.abc import Mapping
3+
from typing import (
4+
Annotated,
5+
TypeAlias,
6+
Union,
7+
Literal,
8+
)
9+
10+
just_literals_pipe_union: TypeAlias = (
11+
Literal[True] | Literal["idk"]
12+
) # PYI042, since not camel case
13+
PublicAliasT: TypeAlias = str | int
14+
PublicAliasT2: TypeAlias = Union[str, bytes]
15+
_ABCDEFGHIJKLMNOPQRST: TypeAlias = typing.Any
16+
_PrivateAliasS: TypeAlias = Literal["I", "guess", "this", "is", "okay"]
17+
_PrivateAliasS2: TypeAlias = Annotated[str, "also okay"]
18+
19+
snake_case_alias1: TypeAlias = str | int # PYI042, since not camel case
20+
_snake_case_alias2: TypeAlias = Literal["whatever"] # PYI042, since not camel case
21+
Snake_case_alias: TypeAlias = int | float # PYI042, since not camel case
22+
23+
# check that this edge case doesn't crash
24+
_: TypeAlias = str | int
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import typing
2+
from collections.abc import Mapping
3+
from typing import (
4+
Annotated,
5+
TypeAlias,
6+
Union,
7+
Literal,
8+
)
9+
10+
_PrivateAliasT: TypeAlias = str | int # not PYI043 (not a stubfile)
11+
_PrivateAliasT2: TypeAlias = typing.Any # not PYI043 (not a stubfile)
12+
_PrivateAliasT3: TypeAlias = Literal[
13+
"not", "a", "chance"
14+
] # not PYI043 (not a stubfile)
15+
just_literals_pipe_union: TypeAlias = Literal[True] | Literal["idk"]
16+
PublicAliasT: TypeAlias = str | int
17+
PublicAliasT2: TypeAlias = Union[str, bytes]
18+
_ABCDEFGHIJKLMNOPQRST: TypeAlias = typing.Any
19+
_PrivateAliasS: TypeAlias = Literal["I", "guess", "this", "is", "okay"]
20+
_PrivateAliasS2: TypeAlias = Annotated[str, "also okay"]
21+
22+
# check that this edge case doesn't crash
23+
_: TypeAlias = str | int
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import typing
2+
from collections.abc import Mapping
3+
from typing import (
4+
Annotated,
5+
TypeAlias,
6+
Union,
7+
Literal,
8+
)
9+
10+
_PrivateAliasT: TypeAlias = str | int # PYI043, since this ends in a T
11+
_PrivateAliasT2: TypeAlias = typing.Any # PYI043, since this ends in a T
12+
_PrivateAliasT3: TypeAlias = Literal[
13+
"not", "a", "chance"
14+
] # PYI043, since this ends in a T
15+
just_literals_pipe_union: TypeAlias = Literal[True] | Literal["idk"]
16+
PublicAliasT: TypeAlias = str | int
17+
PublicAliasT2: TypeAlias = Union[str, bytes]
18+
_ABCDEFGHIJKLMNOPQRST: TypeAlias = typing.Any
19+
_PrivateAliasS: TypeAlias = Literal["I", "guess", "this", "is", "okay"]
20+
_PrivateAliasS2: TypeAlias = Annotated[str, "also okay"]
21+
22+
# check that this edge case doesn't crash
23+
_: TypeAlias = str | int

crates/ruff/src/checkers/ast/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,6 +1914,14 @@ where
19141914
}
19151915
}
19161916
}
1917+
if self.ctx.match_typing_expr(annotation, "TypeAlias") {
1918+
if self.settings.rules.enabled(Rule::SnakeCaseTypeAlias) {
1919+
flake8_pyi::rules::snake_case_type_alias(self, target);
1920+
}
1921+
if self.settings.rules.enabled(Rule::TSuffixedTypeAlias) {
1922+
flake8_pyi::rules::t_suffixed_type_alias(self, target);
1923+
}
1924+
}
19171925
}
19181926
}
19191927
StmtKind::Delete { targets } => {

crates/ruff/src/codes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
595595
(Flake8Pyi, "020") => Rule::QuotedAnnotationInStub,
596596
(Flake8Pyi, "021") => Rule::DocstringInStub,
597597
(Flake8Pyi, "033") => Rule::TypeCommentInStub,
598+
(Flake8Pyi, "042") => Rule::SnakeCaseTypeAlias,
599+
(Flake8Pyi, "043") => Rule::TSuffixedTypeAlias,
598600

599601
// flake8-pytest-style
600602
(Flake8PytestStyle, "001") => Rule::PytestFixtureIncorrectParenthesesStyle,

crates/ruff/src/registry.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,8 @@ ruff_macros::register_rules!(
540540
rules::flake8_pyi::rules::PassInClassBody,
541541
rules::flake8_pyi::rules::DuplicateUnionMember,
542542
rules::flake8_pyi::rules::QuotedAnnotationInStub,
543+
rules::flake8_pyi::rules::SnakeCaseTypeAlias,
544+
rules::flake8_pyi::rules::TSuffixedTypeAlias,
543545
// flake8-pytest-style
544546
rules::flake8_pytest_style::rules::PytestFixtureIncorrectParenthesesStyle,
545547
rules::flake8_pytest_style::rules::PytestFixturePositionalArgs,

crates/ruff/src/registry/rule_set.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use std::iter::FusedIterator;
77
///
88
/// Uses a bitset where a bit of one signals that the Rule with that [u16] is in this set.
99
#[derive(Clone, Default, CacheKey, PartialEq, Eq)]
10-
pub struct RuleSet([u64; 9]);
10+
pub struct RuleSet([u64; 10]);
1111

1212
impl RuleSet {
13-
const EMPTY: [u64; 9] = [0; 9];
13+
const EMPTY: [u64; 10] = [0; 10];
1414

1515
// 64 fits into a u16 without truncation
1616
#[allow(clippy::cast_possible_truncation)]

crates/ruff/src/rules/flake8_pyi/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ mod tests {
4141
#[test_case(Rule::DocstringInStub, Path::new("PYI021.pyi"))]
4242
#[test_case(Rule::TypeCommentInStub, Path::new("PYI033.py"))]
4343
#[test_case(Rule::TypeCommentInStub, Path::new("PYI033.pyi"))]
44+
#[test_case(Rule::SnakeCaseTypeAlias, Path::new("PYI042.py"))]
45+
#[test_case(Rule::SnakeCaseTypeAlias, Path::new("PYI042.pyi"))]
46+
#[test_case(Rule::TSuffixedTypeAlias, Path::new("PYI043.py"))]
47+
#[test_case(Rule::TSuffixedTypeAlias, Path::new("PYI043.pyi"))]
4448
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
4549
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
4650
let diagnostics = test_path(

crates/ruff/src/rules/flake8_pyi/rules/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ pub use simple_defaults::{
1111
typed_argument_simple_defaults, ArgumentDefaultInStub, AssignmentDefaultInStub,
1212
TypedArgumentDefaultInStub,
1313
};
14+
pub use type_alias_naming::{
15+
snake_case_type_alias, t_suffixed_type_alias, SnakeCaseTypeAlias, TSuffixedTypeAlias,
16+
};
1417
pub use type_comment_in_stub::{type_comment_in_stub, TypeCommentInStub};
1518
pub use unrecognized_platform::{
1619
unrecognized_platform, UnrecognizedPlatformCheck, UnrecognizedPlatformName,
@@ -25,5 +28,6 @@ mod pass_statement_stub_body;
2528
mod prefix_type_params;
2629
mod quoted_annotation_in_stub;
2730
mod simple_defaults;
31+
mod type_alias_naming;
2832
mod type_comment_in_stub;
2933
mod unrecognized_platform;

0 commit comments

Comments
 (0)