Skip to content

Commit

Permalink
Add custom-dunder-method-names setting for PLW3201
Browse files Browse the repository at this point in the history
  • Loading branch information
ThiefMaster committed Nov 21, 2023
1 parent 5373759 commit a454793
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __doc__(self):
return "Docstring"

# Added in Python 3.12
def __buffer__(self):
def __buffer__(self):
return memoryview(b'')

def __release_buffer__(self, buf):
Expand Down Expand Up @@ -83,6 +83,10 @@ def _missing_(cls, value):
def _(self):
pass

# Allow custom dunder names (via setting)
def __special_custom_magic__(self):
pass


def __foo_bar__(): # this is not checked by the [bad-dunder-name] rule
...
11 changes: 10 additions & 1 deletion crates/ruff_linter/src/rules/pylint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod tests {

use anyhow::Result;
use regex::Regex;
use rustc_hash::FxHashSet;
use test_case::test_case;

use crate::assert_messages;
Expand Down Expand Up @@ -157,7 +158,15 @@ mod tests {
let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy());
let diagnostics = test_path(
Path::new("pylint").join(path).as_path(),
&LinterSettings::for_rule(rule_code),
&LinterSettings {
pylint: pylint::settings::Settings {
custom_dunder_method_names: FxHashSet::from_iter([
"__special_custom_magic__".to_string()
]),
..pylint::settings::Settings::default()
},
..LinterSettings::for_rule(rule_code)
},
)?;
assert_messages!(snapshot, diagnostics);
Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ use crate::checkers::ast::Checker;
/// that diverges from standard Python dunder methods could potentially
/// confuse someone reading the code.
///
/// Non-standard dunder methods that are required by some library you're
/// using can be defined using the [`pylint.custom-dunder-method-names`]
/// configuration option.
///
/// This rule will detect all methods starting and ending with at least
/// one underscore (e.g., `_str_`), but ignores known dunder methods (like
/// `__init__`), as well as methods that are marked with `@override`.
Expand All @@ -35,6 +39,9 @@ use crate::checkers::ast::Checker;
/// def __init__(self):
/// ...
/// ```
///
/// ## Options
/// - `pylint.custom-dunder-method-names`
#[violation]
pub struct BadDunderMethodName {
name: String,
Expand All @@ -54,7 +61,14 @@ pub(crate) fn bad_dunder_method_name(checker: &mut Checker, class_body: &[Stmt])
.iter()
.filter_map(ruff_python_ast::Stmt::as_function_def_stmt)
.filter(|method| {
if is_known_dunder_method(&method.name) || matches!(method.name.as_str(), "_") {
if is_known_dunder_method(&method.name)
|| checker
.settings
.pylint
.custom_dunder_method_names
.contains(method.name.as_str())
|| matches!(method.name.as_str(), "_")
{
return false;
}
method.name.starts_with('_') && method.name.ends_with('_')
Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_linter/src/rules/pylint/settings.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Settings for the `pylint` plugin.
use rustc_hash::FxHashSet;
use serde::{Deserialize, Serialize};

use ruff_macros::CacheKey;
Expand Down Expand Up @@ -36,6 +37,7 @@ impl ConstantType {
#[derive(Debug, CacheKey)]
pub struct Settings {
pub allow_magic_value_types: Vec<ConstantType>,
pub custom_dunder_method_names: FxHashSet<String>,
pub max_args: usize,
pub max_returns: usize,
pub max_bool_expr: usize,
Expand All @@ -48,6 +50,7 @@ impl Default for Settings {
fn default() -> Self {
Self {
allow_magic_value_types: vec![ConstantType::Str, ConstantType::Bytes],
custom_dunder_method_names: FxHashSet::default(),
max_args: 5,
max_returns: 6,
max_bool_expr: 5,
Expand Down
11 changes: 11 additions & 0 deletions crates/ruff_workspace/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2545,6 +2545,16 @@ pub struct PylintOptions {
)]
pub allow_magic_value_types: Option<Vec<ConstantType>>,

/// Custom names to allow for dunder methods (see: `PLW3201`).
#[option(
default = r#"[]"#,
value_type = r#"list[str]"#,
example = r#"
custom-dunder-method-names = ["__tablename__", "__table_args__"]
"#
)]
pub custom_dunder_method_names: Option<FxHashSet<String>>,

/// Maximum number of branches allowed for a function or method body (see:
/// `PLR0912`).
#[option(default = r"12", value_type = "int", example = r"max-branches = 12")]
Expand Down Expand Up @@ -2586,6 +2596,7 @@ impl PylintOptions {
allow_magic_value_types: self
.allow_magic_value_types
.unwrap_or(defaults.allow_magic_value_types),
custom_dunder_method_names: self.custom_dunder_method_names.unwrap_or_default(),
max_args: self.max_args.unwrap_or(defaults.max_args),
max_bool_expr: self.max_bool_expr.unwrap_or(defaults.max_bool_expr),
max_returns: self.max_returns.unwrap_or(defaults.max_returns),
Expand Down
11 changes: 11 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 a454793

Please sign in to comment.