mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 13:33:50 +00:00
[pycodestyle
] Avoid false positives and negatives related to type parameter default syntax (E225
, E251
) (#15214)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
This commit is contained in:
parent
79682a28b8
commit
af95f6b577
6 changed files with 34 additions and 11 deletions
|
@ -183,3 +183,8 @@ if i == -1:
|
|||
|
||||
if a == 1:
|
||||
print(a)
|
||||
|
||||
|
||||
# No E225: `=` is not an operator in this case
|
||||
def _[T: str=None](): ...
|
||||
def _(t: str=None): ...
|
||||
|
|
|
@ -75,3 +75,7 @@ def pep_696_good[A = int, B: object = str, C:object = memoryview]():
|
|||
class PEP696Good[A = int, B: object = str, C:object = memoryview]:
|
||||
def pep_696_good_method[A = int, B: object = str, C:object = memoryview](self):
|
||||
pass
|
||||
|
||||
|
||||
# https://github.com/astral-sh/ruff/issues/15202
|
||||
type Coro[T: object = Any] = Coroutine[None, None, T]
|
||||
|
|
|
@ -5,7 +5,7 @@ use ruff_text_size::Ranged;
|
|||
|
||||
use crate::checkers::logical_lines::LogicalLinesContext;
|
||||
use crate::rules::pycodestyle::helpers::is_non_logical_token;
|
||||
use crate::rules::pycodestyle::rules::logical_lines::LogicalLine;
|
||||
use crate::rules::pycodestyle::rules::logical_lines::{DefinitionState, LogicalLine};
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for missing whitespace around all operators.
|
||||
|
@ -146,6 +146,7 @@ pub(crate) fn missing_whitespace_around_operator(
|
|||
line: &LogicalLine,
|
||||
context: &mut LogicalLinesContext,
|
||||
) {
|
||||
let mut definition_state = DefinitionState::from_tokens(line.tokens());
|
||||
let mut tokens = line.tokens().iter().peekable();
|
||||
let first_token = tokens
|
||||
.by_ref()
|
||||
|
@ -162,6 +163,8 @@ pub(crate) fn missing_whitespace_around_operator(
|
|||
while let Some(token) = tokens.next() {
|
||||
let kind = token.kind();
|
||||
|
||||
definition_state.visit_token_kind(kind);
|
||||
|
||||
if is_non_logical_token(kind) {
|
||||
continue;
|
||||
}
|
||||
|
@ -174,8 +177,11 @@ pub(crate) fn missing_whitespace_around_operator(
|
|||
_ => {}
|
||||
};
|
||||
|
||||
let needs_space = if kind == TokenKind::Equal && (parens > 0 || fstrings > 0) {
|
||||
let needs_space = if kind == TokenKind::Equal
|
||||
&& (parens > 0 || fstrings > 0 || definition_state.in_type_params())
|
||||
{
|
||||
// Allow keyword args, defaults: foo(bar=None) and f-strings: f'{foo=}'
|
||||
// Also ignore `foo[T=int]`, which is handled by E251.
|
||||
NeedsSpace::No
|
||||
} else if kind == TokenKind::Slash {
|
||||
// Tolerate the "/" operator in function definition
|
||||
|
|
|
@ -480,7 +480,8 @@ struct Line {
|
|||
enum DefinitionState {
|
||||
InClass(TypeParamsState),
|
||||
InFunction(TypeParamsState),
|
||||
NotInClassOrFunction,
|
||||
InTypeAlias(TypeParamsState),
|
||||
NotInDefinition,
|
||||
}
|
||||
|
||||
impl DefinitionState {
|
||||
|
@ -494,11 +495,12 @@ impl DefinitionState {
|
|||
TokenKind::Async if matches!(token_kinds.next(), Some(TokenKind::Def)) => {
|
||||
Self::InFunction(TypeParamsState::default())
|
||||
}
|
||||
_ => Self::NotInClassOrFunction,
|
||||
TokenKind::Type => Self::InTypeAlias(TypeParamsState::default()),
|
||||
_ => Self::NotInDefinition,
|
||||
};
|
||||
return state;
|
||||
}
|
||||
Self::NotInClassOrFunction
|
||||
Self::NotInDefinition
|
||||
}
|
||||
|
||||
const fn in_function_definition(self) -> bool {
|
||||
|
@ -507,8 +509,10 @@ impl DefinitionState {
|
|||
|
||||
const fn type_params_state(self) -> Option<TypeParamsState> {
|
||||
match self {
|
||||
Self::InClass(state) | Self::InFunction(state) => Some(state),
|
||||
Self::NotInClassOrFunction => None,
|
||||
Self::InClass(state) | Self::InFunction(state) | Self::InTypeAlias(state) => {
|
||||
Some(state)
|
||||
}
|
||||
Self::NotInDefinition => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,10 +525,10 @@ impl DefinitionState {
|
|||
|
||||
fn visit_token_kind(&mut self, token_kind: TokenKind) {
|
||||
let type_params_state_mut = match self {
|
||||
Self::InClass(type_params_state) | Self::InFunction(type_params_state) => {
|
||||
type_params_state
|
||||
}
|
||||
Self::NotInClassOrFunction => return,
|
||||
Self::InClass(type_params_state)
|
||||
| Self::InFunction(type_params_state)
|
||||
| Self::InTypeAlias(type_params_state) => type_params_state,
|
||||
Self::NotInDefinition => return,
|
||||
};
|
||||
match token_kind {
|
||||
TokenKind::Lpar if type_params_state_mut.before_type_params() => {
|
||||
|
|
|
@ -186,3 +186,5 @@ E22.py:184:5: E221 [*] Multiple spaces before operator
|
|||
184 |-if a == 1:
|
||||
184 |+if a == 1:
|
||||
185 185 | print(a)
|
||||
186 186 |
|
||||
187 187 |
|
||||
|
|
|
@ -123,3 +123,5 @@ E22.py:184:9: E222 [*] Multiple spaces after operator
|
|||
184 |-if a == 1:
|
||||
184 |+if a == 1:
|
||||
185 185 | print(a)
|
||||
186 186 |
|
||||
187 187 |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue