[pydoclint] Support NumPy-style comma-separated parameters (DOC102) (#20972)

This commit is contained in:
Dan Parizher 2025-11-12 02:29:23 -05:00 committed by GitHub
parent d2c3996f4e
commit 725ae69773
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 130 additions and 12 deletions

View file

@ -371,6 +371,61 @@ class Foo:
"""
return
# DOC102 - Test case from issue #20959: comma-separated parameters
def leq(x: object, y: object) -> bool:
"""Compare two objects for loose equality.
Parameters
----------
x1, x2 : object
Objects.
Returns
-------
bool
Whether the objects are identical or equal.
"""
return x is y or x == y
# OK - comma-separated parameters that match function signature
def compare_values(x1: int, x2: int) -> bool:
"""Compare two integer values.
Parameters
----------
x1, x2 : int
Values to compare.
Returns
-------
bool
True if values are equal.
"""
return x1 == x2
# DOC102 - mixed comma-separated and regular parameters
def process_data(data, x1: str, x2: str) -> str:
"""Process data with multiple string parameters.
Parameters
----------
data : list
Input data to process.
x1, x2 : str
String parameters for processing.
extra_param : str
Extra parameter not in signature.
Returns
-------
str
Processed result.
"""
return f"{x1}{x2}{len(data)}"
# OK
def baz(x: int) -> int:
"""
@ -389,3 +444,21 @@ def baz(x: int) -> int:
int
"""
return x
# OK - comma-separated parameters without type annotations
def add_numbers(a, b):
"""
Adds two numbers and returns the result.
Parameters
----------
a, b
The numbers to add.
Returns
-------
int
The sum of the two numbers.
"""
return a + b

View file

@ -661,19 +661,31 @@ fn parse_parameters_numpy(content: &str, content_start: TextSize) -> Vec<Paramet
.is_some_and(|first_char| !first_char.is_whitespace())
{
if let Some(before_colon) = entry.split(':').next() {
let param = before_colon.trim_end();
let param_name = param.trim_start_matches('*');
if is_identifier(param_name) {
let param_start = line_start + indentation.text_len();
let param_end = param_start + param.text_len();
let param_line = before_colon.trim_end();
entries.push(ParameterEntry {
name: param_name,
range: TextRange::new(
content_start + param_start,
content_start + param_end,
),
});
// Split on commas to handle comma-separated parameters
let mut current_offset = TextSize::from(0);
for param_part in param_line.split(',') {
let param_part_trimmed = param_part.trim();
let param_name = param_part_trimmed.trim_start_matches('*');
if is_identifier(param_name) {
// Calculate the position of this specific parameter part within the line
// Account for leading whitespace that gets trimmed
let param_start_in_line = current_offset
+ (param_part.text_len() - param_part_trimmed.text_len());
let param_start =
line_start + indentation.text_len() + param_start_in_line;
entries.push(ParameterEntry {
name: param_name,
range: TextRange::at(
content_start + param_start,
param_part_trimmed.text_len(),
),
});
}
// Update offset for next iteration: add the part length plus comma length
current_offset = current_offset + param_part.text_len() + ','.text_len();
}
}
}

View file

@ -187,3 +187,36 @@ DOC102 Documented parameter `a` is not in the function's signature
302 | b
|
help: Remove the extraneous parameter from the docstring
DOC102 Documented parameter `x1` is not in the function's signature
--> DOC102_numpy.py:380:5
|
378 | Parameters
379 | ----------
380 | x1, x2 : object
| ^^
381 | Objects.
|
help: Remove the extraneous parameter from the docstring
DOC102 Documented parameter `x2` is not in the function's signature
--> DOC102_numpy.py:380:9
|
378 | Parameters
379 | ----------
380 | x1, x2 : object
| ^^
381 | Objects.
|
help: Remove the extraneous parameter from the docstring
DOC102 Documented parameter `extra_param` is not in the function's signature
--> DOC102_numpy.py:418:5
|
416 | x1, x2 : str
417 | String parameters for processing.
418 | extra_param : str
| ^^^^^^^^^^^
419 | Extra parameter not in signature.
|
help: Remove the extraneous parameter from the docstring