mirror of https://github.com/astral-sh/ruff
Implement pylint too-many-lines (C0302)
This commit is contained in:
parent
e548ce1ca9
commit
ada46d883d
|
|
@ -259,6 +259,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -261,6 +261,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -372,6 +372,7 @@ linter.pylint.max_statements = 50
|
|||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pylint.max_module_lines = 1000
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@ pub(crate) fn check_physical_lines(
|
|||
if enforce_copyright_notice {
|
||||
missing_copyright_notice(locator, settings, context);
|
||||
}
|
||||
|
||||
if context.is_rule_enabled(Rule::TooManyLines) {
|
||||
pylint::rules::too_many_lines(locator, settings, context);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
(Pylint, "C0206") => rules::pylint::rules::DictIndexMissingItems,
|
||||
(Pylint, "C0207") => rules::pylint::rules::MissingMaxsplitArg,
|
||||
(Pylint, "C0208") => rules::pylint::rules::IterationOverSet,
|
||||
(Pylint, "C0302") => rules::pylint::rules::TooManyLines,
|
||||
(Pylint, "C0414") => rules::pylint::rules::UselessImportAlias,
|
||||
(Pylint, "C0415") => rules::pylint::rules::ImportOutsideTopLevel,
|
||||
(Pylint, "C1802") => rules::pylint::rules::LenTest,
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ impl Rule {
|
|||
| Rule::MissingCopyrightNotice
|
||||
| Rule::MissingNewlineAtEndOfFile
|
||||
| Rule::MixedSpacesAndTabs
|
||||
| Rule::TooManyLines
|
||||
| Rule::TrailingWhitespace => LintSource::PhysicalLines,
|
||||
Rule::AmbiguousUnicodeCharacterComment
|
||||
| Rule::BlanketTypeIgnore
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
//! Settings for the `flake8-lineleak` plugin.
|
||||
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use ruff_macros::CacheKey;
|
||||
|
||||
use crate::display_settings;
|
||||
|
||||
#[derive(Debug, Clone, CacheKey)]
|
||||
pub struct Settings {
|
||||
pub max_line_count: usize,
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
max_line_count: 100,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Settings {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
display_settings! {
|
||||
formatter = f,
|
||||
namespace = "linter.flake8_lineleak",
|
||||
fields = [
|
||||
self.max_line_count,
|
||||
]
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -444,4 +444,90 @@ mod tests {
|
|||
assert_diagnostics!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn too_many_lines_below_limit() {
|
||||
use crate::test::test_snippet;
|
||||
|
||||
let diagnostics = test_snippet(
|
||||
r"
|
||||
# Line 1
|
||||
# Line 2
|
||||
# Line 3
|
||||
import os
|
||||
"
|
||||
.trim(),
|
||||
&LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
pylint: pylint::settings::Settings {
|
||||
max_module_lines: 1000,
|
||||
..pylint::settings::Settings::default()
|
||||
},
|
||||
..LinterSettings::for_rules(vec![Rule::TooManyLines])
|
||||
},
|
||||
);
|
||||
assert_diagnostics!(diagnostics);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn too_many_lines_exceeds_limit() {
|
||||
use crate::test::test_snippet;
|
||||
|
||||
let diagnostics = test_snippet(
|
||||
r"
|
||||
# Line 1
|
||||
# Line 2
|
||||
# Line 3
|
||||
# Line 4
|
||||
# Line 5
|
||||
# Line 6
|
||||
# Line 7
|
||||
# Line 8
|
||||
# Line 9
|
||||
# Line 10
|
||||
# Line 11
|
||||
import os
|
||||
"
|
||||
.trim(),
|
||||
&LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
pylint: pylint::settings::Settings {
|
||||
max_module_lines: 10,
|
||||
..pylint::settings::Settings::default()
|
||||
},
|
||||
..LinterSettings::for_rules(vec![Rule::TooManyLines])
|
||||
},
|
||||
);
|
||||
assert!(!diagnostics.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn too_many_lines_at_limit() {
|
||||
use crate::test::test_snippet;
|
||||
|
||||
let diagnostics = test_snippet(
|
||||
r"
|
||||
# Line 1
|
||||
# Line 2
|
||||
# Line 3
|
||||
# Line 4
|
||||
# Line 5
|
||||
# Line 6
|
||||
# Line 7
|
||||
# Line 8
|
||||
# Line 9
|
||||
# Line 10
|
||||
"
|
||||
.trim(),
|
||||
&LinterSettings {
|
||||
preview: PreviewMode::Enabled,
|
||||
pylint: pylint::settings::Settings {
|
||||
max_module_lines: 10,
|
||||
..pylint::settings::Settings::default()
|
||||
},
|
||||
..LinterSettings::for_rules(vec![Rule::TooManyLines])
|
||||
},
|
||||
);
|
||||
assert_diagnostics!(diagnostics);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ pub(crate) use sys_exit_alias::*;
|
|||
pub(crate) use too_many_arguments::*;
|
||||
pub(crate) use too_many_boolean_expressions::*;
|
||||
pub(crate) use too_many_branches::*;
|
||||
pub(crate) use too_many_lines::*;
|
||||
pub(crate) use too_many_locals::*;
|
||||
pub(crate) use too_many_nested_blocks::*;
|
||||
pub(crate) use too_many_positional_arguments::*;
|
||||
|
|
@ -194,6 +195,7 @@ mod sys_exit_alias;
|
|||
mod too_many_arguments;
|
||||
mod too_many_boolean_expressions;
|
||||
mod too_many_branches;
|
||||
mod too_many_lines;
|
||||
mod too_many_locals;
|
||||
mod too_many_nested_blocks;
|
||||
mod too_many_positional_arguments;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_text_size::TextRange;
|
||||
|
||||
use crate::Locator;
|
||||
use crate::Violation;
|
||||
use crate::checkers::ast::LintContext;
|
||||
use crate::settings::LinterSettings;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for modules with too many lines.
|
||||
///
|
||||
/// By default, this rule allows up to 1000 lines, as configured by the
|
||||
/// [`lint.pylint.max-module-lines`] option.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Modules with many lines are generally harder to read and understand.
|
||||
/// Extracting functionality into separate modules can improve code organization
|
||||
/// and maintainability.
|
||||
///
|
||||
/// ## Example
|
||||
/// A module with 1500 lines when `max-module-lines` is set to 1000 will trigger
|
||||
/// this rule.
|
||||
///
|
||||
/// ## Options
|
||||
/// - `lint.pylint.max-module-lines`
|
||||
#[derive(ViolationMetadata)]
|
||||
#[violation_metadata(preview_since = "v0.14.9")]
|
||||
pub(crate) struct TooManyLines {
|
||||
actual_lines: usize,
|
||||
max_lines: usize,
|
||||
}
|
||||
|
||||
impl Violation for TooManyLines {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let TooManyLines {
|
||||
actual_lines,
|
||||
max_lines,
|
||||
} = self;
|
||||
format!("Too many lines in module ({actual_lines}/{max_lines})")
|
||||
}
|
||||
}
|
||||
|
||||
/// C0302
|
||||
pub(crate) fn too_many_lines(locator: &Locator, settings: &LinterSettings, context: &LintContext) {
|
||||
let actual_lines = locator.contents().lines().count();
|
||||
let max_lines = settings.pylint.max_module_lines;
|
||||
|
||||
if actual_lines > max_lines {
|
||||
context.report_diagnostic(
|
||||
TooManyLines {
|
||||
actual_lines,
|
||||
max_lines,
|
||||
},
|
||||
TextRange::default(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -61,6 +61,7 @@ pub struct Settings {
|
|||
pub max_public_methods: usize,
|
||||
pub max_locals: usize,
|
||||
pub max_nested_blocks: usize,
|
||||
pub max_module_lines: usize,
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
|
|
@ -77,6 +78,7 @@ impl Default for Settings {
|
|||
max_public_methods: 20,
|
||||
max_locals: 15,
|
||||
max_nested_blocks: 5,
|
||||
max_module_lines: 1000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,7 +99,8 @@ impl fmt::Display for Settings {
|
|||
self.max_statements,
|
||||
self.max_public_methods,
|
||||
self.max_locals,
|
||||
self.max_nested_blocks
|
||||
self.max_nested_blocks,
|
||||
self.max_module_lines
|
||||
]
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||
---
|
||||
|
||||
|
|
@ -3343,6 +3343,14 @@ pub struct PylintOptions {
|
|||
example = r"max-nested-blocks = 10"
|
||||
)]
|
||||
pub max_nested_blocks: Option<usize>,
|
||||
|
||||
/// Maximum number of lines allowed in a module (see `PLC0302`).
|
||||
#[option(
|
||||
default = r"1000",
|
||||
value_type = "int",
|
||||
example = r"max-module-lines = 1500"
|
||||
)]
|
||||
pub max_module_lines: Option<usize>,
|
||||
}
|
||||
|
||||
impl PylintOptions {
|
||||
|
|
@ -3367,6 +3375,7 @@ impl PylintOptions {
|
|||
.unwrap_or(defaults.max_public_methods),
|
||||
max_locals: self.max_locals.unwrap_or(defaults.max_locals),
|
||||
max_nested_blocks: self.max_nested_blocks.unwrap_or(defaults.max_nested_blocks),
|
||||
max_module_lines: self.max_module_lines.unwrap_or(defaults.max_module_lines),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2794,6 +2794,15 @@
|
|||
"format": "uint",
|
||||
"minimum": 0
|
||||
},
|
||||
"max-module-lines": {
|
||||
"description": "Maximum number of lines allowed in a module (see `PLC0302`).",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint",
|
||||
"minimum": 0
|
||||
},
|
||||
"max-nested-blocks": {
|
||||
"description": "Maximum number of nested blocks allowed within a function or method body\n(see `PLR1702`).",
|
||||
"type": [
|
||||
|
|
@ -3590,6 +3599,9 @@
|
|||
"PLC0206",
|
||||
"PLC0207",
|
||||
"PLC0208",
|
||||
"PLC03",
|
||||
"PLC030",
|
||||
"PLC0302",
|
||||
"PLC04",
|
||||
"PLC041",
|
||||
"PLC0414",
|
||||
|
|
|
|||
Loading…
Reference in New Issue