Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/pydocstyle/D417.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,57 @@ def function_with_unpack_and_missing_arg_doc_should_fail(query: str, **kwargs: U
Args:
**kwargs: keyword arguments
"""


# regression test for https://github.com/astral-sh/ruff/issues/29535.
# reStructuredText requires `*` to be escaped with a backslash.
def escaped_stars_numpy(x, *args, **kwargs):
r"""Do something.
Parameters
----------
x : int
The value.
\*args : tuple
Variable arguments.
\*\*kwargs : dict
Keyword arguments.
"""


def escaped_stars_numpy_missing(x, *args, **kwargs):
r"""Do something.
Parameters
----------
\*\*kwargs : dict
Keyword arguments.
"""


def escaped_stars_google(x, *args, **kwargs):
r"""Do something.
Args:
x: the value
\*args: variable arguments
\*\*kwargs: keyword arguments
"""


def escaped_stars_google_missing(x, *args, **kwargs):
r"""Do something.
Args:
\*\*kwargs: keyword arguments
"""


def escaped_stars_non_raw(x, *args, **kwargs):
"""Do something.
Args:
x: the value
\\*args: variable arguments
\\*\\*kwargs: keyword arguments
"""
2 changes: 1 addition & 1 deletion crates/ruff_linter/src/rules/pydocstyle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ mod tests {
let diagnostics = test_path(
Path::new("pydocstyle/D417.py"),
&settings::LinterSettings {
// With explicit numpy convention, we shouldn't flag anything.
// With explicit numpy convention, we should only flag the NumPy-style docstrings.
pydocstyle: Settings {
convention: Some(Convention::Numpy),
..Settings::default()
Expand Down
19 changes: 15 additions & 4 deletions crates/ruff_linter/src/rules/pydocstyle/rules/sections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1967,8 +1967,15 @@ fn has_unpack_annotation(checker: &Checker, parameter: &Parameter) -> bool {
}

// See: `GOOGLE_ARGS_REGEX` in `pydocstyle/checker.py`.
static GOOGLE_ARGS_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^\s*(\*?\*?\w+)\s*(\(.*?\))?\s*:(\r\n|\n)?\s*.+").unwrap());
static GOOGLE_ARGS_REGEX: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^\s*((?:\\*\*){0,2}\w+)\s*(\(.*?\))?\s*:(\r\n|\n)?\s*.+").unwrap()
});

/// Removes the backslashes that escape `*` in reStructuredText, so that `\*\*kwargs` (or
/// `\\*\\*kwargs` in a non-raw docstring) is treated as `**kwargs`.
fn unescape_parameter_name(name: &str) -> String {
name.replace('\\', "")
}

fn args_section(context: &SectionContext) -> FxHashSet<String> {
let mut following_lines = context.following_lines();
Expand Down Expand Up @@ -2018,7 +2025,11 @@ fn args_section(context: &SectionContext) -> FxHashSet<String> {

matches
.iter()
.filter_map(|captures| captures.get(1).map(|arg_name| arg_name.as_str().to_owned()))
.filter_map(|captures| {
captures
.get(1)
.map(|arg_name| unescape_parameter_name(arg_name.as_str()))
})
.collect::<FxHashSet<String>>()
}

Expand Down Expand Up @@ -2051,7 +2062,7 @@ fn parameters_section(checker: &Checker, docstring: &Docstring, context: &Sectio
// Notably, NumPy lets you put multiple parameters of the same type on the same
// line.
for parameter in parameters.split(',') {
docstring_args.insert(parameter.trim().to_owned());
docstring_args.insert(unescape_parameter_name(parameter.trim()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,11 @@ D417 Missing argument description in the docstring for `function_with_unpack_and
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
239 | """Function with Unpack kwargs but missing query arg documentation.
|

D417 Missing argument descriptions in the docstring for `escaped_stars_google_missing`: `*args`, `x`
--> D417.py:282:5
|
282 | def escaped_stars_google_missing(x, *args, **kwargs):
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
283 | r"""Do something.
|
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,11 @@ D417 Missing argument description in the docstring for `function_with_unpack_and
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
239 | """Function with Unpack kwargs but missing query arg documentation.
|

D417 Missing argument description in the docstring for `escaped_stars_google_missing`: `x`
--> D417.py:282:5
|
282 | def escaped_stars_google_missing(x, *args, **kwargs):
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
283 | r"""Do something.
|
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
---
source: crates/ruff_linter/src/rules/pydocstyle/mod.rs
---

D417 Missing argument descriptions in the docstring for `escaped_stars_numpy_missing`: `*args`, `x`
--> D417.py:262:5
|
262 | def escaped_stars_numpy_missing(x, *args, **kwargs):
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
263 | r"""Do something.
|
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,19 @@ D417 Missing argument description in the docstring for `function_with_unpack_and
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
239 | """Function with Unpack kwargs but missing query arg documentation.
|

D417 Missing argument descriptions in the docstring for `escaped_stars_numpy_missing`: `*args`, `x`
--> D417.py:262:5
|
262 | def escaped_stars_numpy_missing(x, *args, **kwargs):
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
263 | r"""Do something.
|

D417 Missing argument descriptions in the docstring for `escaped_stars_google_missing`: `*args`, `x`
--> D417.py:282:5
|
282 | def escaped_stars_google_missing(x, *args, **kwargs):
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
283 | r"""Do something.
|
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,19 @@ D417 Missing argument description in the docstring for `function_with_unpack_and
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
239 | """Function with Unpack kwargs but missing query arg documentation.
|

D417 Missing argument descriptions in the docstring for `escaped_stars_numpy_missing`: `*args`, `x`
--> D417.py:262:5
|
262 | def escaped_stars_numpy_missing(x, *args, **kwargs):
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
263 | r"""Do something.
|

D417 Missing argument descriptions in the docstring for `escaped_stars_google_missing`: `*args`, `x`
--> D417.py:282:5
|
282 | def escaped_stars_google_missing(x, *args, **kwargs):
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
283 | r"""Do something.
|
Loading