Skip to content

Commit

Permalink
Update fixes; change default to five
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Dec 4, 2023
1 parent cc81842 commit 372e369
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 22 deletions.
2 changes: 1 addition & 1 deletion crates/ruff_linter/src/codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Pylint, "R0913") => (RuleGroup::Stable, rules::pylint::rules::TooManyArguments),
(Pylint, "R0915") => (RuleGroup::Stable, rules::pylint::rules::TooManyStatements),
(Pylint, "R0916") => (RuleGroup::Preview, rules::pylint::rules::TooManyBooleanExpressions),
(Pylint, "R0917") => (RuleGroup::Stable, rules::pylint::rules::TooManyPositional),
(Pylint, "R0917") => (RuleGroup::Preview, rules::pylint::rules::TooManyPositional),
(Pylint, "R1701") => (RuleGroup::Stable, rules::pylint::rules::RepeatedIsinstanceCalls),
(Pylint, "R1704") => (RuleGroup::Preview, rules::pylint::rules::RedefinedArgumentFromLocal),
(Pylint, "R1711") => (RuleGroup::Stable, rules::pylint::rules::UselessReturn),
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_linter/src/rules/pylint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,12 @@ mod tests {
}

#[test]
fn max_pos_args() -> Result<()> {
fn max_positional_args() -> Result<()> {
let diagnostics = test_path(
Path::new("pylint/too_many_positional_params.py"),
&LinterSettings {
pylint: pylint::settings::Settings {
max_pos_args: 4,
max_positional_args: 4,
..pylint::settings::Settings::default()
},
..LinterSettings::for_rule(Rule::TooManyPositional)
Expand Down
42 changes: 27 additions & 15 deletions crates/ruff_linter/src/rules/pylint/rules/too_many_positional.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,45 @@
use ruff_diagnostics::{Violation, Diagnostic};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{Parameters, Stmt, identifier::Identifier};
use ruff_python_ast::{identifier::Identifier, Parameters, Stmt};

use crate::checkers::ast::Checker;

/// ## What it does
/// Checks for function definitions that include too many positional arguments.
///
/// By default, this rule allows up to five arguments, as configured by the
/// [`pylint.max-positional-args`] option.
///
/// ## Why is this bad?
/// The position of arguments that are not defined as keyword-only
/// becomes part of the function’s API. This encourages consumers of the API
/// to specify arguments positionally, making their code harder to read,
/// and complicating refactoring of the API, such as deprecating a parameter.
/// Functions with many arguments are harder to understand, maintain, and call.
/// This is especially true for functions with many positional arguments, as
/// providing arguments positionally is more error-prone and less clear to
/// readers than providing arguments by name.
///
/// Consider refactoring functions with many arguments into smaller functions
/// with fewer arguments, using objects to group related arguments, or
/// migrating to keyword-only arguments.
///
/// ## Example
/// ```python
/// def plot(x, y, z, color, mark, add_trendline):
/// ...
///
/// plot(1, 2, 3, 'r', '*', True)
///
///
/// plot(1, 2, 3, "r", "*", True)
/// ```
///
/// Use instead:
/// ```python
/// def plot(x, y, z, *, color, mark, add_trendline):
/// ...
///
/// plot(1, 2, 3, color='r', mark='*', add_trendline=True)
///
///
/// plot(1, 2, 3, color="r", mark="*", add_trendline=True)
/// ```
///
/// ## Options
/// - `pylint.max-positional-args`
#[violation]
pub struct TooManyPositional {
c_pos: usize,
Expand All @@ -42,9 +54,9 @@ impl Violation for TooManyPositional {
}
}

/// PLRR0917
/// PLR0917
pub(crate) fn too_many_positional(checker: &mut Checker, parameters: &Parameters, stmt: &Stmt) {
let num_positional = parameters
let num_positional_args = parameters
.args
.iter()
.chain(&parameters.posonlyargs)
Expand All @@ -55,11 +67,11 @@ pub(crate) fn too_many_positional(checker: &mut Checker, parameters: &Parameters
.is_match(&arg.parameter.name)
})
.count();
if num_positional > checker.settings.pylint.max_pos_args {
if num_positional_args > checker.settings.pylint.max_positional_args {
checker.diagnostics.push(Diagnostic::new(
TooManyPositional {
c_pos: num_positional,
max_pos: checker.settings.pylint.max_pos_args,
c_pos: num_positional_args,
max_pos: checker.settings.pylint.max_positional_args,
},
stmt.identifier(),
));
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_linter/src/rules/pylint/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub struct Settings {
pub allow_magic_value_types: Vec<ConstantType>,
pub allow_dunder_method_names: FxHashSet<String>,
pub max_args: usize,
pub max_pos_args: usize,
pub max_positional_args: usize,
pub max_returns: usize,
pub max_bool_expr: usize,
pub max_branches: usize,
Expand All @@ -53,7 +53,7 @@ impl Default for Settings {
allow_magic_value_types: vec![ConstantType::Str, ConstantType::Bytes],
allow_dunder_method_names: FxHashSet::default(),
max_args: 5,
max_pos_args: 3,
max_positional_args: 5,
max_returns: 6,
max_bool_expr: 5,
max_branches: 12,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
source: crates/ruff_linter/src/rules/pylint/mod.rs
---
too_many_positional.py:1:5: PLR0917 Too many positional arguments: (8/5)
|
1 | def f(x, y, z, t, u, v, w, r): # Too many positional arguments (8/3)
| ^ PLR0917
2 | pass
|

too_many_positional.py:21:5: PLR0917 Too many positional arguments: (6/5)
|
21 | def f(x, y, z, /, u, v, w): # Too many positional arguments (6/3)
| ^ PLR0917
22 | pass
|

too_many_positional.py:29:5: PLR0917 Too many positional arguments: (6/5)
|
29 | def f(x, y, z, a, b, c, *, u, v, w): # Too many positional arguments (6/3)
| ^ PLR0917
30 | pass
|


Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
source: crates/ruff_linter/src/rules/pylint/mod.rs
---
too_many_positional_params.py:3:5: PLR0917 Too many positional arguments: (7/4)
|
1 | # Too many positional arguments (7/4) for max_positional=4
2 | # OK for dummy_variable_rgx ~ "skip_.*"
3 | def f(w, x, y, z, skip_t, skip_u, skip_v):
| ^ PLR0917
4 | pass
|

too_many_positional_params.py:9:5: PLR0917 Too many positional arguments: (7/4)
|
7 | # Too many positional arguments (7/4) for max_args=4
8 | # Too many positional arguments (7/3) for dummy_variable_rgx ~ "skip_.*"
9 | def f(w, x, y, z, t, u, v):
| ^ PLR0917
10 | pass
|


6 changes: 4 additions & 2 deletions crates/ruff_workspace/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2638,7 +2638,7 @@ pub struct PylintOptions {
/// Maximum number of positional arguments allowed for a function or method definition
/// (see: `PLR0917`).
#[option(default = r"3", value_type = "int", example = r"max-pos-args = 3")]
pub max_pos_args: Option<usize>,
pub max_positional_args: Option<usize>,

/// Maximum number of statements allowed for a function or method body (see:
/// `PLR0915`).
Expand Down Expand Up @@ -2668,7 +2668,9 @@ impl PylintOptions {
.unwrap_or(defaults.allow_magic_value_types),
allow_dunder_method_names: self.allow_dunder_method_names.unwrap_or_default(),
max_args: self.max_args.unwrap_or(defaults.max_args),
max_pos_args: self.max_pos_args.unwrap_or(defaults.max_pos_args),
max_positional_args: self
.max_positional_args
.unwrap_or(defaults.max_positional_args),
max_bool_expr: self.max_bool_expr.unwrap_or(defaults.max_bool_expr),
max_returns: self.max_returns.unwrap_or(defaults.max_returns),
max_branches: self.max_branches.unwrap_or(defaults.max_branches),
Expand Down
10 changes: 10 additions & 0 deletions ruff.schema.json

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

0 comments on commit 372e369

Please sign in to comment.