mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +00:00
[pycodestyle
]: Make blank lines in typing stub files optional (E3*
) (#10098)
## Summary Fixes https://github.com/astral-sh/ruff/issues/10039 The [recommendation for typing stub files](https://typing.readthedocs.io/en/latest/source/stubs.html#blank-lines) is to use **one** blank line to group related definitions and otherwise omit blank lines. The newly added blank line rules (`E3*`) didn't account for typing stub files and enforced two empty lines at the top level and one empty line otherwise, making it impossible to group related definitions. This PR implements the `E3*` rules to: * Not enforce blank lines. The use of blank lines in typing definitions is entirely up to the user. * Allow at most one empty line, including between top level statements. ## Test Plan Added unit tests (It may look odd that many snapshots are empty but the point is that the rule should no longer emit diagnostics)
This commit is contained in:
parent
46ab9dec18
commit
af6ea2f5e4
12 changed files with 577 additions and 12 deletions
50
crates/ruff_linter/resources/test/fixtures/pycodestyle/E30.pyi
vendored
Normal file
50
crates/ruff_linter/resources/test/fixtures/pycodestyle/E30.pyi
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
from typing import Any, Sequence
|
||||||
|
|
||||||
|
class MissingCommand(TypeError): ...
|
||||||
|
class AnoherClass: ...
|
||||||
|
|
||||||
|
def a(): ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def a(arg: int): ...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def a(arg: int, name: str): ...
|
||||||
|
|
||||||
|
|
||||||
|
def grouped1(): ...
|
||||||
|
def grouped2(): ...
|
||||||
|
def grouped3( ): ...
|
||||||
|
|
||||||
|
|
||||||
|
class BackendProxy:
|
||||||
|
backend_module: str
|
||||||
|
backend_object: str | None
|
||||||
|
backend: Any
|
||||||
|
|
||||||
|
def grouped1(): ...
|
||||||
|
def grouped2(): ...
|
||||||
|
def grouped3( ): ...
|
||||||
|
@decorated
|
||||||
|
|
||||||
|
def with_blank_line(): ...
|
||||||
|
|
||||||
|
|
||||||
|
def ungrouped(): ...
|
||||||
|
a = "test"
|
||||||
|
|
||||||
|
def function_def():
|
||||||
|
pass
|
||||||
|
b = "test"
|
||||||
|
|
||||||
|
|
||||||
|
def outer():
|
||||||
|
def inner():
|
||||||
|
pass
|
||||||
|
def inner2():
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Foo: ...
|
||||||
|
class Bar: ...
|
62
crates/ruff_linter/resources/test/fixtures/pycodestyle/E30_isort.pyi
vendored
Normal file
62
crates/ruff_linter/resources/test/fixtures/pycodestyle/E30_isort.pyi
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Any, Sequence
|
||||||
|
|
||||||
|
|
||||||
|
class MissingCommand(TypeError): ... # noqa: N818
|
||||||
|
|
||||||
|
|
||||||
|
class BackendProxy:
|
||||||
|
backend_module: str
|
||||||
|
backend_object: str | None
|
||||||
|
backend: Any
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import abcd
|
||||||
|
|
||||||
|
|
||||||
|
abcd.foo()
|
||||||
|
|
||||||
|
def __init__(self, backend_module: str, backend_obj: str | None) -> None: ...
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
from typing_extensions import TypeAlias
|
||||||
|
|
||||||
|
|
||||||
|
abcd.foo()
|
||||||
|
|
||||||
|
def __call__(self, name: str, *args: Any, **kwargs: Any) -> Any:
|
||||||
|
...
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from typing_extensions import TypeAlias
|
||||||
|
|
||||||
|
def __call__2(self, name: str, *args: Any, **kwargs: Any) -> Any:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
def _exit(self) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
def _optional_commands(self) -> dict[str, bool]: ...
|
||||||
|
|
||||||
|
|
||||||
|
def run(argv: Sequence[str]) -> int: ...
|
||||||
|
|
||||||
|
|
||||||
|
def read_line(fd: int = 0) -> bytearray: ...
|
||||||
|
|
||||||
|
|
||||||
|
def flush() -> None: ...
|
||||||
|
|
||||||
|
|
||||||
|
from typing import Any, Sequence
|
||||||
|
|
||||||
|
class MissingCommand(TypeError): ... # noqa: N818
|
|
@ -41,7 +41,8 @@ pub(crate) fn check_tokens(
|
||||||
Rule::BlankLinesAfterFunctionOrClass,
|
Rule::BlankLinesAfterFunctionOrClass,
|
||||||
Rule::BlankLinesBeforeNestedDefinition,
|
Rule::BlankLinesBeforeNestedDefinition,
|
||||||
]) {
|
]) {
|
||||||
BlankLinesChecker::new(locator, stylist, settings).check_lines(tokens, &mut diagnostics);
|
BlankLinesChecker::new(locator, stylist, settings, source_type)
|
||||||
|
.check_lines(tokens, &mut diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.rules.enabled(Rule::BlanketNOQA) {
|
if settings.rules.enabled(Rule::BlanketNOQA) {
|
||||||
|
|
|
@ -222,6 +222,38 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test_case(Rule::BlankLineBetweenMethods)]
|
||||||
|
#[test_case(Rule::BlankLinesTopLevel)]
|
||||||
|
#[test_case(Rule::TooManyBlankLines)]
|
||||||
|
#[test_case(Rule::BlankLineAfterDecorator)]
|
||||||
|
#[test_case(Rule::BlankLinesAfterFunctionOrClass)]
|
||||||
|
#[test_case(Rule::BlankLinesBeforeNestedDefinition)]
|
||||||
|
fn blank_lines_typing_stub(rule_code: Rule) -> Result<()> {
|
||||||
|
let snapshot = format!("blank_lines_{}_typing_stub", rule_code.noqa_code());
|
||||||
|
let diagnostics = test_path(
|
||||||
|
Path::new("pycodestyle").join("E30.pyi"),
|
||||||
|
&settings::LinterSettings::for_rule(rule_code),
|
||||||
|
)?;
|
||||||
|
assert_messages!(snapshot, diagnostics);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn blank_lines_typing_stub_isort() -> Result<()> {
|
||||||
|
let diagnostics = test_path(
|
||||||
|
Path::new("pycodestyle").join("E30_isort.pyi"),
|
||||||
|
&settings::LinterSettings {
|
||||||
|
..settings::LinterSettings::for_rules([
|
||||||
|
Rule::TooManyBlankLines,
|
||||||
|
Rule::BlankLinesTopLevel,
|
||||||
|
Rule::UnsortedImports,
|
||||||
|
])
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
assert_messages!(diagnostics);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn constant_literals() -> Result<()> {
|
fn constant_literals() -> Result<()> {
|
||||||
let diagnostics = test_path(
|
let diagnostics = test_path(
|
||||||
|
|
|
@ -8,6 +8,7 @@ use ruff_diagnostics::Diagnostic;
|
||||||
use ruff_diagnostics::Edit;
|
use ruff_diagnostics::Edit;
|
||||||
use ruff_diagnostics::Fix;
|
use ruff_diagnostics::Fix;
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
use ruff_python_ast::PySourceType;
|
||||||
use ruff_python_codegen::Stylist;
|
use ruff_python_codegen::Stylist;
|
||||||
use ruff_python_parser::lexer::LexResult;
|
use ruff_python_parser::lexer::LexResult;
|
||||||
use ruff_python_parser::lexer::LexicalError;
|
use ruff_python_parser::lexer::LexicalError;
|
||||||
|
@ -51,9 +52,14 @@ const BLANK_LINES_NESTED_LEVEL: u32 = 1;
|
||||||
/// pass
|
/// pass
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ## Typing stub files (`.pyi`)
|
||||||
|
/// The typing style guide recommends to not use blank lines between methods except to group
|
||||||
|
/// them. That's why this rule is not enabled in typing stub files.
|
||||||
|
///
|
||||||
/// ## References
|
/// ## References
|
||||||
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
||||||
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E301.html)
|
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E301.html)
|
||||||
|
/// - [Typing Style Guide](https://typing.readthedocs.io/en/latest/source/stubs.html#blank-lines)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct BlankLineBetweenMethods;
|
pub struct BlankLineBetweenMethods;
|
||||||
|
|
||||||
|
@ -96,9 +102,14 @@ impl AlwaysFixableViolation for BlankLineBetweenMethods {
|
||||||
/// pass
|
/// pass
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ## Typing stub files (`.pyi`)
|
||||||
|
/// The typing style guide recommends to not use blank lines between classes and functions except to group
|
||||||
|
/// them. That's why this rule is not enabled in typing stub files.
|
||||||
|
///
|
||||||
/// ## References
|
/// ## References
|
||||||
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
||||||
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E302.html)
|
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E302.html)
|
||||||
|
/// - [Typing Style Guide](https://typing.readthedocs.io/en/latest/source/stubs.html#blank-lines)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct BlankLinesTopLevel {
|
pub struct BlankLinesTopLevel {
|
||||||
actual_blank_lines: u32,
|
actual_blank_lines: u32,
|
||||||
|
@ -150,6 +161,9 @@ impl AlwaysFixableViolation for BlankLinesTopLevel {
|
||||||
/// pass
|
/// pass
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ## Typing stub files (`.pyi`)
|
||||||
|
/// The rule allows at most one blank line in typing stub files in accordance to the typing style guide recommendation.
|
||||||
|
///
|
||||||
/// Note: The rule respects the following `isort` settings when determining the maximum number of blank lines allowed between two statements:
|
/// Note: The rule respects the following `isort` settings when determining the maximum number of blank lines allowed between two statements:
|
||||||
/// * [`lint.isort.lines-after-imports`]: For top-level statements directly following an import statement.
|
/// * [`lint.isort.lines-after-imports`]: For top-level statements directly following an import statement.
|
||||||
/// * [`lint.isort.lines-between-types`]: For `import` statements directly following a `from ... import ...` statement or vice versa.
|
/// * [`lint.isort.lines-between-types`]: For `import` statements directly following a `from ... import ...` statement or vice versa.
|
||||||
|
@ -157,6 +171,7 @@ impl AlwaysFixableViolation for BlankLinesTopLevel {
|
||||||
/// ## References
|
/// ## References
|
||||||
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
||||||
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E303.html)
|
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E303.html)
|
||||||
|
/// - [Typing Style Guide](https://typing.readthedocs.io/en/latest/source/stubs.html#blank-lines)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct TooManyBlankLines {
|
pub struct TooManyBlankLines {
|
||||||
actual_blank_lines: u32,
|
actual_blank_lines: u32,
|
||||||
|
@ -246,9 +261,14 @@ impl AlwaysFixableViolation for BlankLineAfterDecorator {
|
||||||
/// user = User()
|
/// user = User()
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ## Typing stub files (`.pyi`)
|
||||||
|
/// The typing style guide recommends to not use blank lines between statements except to group
|
||||||
|
/// them. That's why this rule is not enabled in typing stub files.
|
||||||
|
///
|
||||||
/// ## References
|
/// ## References
|
||||||
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
||||||
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E305.html)
|
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E305.html)
|
||||||
|
/// - [Typing Style Guide](https://typing.readthedocs.io/en/latest/source/stubs.html#blank-lines)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct BlankLinesAfterFunctionOrClass {
|
pub struct BlankLinesAfterFunctionOrClass {
|
||||||
actual_blank_lines: u32,
|
actual_blank_lines: u32,
|
||||||
|
@ -295,9 +315,14 @@ impl AlwaysFixableViolation for BlankLinesAfterFunctionOrClass {
|
||||||
/// pass
|
/// pass
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ## Typing stub files (`.pyi`)
|
||||||
|
/// The typing style guide recommends to not use blank lines between classes and functions except to group
|
||||||
|
/// them. That's why this rule is not enabled in typing stub files.
|
||||||
|
///
|
||||||
/// ## References
|
/// ## References
|
||||||
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
/// - [PEP 8](https://peps.python.org/pep-0008/#blank-lines)
|
||||||
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E306.html)
|
/// - [Flake 8 rule](https://www.flake8rules.com/rules/E306.html)
|
||||||
|
/// - [Typing Style Guide](https://typing.readthedocs.io/en/latest/source/stubs.html#blank-lines)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct BlankLinesBeforeNestedDefinition;
|
pub struct BlankLinesBeforeNestedDefinition;
|
||||||
|
|
||||||
|
@ -628,6 +653,7 @@ pub(crate) struct BlankLinesChecker<'a> {
|
||||||
indent_width: IndentWidth,
|
indent_width: IndentWidth,
|
||||||
lines_after_imports: isize,
|
lines_after_imports: isize,
|
||||||
lines_between_types: usize,
|
lines_between_types: usize,
|
||||||
|
source_type: PySourceType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> BlankLinesChecker<'a> {
|
impl<'a> BlankLinesChecker<'a> {
|
||||||
|
@ -635,6 +661,7 @@ impl<'a> BlankLinesChecker<'a> {
|
||||||
locator: &'a Locator<'a>,
|
locator: &'a Locator<'a>,
|
||||||
stylist: &'a Stylist<'a>,
|
stylist: &'a Stylist<'a>,
|
||||||
settings: &crate::settings::LinterSettings,
|
settings: &crate::settings::LinterSettings,
|
||||||
|
source_type: PySourceType,
|
||||||
) -> BlankLinesChecker<'a> {
|
) -> BlankLinesChecker<'a> {
|
||||||
BlankLinesChecker {
|
BlankLinesChecker {
|
||||||
stylist,
|
stylist,
|
||||||
|
@ -642,6 +669,7 @@ impl<'a> BlankLinesChecker<'a> {
|
||||||
indent_width: settings.tab_size,
|
indent_width: settings.tab_size,
|
||||||
lines_after_imports: settings.isort.lines_after_imports,
|
lines_after_imports: settings.isort.lines_after_imports,
|
||||||
lines_between_types: settings.isort.lines_between_types,
|
lines_between_types: settings.isort.lines_between_types,
|
||||||
|
source_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,6 +767,8 @@ impl<'a> BlankLinesChecker<'a> {
|
||||||
&& !matches!(state.follows, Follows::Docstring | Follows::Decorator)
|
&& !matches!(state.follows, Follows::Docstring | Follows::Decorator)
|
||||||
// Do not trigger when the def follows an if/while/etc...
|
// Do not trigger when the def follows an if/while/etc...
|
||||||
&& prev_indent_length.is_some_and(|prev_indent_length| prev_indent_length >= line.indent_length)
|
&& prev_indent_length.is_some_and(|prev_indent_length| prev_indent_length >= line.indent_length)
|
||||||
|
// Blank lines in stub files are only used for grouping. Don't enforce blank lines.
|
||||||
|
&& !self.source_type.is_stub()
|
||||||
{
|
{
|
||||||
// E301
|
// E301
|
||||||
let mut diagnostic = Diagnostic::new(BlankLineBetweenMethods, line.first_token_range);
|
let mut diagnostic = Diagnostic::new(BlankLineBetweenMethods, line.first_token_range);
|
||||||
|
@ -750,20 +780,31 @@ impl<'a> BlankLinesChecker<'a> {
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Blank lines in stub files are used to group definitions. Don't enforce blank lines.
|
||||||
|
let max_lines_level = if self.source_type.is_stub() {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
if line.indent_length == 0 {
|
||||||
|
BLANK_LINES_TOP_LEVEL
|
||||||
|
} else {
|
||||||
|
BLANK_LINES_NESTED_LEVEL
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let expected_blank_lines_before_definition = if line.indent_length == 0 {
|
let expected_blank_lines_before_definition = if line.indent_length == 0 {
|
||||||
// Mimic the isort rules for the number of blank lines before classes and functions
|
// Mimic the isort rules for the number of blank lines before classes and functions
|
||||||
if state.follows.is_any_import() {
|
if state.follows.is_any_import() {
|
||||||
// Fallback to the default if the value is too large for an u32 or if it is negative.
|
// Fallback to the default if the value is too large for an u32 or if it is negative.
|
||||||
// A negative value means that isort should determine the blank lines automatically.
|
// A negative value means that isort should determine the blank lines automatically.
|
||||||
// `isort` defaults to 2 if before a class or function definition and 1 otherwise.
|
// `isort` defaults to 2 if before a class or function definition (except in stubs where it is one) and 1 otherwise.
|
||||||
// Defaulting to 2 here is correct because the variable is only used when testing the
|
// Defaulting to 2 (or 1 in stubs) here is correct because the variable is only used when testing the
|
||||||
// blank lines before a class or function definition.
|
// blank lines before a class or function definition.
|
||||||
u32::try_from(self.lines_after_imports).unwrap_or(BLANK_LINES_TOP_LEVEL)
|
u32::try_from(self.lines_after_imports).unwrap_or(max_lines_level)
|
||||||
} else {
|
} else {
|
||||||
BLANK_LINES_TOP_LEVEL
|
max_lines_level
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BLANK_LINES_NESTED_LEVEL
|
max_lines_level
|
||||||
};
|
};
|
||||||
|
|
||||||
if line.preceding_blank_lines < expected_blank_lines_before_definition
|
if line.preceding_blank_lines < expected_blank_lines_before_definition
|
||||||
|
@ -775,6 +816,8 @@ impl<'a> BlankLinesChecker<'a> {
|
||||||
&& line.indent_length == 0
|
&& line.indent_length == 0
|
||||||
// Only apply to functions or classes.
|
// Only apply to functions or classes.
|
||||||
&& line.kind.is_class_function_or_decorator()
|
&& line.kind.is_class_function_or_decorator()
|
||||||
|
// Blank lines in stub files are used to group definitions. Don't enforce blank lines.
|
||||||
|
&& !self.source_type.is_stub()
|
||||||
{
|
{
|
||||||
// E302
|
// E302
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
|
@ -804,12 +847,6 @@ impl<'a> BlankLinesChecker<'a> {
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
let max_lines_level = if line.indent_length == 0 {
|
|
||||||
BLANK_LINES_TOP_LEVEL
|
|
||||||
} else {
|
|
||||||
BLANK_LINES_NESTED_LEVEL
|
|
||||||
};
|
|
||||||
|
|
||||||
// If between `import` and `from .. import ..` or the other way round,
|
// If between `import` and `from .. import ..` or the other way round,
|
||||||
// allow up to `lines_between_types` newlines for isort compatibility.
|
// allow up to `lines_between_types` newlines for isort compatibility.
|
||||||
// We let `isort` remove extra blank lines when the imports belong
|
// We let `isort` remove extra blank lines when the imports belong
|
||||||
|
@ -893,6 +930,8 @@ impl<'a> BlankLinesChecker<'a> {
|
||||||
&& line.indent_length == 0
|
&& line.indent_length == 0
|
||||||
&& !line.is_comment_only
|
&& !line.is_comment_only
|
||||||
&& !line.kind.is_class_function_or_decorator()
|
&& !line.kind.is_class_function_or_decorator()
|
||||||
|
// Blank lines in stub files are used for grouping, don't enforce blank lines.
|
||||||
|
&& !self.source_type.is_stub()
|
||||||
{
|
{
|
||||||
// E305
|
// E305
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
|
@ -933,6 +972,8 @@ impl<'a> BlankLinesChecker<'a> {
|
||||||
&& prev_indent_length.is_some_and(|prev_indent_length| prev_indent_length >= line.indent_length)
|
&& prev_indent_length.is_some_and(|prev_indent_length| prev_indent_length >= line.indent_length)
|
||||||
// Allow groups of one-liners.
|
// Allow groups of one-liners.
|
||||||
&& !(matches!(state.follows, Follows::Def) && line.last_token != TokenKind::Colon)
|
&& !(matches!(state.follows, Follows::Def) && line.last_token != TokenKind::Colon)
|
||||||
|
// Blank lines in stub files are only used for grouping. Don't enforce blank lines.
|
||||||
|
&& !self.source_type.is_stub()
|
||||||
{
|
{
|
||||||
// E306
|
// E306
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
|
---
|
||||||
|
E30.pyi:17:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
17 | def grouped1(): ...
|
||||||
|
| ^^^ E303
|
||||||
|
18 | def grouped2(): ...
|
||||||
|
19 | def grouped3( ): ...
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
13 13 | @overload
|
||||||
|
14 14 | def a(arg: int, name: str): ...
|
||||||
|
15 15 |
|
||||||
|
16 |-
|
||||||
|
17 16 | def grouped1(): ...
|
||||||
|
18 17 | def grouped2(): ...
|
||||||
|
19 18 | def grouped3( ): ...
|
||||||
|
|
||||||
|
E30.pyi:22:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
22 | class BackendProxy:
|
||||||
|
| ^^^^^ E303
|
||||||
|
23 | backend_module: str
|
||||||
|
24 | backend_object: str | None
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
18 18 | def grouped2(): ...
|
||||||
|
19 19 | def grouped3( ): ...
|
||||||
|
20 20 |
|
||||||
|
21 |-
|
||||||
|
22 21 | class BackendProxy:
|
||||||
|
23 22 | backend_module: str
|
||||||
|
24 23 | backend_object: str | None
|
||||||
|
|
||||||
|
E30.pyi:35:5: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
35 | def ungrouped(): ...
|
||||||
|
| ^^^ E303
|
||||||
|
36 | a = "test"
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
31 31 |
|
||||||
|
32 32 | def with_blank_line(): ...
|
||||||
|
33 33 |
|
||||||
|
34 |-
|
||||||
|
35 34 | def ungrouped(): ...
|
||||||
|
36 35 | a = "test"
|
||||||
|
37 36 |
|
||||||
|
|
||||||
|
E30.pyi:43:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
43 | def outer():
|
||||||
|
| ^^^ E303
|
||||||
|
44 | def inner():
|
||||||
|
45 | pass
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
39 39 | pass
|
||||||
|
40 40 | b = "test"
|
||||||
|
41 41 |
|
||||||
|
42 |-
|
||||||
|
43 42 | def outer():
|
||||||
|
44 43 | def inner():
|
||||||
|
45 44 | pass
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
|
---
|
||||||
|
E30.pyi:32:5: E304 [*] Blank lines found after function decorator (1)
|
||||||
|
|
|
||||||
|
30 | @decorated
|
||||||
|
31 |
|
||||||
|
32 | def with_blank_line(): ...
|
||||||
|
| ^^^ E304
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
28 28 | def grouped2(): ...
|
||||||
|
29 29 | def grouped3( ): ...
|
||||||
|
30 30 | @decorated
|
||||||
|
31 |-
|
||||||
|
32 31 | def with_blank_line(): ...
|
||||||
|
33 32 |
|
||||||
|
34 33 |
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,270 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_linter/src/rules/pycodestyle/mod.rs
|
||||||
|
---
|
||||||
|
E30_isort.pyi:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||||
|
|
|
||||||
|
1 | / import json
|
||||||
|
2 | |
|
||||||
|
3 | |
|
||||||
|
4 | |
|
||||||
|
5 | | from typing import Any, Sequence
|
||||||
|
6 | |
|
||||||
|
7 | |
|
||||||
|
8 | | class MissingCommand(TypeError): ... # noqa: N818
|
||||||
|
| |_^ I001
|
||||||
|
|
|
||||||
|
= help: Organize imports
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
1 1 | import json
|
||||||
|
2 |-
|
||||||
|
3 |-
|
||||||
|
4 |-
|
||||||
|
5 2 | from typing import Any, Sequence
|
||||||
|
6 |-
|
||||||
|
7 3 |
|
||||||
|
8 4 | class MissingCommand(TypeError): ... # noqa: N818
|
||||||
|
9 5 |
|
||||||
|
|
||||||
|
E30_isort.pyi:5:1: E303 [*] Too many blank lines (3)
|
||||||
|
|
|
||||||
|
5 | from typing import Any, Sequence
|
||||||
|
| ^^^^ E303
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
1 1 | import json
|
||||||
|
2 2 |
|
||||||
|
3 |-
|
||||||
|
4 |-
|
||||||
|
5 3 | from typing import Any, Sequence
|
||||||
|
6 4 |
|
||||||
|
7 5 |
|
||||||
|
|
||||||
|
E30_isort.pyi:8:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
8 | class MissingCommand(TypeError): ... # noqa: N818
|
||||||
|
| ^^^^^ E303
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
4 4 |
|
||||||
|
5 5 | from typing import Any, Sequence
|
||||||
|
6 6 |
|
||||||
|
7 |-
|
||||||
|
8 7 | class MissingCommand(TypeError): ... # noqa: N818
|
||||||
|
9 8 |
|
||||||
|
10 9 |
|
||||||
|
|
||||||
|
E30_isort.pyi:11:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
11 | class BackendProxy:
|
||||||
|
| ^^^^^ E303
|
||||||
|
12 | backend_module: str
|
||||||
|
13 | backend_object: str | None
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
7 7 |
|
||||||
|
8 8 | class MissingCommand(TypeError): ... # noqa: N818
|
||||||
|
9 9 |
|
||||||
|
10 |-
|
||||||
|
11 10 | class BackendProxy:
|
||||||
|
12 11 | backend_module: str
|
||||||
|
13 12 | backend_object: str | None
|
||||||
|
|
||||||
|
E30_isort.pyi:17:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
17 | if __name__ == "__main__":
|
||||||
|
| ^^ E303
|
||||||
|
18 | import abcd
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
13 13 | backend_object: str | None
|
||||||
|
14 14 | backend: Any
|
||||||
|
15 15 |
|
||||||
|
16 |-
|
||||||
|
17 16 | if __name__ == "__main__":
|
||||||
|
18 17 | import abcd
|
||||||
|
19 18 |
|
||||||
|
|
||||||
|
E30_isort.pyi:21:5: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
21 | abcd.foo()
|
||||||
|
| ^^^^ E303
|
||||||
|
22 |
|
||||||
|
23 | def __init__(self, backend_module: str, backend_obj: str | None) -> None: ...
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
17 17 | if __name__ == "__main__":
|
||||||
|
18 18 | import abcd
|
||||||
|
19 19 |
|
||||||
|
20 |-
|
||||||
|
21 20 | abcd.foo()
|
||||||
|
22 21 |
|
||||||
|
23 22 | def __init__(self, backend_module: str, backend_obj: str | None) -> None: ...
|
||||||
|
|
||||||
|
E30_isort.pyi:26:1: I001 [*] Import block is un-sorted or un-formatted
|
||||||
|
|
|
||||||
|
25 | if TYPE_CHECKING:
|
||||||
|
26 | / import os
|
||||||
|
27 | |
|
||||||
|
28 | |
|
||||||
|
29 | |
|
||||||
|
30 | | from typing_extensions import TypeAlias
|
||||||
|
31 | |
|
||||||
|
| |_^ I001
|
||||||
|
32 |
|
||||||
|
33 | abcd.foo()
|
||||||
|
|
|
||||||
|
= help: Organize imports
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
25 25 | if TYPE_CHECKING:
|
||||||
|
26 26 | import os
|
||||||
|
27 27 |
|
||||||
|
28 |-
|
||||||
|
29 |-
|
||||||
|
30 28 | from typing_extensions import TypeAlias
|
||||||
|
31 29 |
|
||||||
|
32 30 |
|
||||||
|
|
||||||
|
E30_isort.pyi:30:5: E303 [*] Too many blank lines (3)
|
||||||
|
|
|
||||||
|
30 | from typing_extensions import TypeAlias
|
||||||
|
| ^^^^ E303
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
25 25 | if TYPE_CHECKING:
|
||||||
|
26 26 | import os
|
||||||
|
27 27 |
|
||||||
|
28 |-
|
||||||
|
29 |-
|
||||||
|
30 28 | from typing_extensions import TypeAlias
|
||||||
|
31 29 |
|
||||||
|
32 30 |
|
||||||
|
|
||||||
|
E30_isort.pyi:33:5: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
33 | abcd.foo()
|
||||||
|
| ^^^^ E303
|
||||||
|
34 |
|
||||||
|
35 | def __call__(self, name: str, *args: Any, **kwargs: Any) -> Any:
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
29 29 |
|
||||||
|
30 30 | from typing_extensions import TypeAlias
|
||||||
|
31 31 |
|
||||||
|
32 |-
|
||||||
|
33 32 | abcd.foo()
|
||||||
|
34 33 |
|
||||||
|
35 34 | def __call__(self, name: str, *args: Any, **kwargs: Any) -> Any:
|
||||||
|
|
||||||
|
E30_isort.pyi:45:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
45 | def _exit(self) -> None: ...
|
||||||
|
| ^^^ E303
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
41 41 | def __call__2(self, name: str, *args: Any, **kwargs: Any) -> Any:
|
||||||
|
42 42 | ...
|
||||||
|
43 43 |
|
||||||
|
44 |-
|
||||||
|
45 44 | def _exit(self) -> None: ...
|
||||||
|
46 45 |
|
||||||
|
47 46 |
|
||||||
|
|
||||||
|
E30_isort.pyi:48:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
48 | def _optional_commands(self) -> dict[str, bool]: ...
|
||||||
|
| ^^^ E303
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
44 44 |
|
||||||
|
45 45 | def _exit(self) -> None: ...
|
||||||
|
46 46 |
|
||||||
|
47 |-
|
||||||
|
48 47 | def _optional_commands(self) -> dict[str, bool]: ...
|
||||||
|
49 48 |
|
||||||
|
50 49 |
|
||||||
|
|
||||||
|
E30_isort.pyi:51:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
51 | def run(argv: Sequence[str]) -> int: ...
|
||||||
|
| ^^^ E303
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
47 47 |
|
||||||
|
48 48 | def _optional_commands(self) -> dict[str, bool]: ...
|
||||||
|
49 49 |
|
||||||
|
50 |-
|
||||||
|
51 50 | def run(argv: Sequence[str]) -> int: ...
|
||||||
|
52 51 |
|
||||||
|
53 52 |
|
||||||
|
|
||||||
|
E30_isort.pyi:54:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
54 | def read_line(fd: int = 0) -> bytearray: ...
|
||||||
|
| ^^^ E303
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
50 50 |
|
||||||
|
51 51 | def run(argv: Sequence[str]) -> int: ...
|
||||||
|
52 52 |
|
||||||
|
53 |-
|
||||||
|
54 53 | def read_line(fd: int = 0) -> bytearray: ...
|
||||||
|
55 54 |
|
||||||
|
56 55 |
|
||||||
|
|
||||||
|
E30_isort.pyi:57:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
57 | def flush() -> None: ...
|
||||||
|
| ^^^ E303
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
53 53 |
|
||||||
|
54 54 | def read_line(fd: int = 0) -> bytearray: ...
|
||||||
|
55 55 |
|
||||||
|
56 |-
|
||||||
|
57 56 | def flush() -> None: ...
|
||||||
|
58 57 |
|
||||||
|
59 58 |
|
||||||
|
|
||||||
|
E30_isort.pyi:60:1: E303 [*] Too many blank lines (2)
|
||||||
|
|
|
||||||
|
60 | from typing import Any, Sequence
|
||||||
|
| ^^^^ E303
|
||||||
|
61 |
|
||||||
|
62 | class MissingCommand(TypeError): ... # noqa: N818
|
||||||
|
|
|
||||||
|
= help: Remove extraneous blank line(s)
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
56 56 |
|
||||||
|
57 57 | def flush() -> None: ...
|
||||||
|
58 58 |
|
||||||
|
59 |-
|
||||||
|
60 59 | from typing import Any, Sequence
|
||||||
|
61 60 |
|
||||||
|
62 61 | class MissingCommand(TypeError): ... # noqa: N818
|
Loading…
Add table
Add a link
Reference in a new issue