From 0ce0aa82f7417d64d76446c74d5b88fd17dbde37 Mon Sep 17 00:00:00 2001 From: augustelalande Date: Sat, 25 Oct 2025 17:19:55 -0400 Subject: [PATCH] implement doc101 --- .../test/fixtures/pydoclint/DOC101_google.py | 387 ++++++++++++++ .../test/fixtures/pydoclint/DOC101_numpy.py | 495 ++++++++++++++++++ .../src/checkers/ast/analyze/definitions.rs | 1 + crates/ruff_linter/src/codes.rs | 1 + crates/ruff_linter/src/rules/pydoclint/mod.rs | 2 + .../rules/pydoclint/rules/check_docstring.rs | 105 ++++ ...ng-missing-parameter_DOC101_google.py.snap | 157 ++++++ ...ing-missing-parameter_DOC101_numpy.py.snap | 167 ++++++ ruff.schema.json | 1 + 9 files changed, 1316 insertions(+) create mode 100644 crates/ruff_linter/resources/test/fixtures/pydoclint/DOC101_google.py create mode 100644 crates/ruff_linter/resources/test/fixtures/pydoclint/DOC101_numpy.py create mode 100644 crates/ruff_linter/src/rules/pydoclint/snapshots/ruff_linter__rules__pydoclint__tests__docstring-missing-parameter_DOC101_google.py.snap create mode 100644 crates/ruff_linter/src/rules/pydoclint/snapshots/ruff_linter__rules__pydoclint__tests__docstring-missing-parameter_DOC101_numpy.py.snap diff --git a/crates/ruff_linter/resources/test/fixtures/pydoclint/DOC101_google.py b/crates/ruff_linter/resources/test/fixtures/pydoclint/DOC101_google.py new file mode 100644 index 0000000000..76a7917db7 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pydoclint/DOC101_google.py @@ -0,0 +1,387 @@ +# OK +def add_numbers(a, b): + """ + Adds two numbers and returns the result. + + Args: + a (int): The first number to add. + b (int): The second number to add. + + Returns: + int: The sum of the two numbers. + """ + return a + b + + +# OK +def multiply_list_elements(lst, multiplier): + """ + Multiplies each element in a list by a given multiplier. + + Args: + lst (list of int): A list of integers. + multiplier (int): The multiplier for each element in the list. + + Returns: + list of int: A new list with each element multiplied. + """ + return [x * multiplier for x in lst] + + +# OK +def find_max_value(numbers): + """ + Finds the maximum value in a list of numbers. + + Args: + numbers (list of int): A list of integers to search through. + + Returns: + int: The maximum value found in the list. + """ + return max(numbers) + + +# OK +def create_user_profile(name, age, email, location="here"): + """ + Creates a user profile with basic information. + + Args: + name (str): The name of the user. + age (int): The age of the user. + email (str): The user's email address. + location (str): The location of the user. + + Returns: + dict: A dictionary containing the user's profile. + """ + return { + 'name': name, + 'age': age, + 'email': email, + 'location': location + } + + +# OK +def calculate_total_price(item_prices, tax_rate, discount): + """ + Calculates the total price after applying tax and a discount. + + Args: + item_prices (list of float): A list of prices for each item. + tax_rate (float): The tax rate to apply. + discount (float): The discount to subtract from the total. + + Returns: + float: The final total price after tax and discount. + """ + total = sum(item_prices) + total_with_tax = total + (total * tax_rate) + final_total = total_with_tax - discount + return final_total + + +# OK +def send_email(subject, body, to_address, cc_address=None, bcc_address=None): + """ + Sends an email to the specified recipients. + + Args: + subject (str): The subject of the email. + body (str): The content of the email. + to_address (str): The recipient's email address. + cc_address (str, optional): The email address for CC. Defaults to None. + bcc_address (str, optional): The email address for BCC. Defaults to None. + + Returns: + bool: True if the email was sent successfully, False otherwise. + """ + return True + + +# OK +def concatenate_strings(separator, *args): + """ + Concatenates multiple strings with a specified separator. + + Args: + separator (str): The separator to use between strings. + *args (str): Variable length argument list of strings to concatenate. + + Returns: + str: A single concatenated string. + """ + return separator.join(args) + + +# OK +def process_order(order_id, *items, **details): + """ + Processes an order with a list of items and optional order details. + + Args: + order_id (int): The unique identifier for the order. + *items (str): Variable length argument list of items in the order. + **details (dict): Additional details such as shipping method and address. + + Returns: + dict: A dictionary containing the order summary. + """ + return { + 'order_id': order_id, + 'items': items, + 'details': details + } + + +class Calculator: + """ + A simple calculator class that can perform basic arithmetic operations. + """ + + # OK + def __init__(self, value=0): + """ + Initializes the calculator with an initial value. + + Args: + value (int, optional): The initial value of the calculator. Defaults to 0. + """ + self.value = value + + # OK + def add(self, number): + """ + Adds a number to the current value. + + Args: + number (int or float): The number to add to the current value. + + Returns: + int or float: The updated value after addition. + """ + self.value += number + number2 + return self.value + + # OK + @classmethod + def from_string(cls, value_str): + """ + Creates a Calculator instance from a string representation of a number. + + Args: + value_str (str): The string representing the initial value. + + Returns: + Calculator: A new instance of Calculator initialized with the value from the string. + """ + value = float(value_str) + return cls(value) + + # OK + @staticmethod + def is_valid_number(number): + """ + Checks if a given number is valid (int or float). + + Args: + number (any): The value to check. + + Returns: + bool: True if the number is valid, False otherwise. + """ + return isinstance(number, (int, float)) + + +# DOC101 +def add_numbers(a, b): + """ + Adds two numbers and returns the result. + + Args: + a (int): The first number to add. + + Returns: + int: The sum of the two numbers. + """ + return a + b + + +# DOC101 +def multiply_list_elements(lst, multiplier): + """ + Multiplies each element in a list by a given multiplier. + + Args: + lst (list of int): A list of integers. + + Returns: + list of int: A new list with each element multiplied. + """ + return [x * multiplier for x in lst] + + +# DOC101 +def find_max_value(numbers): + """ + Finds the maximum value in a list of numbers. + + Returns: + int: The maximum value found in the list. + """ + return max(numbers) + + +# DOC101 +def create_user_profile(name, age, email, location="here"): + """ + Creates a user profile with basic information. + + Args: + email (str): The user's email address. + location (str): The location of the user. + + Returns: + dict: A dictionary containing the user's profile. + """ + return { + 'name': name, + 'age': age, + 'email': email, + 'location': location + } + + +# DOC101 +def calculate_total_price(item_prices, tax_rate, discount): + """ + Calculates the total price after applying tax and a discount. + + Args: + item_prices (list of float): A list of prices for each item. + + Returns: + float: The final total price after tax and discount. + """ + total = sum(item_prices) + total_with_tax = total + (total * tax_rate) + final_total = total_with_tax - discount + return final_total + + +# DOC101 +def send_email(subject, body, to_address, cc_address=None, bcc_address=None): + """ + Sends an email to the specified recipients. + + Args: + subject (str): The subject of the email. + body (str): The content of the email. + to_address (str): The recipient's email address. + + Returns: + bool: True if the email was sent successfully, False otherwise. + """ + return True + + +# DOC101 +def concatenate_strings(separator, *args): + """ + Concatenates multiple strings with a specified separator. + + Args: + separator (str): The separator to use between strings. + + Returns: + str: A single concatenated string. + """ + return separator.join(args) + + +# DOC101 +def process_order(order_id, *items, **details): + """ + Processes an order with a list of items and optional order details. + + Args: + order_id (int): The unique identifier for the order. + + Returns: + dict: A dictionary containing the order summary. + """ + return { + 'order_id': order_id, + 'items': items, + 'details': details + } + + +class Calculator: + """ + A simple calculator class that can perform basic arithmetic operations. + """ + + # DOC101 + def __init__(self, value=0): + """ + Initializes the calculator with an initial value. + + Returns: + None + """ + self.value = value + + # DOC101 + def add(self, number, number2): + """ + Adds a number to the current value. + + Args: + number (int or float): The number to add to the current value. + + Returns: + int or float: The updated value after addition. + """ + self.value += number + number2 + return self.value + + # DOC101 + @classmethod + def from_string(cls, value_str): + """ + Creates a Calculator instance from a string representation of a number. + + Returns: + Calculator: A new instance of Calculator initialized with the value from the string. + """ + value = float(value_str) + return cls(value) + + # DOC101 + @staticmethod + def is_valid_number(number): + """ + Checks if a given number is valid (int or float). + + Returns: + bool: True if the number is valid, False otherwise. + """ + return isinstance(number, (int, float)) + + # OK + @classmethod + def from_bytes(cls, value_bytes): + """ + Creates a Calculator instance from a bytes representation of a number. + + Args: + value_bytes (bytes): Bytes. + + Returns: + Calculator: A new instance of Calculator initialized with the value from the string. + """ + value = float(value_bytes) + return cls(value) diff --git a/crates/ruff_linter/resources/test/fixtures/pydoclint/DOC101_numpy.py b/crates/ruff_linter/resources/test/fixtures/pydoclint/DOC101_numpy.py new file mode 100644 index 0000000000..4f47f905a6 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pydoclint/DOC101_numpy.py @@ -0,0 +1,495 @@ +# OK +def add_numbers(a, b): + """ + Adds two numbers and returns the result. + + Parameters + ---------- + a : int + The first number to add. + b : int + The second number to add. + + Returns + ------- + int + The sum of the two numbers. + """ + return a + b + + +# OK +def multiply_list_elements(lst, multiplier): + """ + Multiplies each element in a list by a given multiplier. + + Parameters + ---------- + lst : list of int + A list of integers. + multiplier : int + The multiplier for each element in the list. + + Returns + ------- + list of int + A new list with each element multiplied. + """ + return [x * multiplier for x in lst] + + +# OK +def find_max_value(numbers): + """ + Finds the maximum value in a list of numbers. + + Parameters + ---------- + numbers : list of int + A list of integers to search through. + + Returns + ------- + int + The maximum value found in the list. + """ + return max(numbers) + + +# OK +def create_user_profile(name, age, email, location="here"): + """ + Creates a user profile with basic information. + + Parameters + ---------- + name : str + The name of the user. + age : int + The age of the user. + email : str + The user's email address. + location : str, optional + The location of the user, by default "here". + + Returns + ------- + dict + A dictionary containing the user's profile. + """ + return { + 'name': name, + 'age': age, + 'email': email, + 'location': location + } + + +# OK +def calculate_total_price(item_prices, tax_rate, discount): + """ + Calculates the total price after applying tax and a discount. + + Parameters + ---------- + item_prices : list of float + A list of prices for each item. + tax_rate : float + The tax rate to apply. + discount : float + The discount to subtract from the total. + + Returns + ------- + float + The final total price after tax and discount. + """ + total = sum(item_prices) + total_with_tax = total + (total * tax_rate) + final_total = total_with_tax - discount + return final_total + + +# OK +def send_email(subject, body, to_address, cc_address=None, bcc_address=None): + """ + Sends an email to the specified recipients. + + Parameters + ---------- + subject : str + The subject of the email. + body : str + The content of the email. + to_address : str + The recipient's email address. + cc_address : str, optional + The email address for CC, by default None. + bcc_address : str, optional + The email address for BCC, by default None. + + Returns + ------- + bool + True if the email was sent successfully, False otherwise. + """ + return True + + +# OK +def concatenate_strings(separator, *args): + """ + Concatenates multiple strings with a specified separator. + + Parameters + ---------- + separator : str + The separator to use between strings. + *args : str + Variable length argument list of strings to concatenate. + + Returns + ------- + str + A single concatenated string. + """ + return separator.join(args) + + +# OK +def process_order(order_id, *items, **details): + """ + Processes an order with a list of items and optional order details. + + Parameters + ---------- + order_id : int + The unique identifier for the order. + *items : str + Variable length argument list of items in the order. + **details : dict + Additional details such as shipping method and address. + + Returns + ------- + dict + A dictionary containing the order summary. + """ + return { + 'order_id': order_id, + 'items': items, + 'details': details + } + + +class Calculator: + """ + A simple calculator class that can perform basic arithmetic operations. + """ + + # OK + def __init__(self, value=0): + """ + Initializes the calculator with an initial value. + + Parameters + ---------- + value : int, optional + The initial value of the calculator, by default 0. + """ + self.value = value + + # OK + def add(self, number, number2): + """ + Adds two numbers to the current value. + + Parameters + ---------- + number : int or float + The first number to add. + number2 : int or float + The second number to add. + + Returns + ------- + int or float + The updated value after addition. + """ + self.value += number + number2 + return self.value + + # OK + @classmethod + def from_string(cls, value_str): + """ + Creates a Calculator instance from a string representation of a number. + + Parameters + ---------- + value_str : str + The string representing the initial value. + + Returns + ------- + Calculator + A new instance of Calculator initialized with the value from the string. + """ + value = float(value_str) + return cls(value) + + # OK + @staticmethod + def is_valid_number(number): + """ + Checks if a given number is valid (int or float). + + Parameters + ---------- + number : any + The value to check. + + Returns + ------- + bool + True if the number is valid, False otherwise. + """ + return isinstance(number, (int, float)) + + +# DOC101 +def add_numbers(a, b): + """ + Adds two numbers and returns the result. + + Parameters + ---------- + a : int + The first number to add. + + Returns + ------- + int + The sum of the two numbers. + """ + return a + b + + +# DOC101 +def multiply_list_elements(lst, multiplier): + """ + Multiplies each element in a list by a given multiplier. + + Parameters + ---------- + lst : list of int + A list of integers. + + Returns + ------- + list of int + A new list with each element multiplied. + """ + return [x * multiplier for x in lst] + + +# DOC101 +def find_max_value(numbers): + """ + Finds the maximum value in a list of numbers. + + Returns + ------- + int + The maximum value found in the list. + """ + return max(numbers) + + +# DOC101 +def create_user_profile(name, age, email, location="here"): + """ + Creates a user profile with basic information. + + Parameters + ---------- + email : str + The user's email address. + location : str, optional + The location of the user, by default "here". + + Returns + ------- + dict + A dictionary containing the user's profile. + """ + return { + 'name': name, + 'age': age, + 'email': email, + 'location': location + } + + +# DOC101 +def calculate_total_price(item_prices, tax_rate, discount): + """ + Calculates the total price after applying tax and a discount. + + Parameters + ---------- + item_prices : list of float + A list of prices for each item. + + Returns + ------- + float + The final total price after tax and discount. + """ + total = sum(item_prices) + total_with_tax = total + (total * tax_rate) + final_total = total_with_tax - discount + return final_total + + +# DOC101 +def send_email(subject, body, to_address, cc_address=None, bcc_address=None): + """ + Sends an email to the specified recipients. + + Parameters + ---------- + subject : str + The subject of the email. + body : str + The content of the email. + to_address : str + The recipient's email address. + + Returns + ------- + bool + True if the email was sent successfully, False otherwise. + """ + return True + + +# DOC101 +def concatenate_strings(separator, *args): + """ + Concatenates multiple strings with a specified separator. + + Parameters + ---------- + separator : str + The separator to use between strings. + + Returns + ------- + str + A single concatenated string. + """ + return separator.join(args) + + +# DOC101 +def process_order(order_id, *items, **details): + """ + Processes an order with a list of items and optional order details. + + Parameters + ---------- + order_id : int + The unique identifier for the order. + + Returns + ------- + dict + A dictionary containing the order summary. + """ + return { + 'order_id': order_id, + 'items': items, + 'details': details + } + + +class Calculator: + """ + A simple calculator class that can perform basic arithmetic operations. + """ + + # DOC101 + def __init__(self, value=0): + """ + Initializes the calculator with an initial value. + + """ + self.value = value + + # DOC101 + def add(self, number, number2): + """ + Adds two numbers to the current value. + + Parameters + ---------- + number : int or float + The first number to add. + + Returns + ------- + int or float + The updated value after addition. + """ + self.value += number + number2 + return self.value + + # DOC101 + @classmethod + def from_string(cls, value_str): + """ + Creates a Calculator instance from a string representation of a number. + + Returns + ------- + Calculator + A new instance of Calculator initialized with the value from the string. + """ + value = float(value_str) + return cls(value) + + # DOC101 + @staticmethod + def is_valid_number(number): + """ + Checks if a given number is valid (int or float). + + Returns + ------- + bool + True if the number is valid, False otherwise. + """ + return isinstance(number, (int, float)) + +# OK +def function_with_pep484_type_annotations(param1: int, param2: str) -> bool: + """Example function with PEP 484 type annotations. + + The return type must be duplicated in the docstring to comply + with the NumPy docstring style. + + Parameters + ---------- + param1 + The first parameter. + param2 + The second parameter. + + Returns + ------- + bool + True if successful, False otherwise. + + """ + return False diff --git a/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs b/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs index 4a3fe560be..85ee39de73 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/definitions.rs @@ -81,6 +81,7 @@ pub(crate) fn definitions(checker: &mut Checker) { Rule::UndocumentedPublicPackage, ]); let enforce_pydoclint = checker.any_rule_enabled(&[ + Rule::DocstringMissingParameter, Rule::DocstringExtraneousParameter, Rule::DocstringMissingReturns, Rule::DocstringExtraneousReturns, diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index 172841dc7c..c2134237d5 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -991,6 +991,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (FastApi, "003") => rules::fastapi::rules::FastApiUnusedPathParameter, // pydoclint + (Pydoclint, "101") => rules::pydoclint::rules::DocstringMissingParameter, (Pydoclint, "102") => rules::pydoclint::rules::DocstringExtraneousParameter, (Pydoclint, "201") => rules::pydoclint::rules::DocstringMissingReturns, (Pydoclint, "202") => rules::pydoclint::rules::DocstringExtraneousReturns, diff --git a/crates/ruff_linter/src/rules/pydoclint/mod.rs b/crates/ruff_linter/src/rules/pydoclint/mod.rs index 69326b0c51..ae6c95eba2 100644 --- a/crates/ruff_linter/src/rules/pydoclint/mod.rs +++ b/crates/ruff_linter/src/rules/pydoclint/mod.rs @@ -28,6 +28,7 @@ mod tests { Ok(()) } + #[test_case(Rule::DocstringMissingParameter, Path::new("DOC101_google.py"))] #[test_case(Rule::DocstringExtraneousParameter, Path::new("DOC102_google.py"))] #[test_case(Rule::DocstringMissingReturns, Path::new("DOC201_google.py"))] #[test_case(Rule::DocstringExtraneousReturns, Path::new("DOC202_google.py"))] @@ -51,6 +52,7 @@ mod tests { Ok(()) } + #[test_case(Rule::DocstringMissingParameter, Path::new("DOC101_numpy.py"))] #[test_case(Rule::DocstringExtraneousParameter, Path::new("DOC102_numpy.py"))] #[test_case(Rule::DocstringMissingReturns, Path::new("DOC201_numpy.py"))] #[test_case(Rule::DocstringExtraneousReturns, Path::new("DOC202_numpy.py"))] diff --git a/crates/ruff_linter/src/rules/pydoclint/rules/check_docstring.rs b/crates/ruff_linter/src/rules/pydoclint/rules/check_docstring.rs index dd88250952..c52cadb972 100644 --- a/crates/ruff_linter/src/rules/pydoclint/rules/check_docstring.rs +++ b/crates/ruff_linter/src/rules/pydoclint/rules/check_docstring.rs @@ -4,6 +4,7 @@ use ruff_python_ast::helpers::{map_callable, map_subscript}; use ruff_python_ast::name::QualifiedName; use ruff_python_ast::visitor::Visitor; use ruff_python_ast::{self as ast, Expr, Stmt, visitor}; +use ruff_python_semantic::analyze::visibility::is_staticmethod; use ruff_python_semantic::analyze::{function_type, visibility}; use ruff_python_semantic::{Definition, SemanticModel}; use ruff_python_stdlib::identifiers::is_identifier; @@ -19,6 +20,71 @@ use crate::docstrings::styles::SectionStyle; use crate::registry::Rule; use crate::rules::pydocstyle::settings::Convention; +/// ## What it does +/// Checks for function docstrings that do not include documentation for all +/// parameters. +/// +/// ## Why is this bad? +/// If a function accepts a parameter without documenting it in its docstring, +/// it can be misleading to users and/or a sign of incomplete documentation or +/// refactors. +/// +/// ## Example +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// +/// Returns: +/// Speed as distance divided by time. +/// """ +/// return distance / time +/// ``` +/// +/// Use instead: +/// ```python +/// def calculate_speed(distance: float, time: float) -> float: +/// """Calculate speed as distance divided by time. +/// +/// Args: +/// distance: Distance traveled. +/// time: Time spent travelling. +/// +/// Returns: +/// Speed as distance divided by time. +/// """ +/// return distance / time +/// ``` +#[derive(ViolationMetadata)] +#[violation_metadata(preview_since = "0.14.3")] +pub(crate) struct DocstringMissingParameter { + ids: Vec, +} + +impl Violation for DocstringMissingParameter { + #[derive_message_formats] + fn message(&self) -> String { + let DocstringMissingParameter { ids } = self; + + if let [id] = ids.as_slice() { + format!("Parameter `{id}` missing from the docstring") + } else { + format!( + "These parameters are missing from the docstring: {}", + ids.iter().map(|id| format!("`{id}`")).join(", ") + ) + } + } + + fn fix_title(&self) -> Option { + let DocstringMissingParameter { ids } = self; + let s = if ids.len() == 1 { "" } else { "s" }; + Some(format!("Add the missing parameter{s} to the docstring")) + } +} + /// ## What it does /// Checks for function docstrings that include parameters which are not /// in the function signature. @@ -1196,6 +1262,45 @@ pub(crate) fn check_docstring( let signature_parameters = parameters_from_signature(docstring); + // DOC101 + if checker.is_rule_enabled(Rule::DocstringMissingParameter) { + let mut missing_parameters = Vec::new(); + + // Here we check if the function is a method (and not a staticmethod) + // in which case we skip the first argument which should be `self` or + // `cls`, and does not need to be documented. + for signature_param in signature_parameters.iter().skip(usize::from( + docstring.definition.is_method() + && !is_staticmethod(&function_def.decorator_list, semantic), + )) { + if !docstring_sections + .parameters + .as_ref() + .is_some_and(|section| { + section + .parameters + .iter() + .any(|param| ¶m.name == signature_param) + }) + { + missing_parameters.push((*signature_param).to_string()); + } + } + if !missing_parameters.is_empty() { + let range = if let Some(ref docstring_params) = docstring_sections.parameters { + docstring_params.range() + } else { + docstring.range() + }; + checker.report_diagnostic( + DocstringMissingParameter { + ids: missing_parameters, + }, + range, + ); + } + } + // DOC201 if checker.is_rule_enabled(Rule::DocstringMissingReturns) { if should_document_returns(function_def) diff --git a/crates/ruff_linter/src/rules/pydoclint/snapshots/ruff_linter__rules__pydoclint__tests__docstring-missing-parameter_DOC101_google.py.snap b/crates/ruff_linter/src/rules/pydoclint/snapshots/ruff_linter__rules__pydoclint__tests__docstring-missing-parameter_DOC101_google.py.snap new file mode 100644 index 0000000000..de29c7c62c --- /dev/null +++ b/crates/ruff_linter/src/rules/pydoclint/snapshots/ruff_linter__rules__pydoclint__tests__docstring-missing-parameter_DOC101_google.py.snap @@ -0,0 +1,157 @@ +--- +source: crates/ruff_linter/src/rules/pydoclint/mod.rs +--- +DOC101 Parameter `b` missing from the docstring + --> DOC101_google.py:203:5 + | +201 | Adds two numbers and returns the result. +202 | +203 | Args: + | ^^^^ +204 | a (int): The first number to add. + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `multiplier` missing from the docstring + --> DOC101_google.py:217:5 + | +215 | Multiplies each element in a list by a given multiplier. +216 | +217 | Args: + | ^^^^ +218 | lst (list of int): A list of integers. + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `numbers` missing from the docstring + --> DOC101_google.py:228:5 + | +226 | # DOC101 +227 | def find_max_value(numbers): +228 | / """ +229 | | Finds the maximum value in a list of numbers. +230 | | +231 | | Returns: +232 | | int: The maximum value found in the list. +233 | | """ + | |_______^ +234 | return max(numbers) + | +help: Add the missing parameter to the docstring + +DOC101 These parameters are missing from the docstring: `name`, `age` + --> DOC101_google.py:242:5 + | +240 | Creates a user profile with basic information. +241 | +242 | Args: + | ^^^^ +243 | email (str): The user's email address. +244 | location (str): The location of the user. + | +help: Add the missing parameters to the docstring + +DOC101 These parameters are missing from the docstring: `tax_rate`, `discount` + --> DOC101_google.py:262:5 + | +260 | Calculates the total price after applying tax and a discount. +261 | +262 | Args: + | ^^^^ +263 | item_prices (list of float): A list of prices for each item. + | +help: Add the missing parameters to the docstring + +DOC101 These parameters are missing from the docstring: `cc_address`, `bcc_address` + --> DOC101_google.py:279:5 + | +277 | Sends an email to the specified recipients. +278 | +279 | Args: + | ^^^^ +280 | subject (str): The subject of the email. +281 | body (str): The content of the email. + | +help: Add the missing parameters to the docstring + +DOC101 Parameter `args` missing from the docstring + --> DOC101_google.py:295:5 + | +293 | Concatenates multiple strings with a specified separator. +294 | +295 | Args: + | ^^^^ +296 | separator (str): The separator to use between strings. + | +help: Add the missing parameter to the docstring + +DOC101 These parameters are missing from the docstring: `items`, `details` + --> DOC101_google.py:309:5 + | +307 | Processes an order with a list of items and optional order details. +308 | +309 | Args: + | ^^^^ +310 | order_id (int): The unique identifier for the order. + | +help: Add the missing parameters to the docstring + +DOC101 Parameter `value` missing from the docstring + --> DOC101_google.py:329:9 + | +327 | # DOC101 +328 | def __init__(self, value=0): +329 | / """ +330 | | Initializes the calculator with an initial value. +331 | | +332 | | Returns: +333 | | None +334 | | """ + | |___________^ +335 | self.value = value + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `number2` missing from the docstring + --> DOC101_google.py:342:9 + | +340 | Adds a number to the current value. +341 | +342 | Args: + | ^^^^ +343 | number (int or float): The number to add to the current value. + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `value_str` missing from the docstring + --> DOC101_google.py:354:9 + | +352 | @classmethod +353 | def from_string(cls, value_str): +354 | / """ +355 | | Creates a Calculator instance from a string representation of a number. +356 | | +357 | | Returns: +358 | | Calculator: A new instance of Calculator initialized with the value from the string. +359 | | """ + | |___________^ +360 | value = float(value_str) +361 | return cls(value) + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `number` missing from the docstring + --> DOC101_google.py:366:9 + | +364 | @staticmethod +365 | def is_valid_number(number): +366 | / """ +367 | | Checks if a given number is valid (int or float). +368 | | +369 | | Returns: +370 | | bool: True if the number is valid, False otherwise. +371 | | """ + | |___________^ +372 | return isinstance(number, (int, float)) + | +help: Add the missing parameter to the docstring diff --git a/crates/ruff_linter/src/rules/pydoclint/snapshots/ruff_linter__rules__pydoclint__tests__docstring-missing-parameter_DOC101_numpy.py.snap b/crates/ruff_linter/src/rules/pydoclint/snapshots/ruff_linter__rules__pydoclint__tests__docstring-missing-parameter_DOC101_numpy.py.snap new file mode 100644 index 0000000000..ee68e621b2 --- /dev/null +++ b/crates/ruff_linter/src/rules/pydoclint/snapshots/ruff_linter__rules__pydoclint__tests__docstring-missing-parameter_DOC101_numpy.py.snap @@ -0,0 +1,167 @@ +--- +source: crates/ruff_linter/src/rules/pydoclint/mod.rs +--- +DOC101 Parameter `b` missing from the docstring + --> DOC101_numpy.py:265:5 + | +263 | Adds two numbers and returns the result. +264 | +265 | Parameters + | ^^^^^^^^^^ +266 | ---------- +267 | a : int + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `multiplier` missing from the docstring + --> DOC101_numpy.py:283:5 + | +281 | Multiplies each element in a list by a given multiplier. +282 | +283 | Parameters + | ^^^^^^^^^^ +284 | ---------- +285 | lst : list of int + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `numbers` missing from the docstring + --> DOC101_numpy.py:298:5 + | +296 | # DOC101 +297 | def find_max_value(numbers): +298 | / """ +299 | | Finds the maximum value in a list of numbers. +300 | | +301 | | Returns +302 | | ------- +303 | | int +304 | | The maximum value found in the list. +305 | | """ + | |_______^ +306 | return max(numbers) + | +help: Add the missing parameter to the docstring + +DOC101 These parameters are missing from the docstring: `name`, `age` + --> DOC101_numpy.py:314:5 + | +312 | Creates a user profile with basic information. +313 | +314 | Parameters + | ^^^^^^^^^^ +315 | ---------- +316 | email : str + | +help: Add the missing parameters to the docstring + +DOC101 These parameters are missing from the docstring: `tax_rate`, `discount` + --> DOC101_numpy.py:339:5 + | +337 | Calculates the total price after applying tax and a discount. +338 | +339 | Parameters + | ^^^^^^^^^^ +340 | ---------- +341 | item_prices : list of float + | +help: Add the missing parameters to the docstring + +DOC101 These parameters are missing from the docstring: `cc_address`, `bcc_address` + --> DOC101_numpy.py:360:5 + | +358 | Sends an email to the specified recipients. +359 | +360 | Parameters + | ^^^^^^^^^^ +361 | ---------- +362 | subject : str + | +help: Add the missing parameters to the docstring + +DOC101 Parameter `args` missing from the docstring + --> DOC101_numpy.py:382:5 + | +380 | Concatenates multiple strings with a specified separator. +381 | +382 | Parameters + | ^^^^^^^^^^ +383 | ---------- +384 | separator : str + | +help: Add the missing parameter to the docstring + +DOC101 These parameters are missing from the docstring: `items`, `details` + --> DOC101_numpy.py:400:5 + | +398 | Processes an order with a list of items and optional order details. +399 | +400 | Parameters + | ^^^^^^^^^^ +401 | ---------- +402 | order_id : int + | +help: Add the missing parameters to the docstring + +DOC101 Parameter `value` missing from the docstring + --> DOC101_numpy.py:424:9 + | +422 | # DOC101 +423 | def __init__(self, value=0): +424 | / """ +425 | | Initializes the calculator with an initial value. +426 | | +427 | | """ + | |___________^ +428 | self.value = value + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `number2` missing from the docstring + --> DOC101_numpy.py:435:9 + | +433 | Adds two numbers to the current value. +434 | +435 | Parameters + | ^^^^^^^^^^ +436 | ---------- +437 | number : int or float + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `value_str` missing from the docstring + --> DOC101_numpy.py:451:9 + | +449 | @classmethod +450 | def from_string(cls, value_str): +451 | / """ +452 | | Creates a Calculator instance from a string representation of a number. +453 | | +454 | | Returns +455 | | ------- +456 | | Calculator +457 | | A new instance of Calculator initialized with the value from the string. +458 | | """ + | |___________^ +459 | value = float(value_str) +460 | return cls(value) + | +help: Add the missing parameter to the docstring + +DOC101 Parameter `number` missing from the docstring + --> DOC101_numpy.py:465:9 + | +463 | @staticmethod +464 | def is_valid_number(number): +465 | / """ +466 | | Checks if a given number is valid (int or float). +467 | | +468 | | Returns +469 | | ------- +470 | | bool +471 | | True if the number is valid, False otherwise. +472 | | """ + | |___________^ +473 | return isinstance(number, (int, float)) + | +help: Add the missing parameter to the docstring diff --git a/ruff.schema.json b/ruff.schema.json index 04ef3fcc3d..6d2163adf1 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -3160,6 +3160,7 @@ "DOC", "DOC1", "DOC10", + "DOC101", "DOC102", "DOC2", "DOC20",