-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[flake8-pyi] Avoid syntax error in the case of starred and keyword arguments (PYI059)
#18611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
793f552
ee7d834
18bc625
c240c13
41a65ec
6f5fad9
258257c
6815c68
aa9803b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| use ruff_diagnostics::Edit; | ||
| use ruff_macros::{ViolationMetadata, derive_message_formats}; | ||
| use ruff_python_ast::parenthesize::parenthesized_range; | ||
| use ruff_python_ast::{self as ast, helpers::map_subscript}; | ||
| use ruff_text_size::Ranged; | ||
|
|
||
|
|
@@ -43,6 +45,11 @@ use crate::{Fix, FixAvailability, Violation}; | |
| /// ): | ||
| /// ... | ||
| /// ``` | ||
| /// | ||
| /// ## Fix availability | ||
| /// | ||
| /// This rule's fix is only available when there are no `*args` present in the base class list. | ||
| /// | ||
| /// ## References | ||
| /// - [`typing.Generic` documentation](https://docs.python.org/3/library/typing.html#typing.Generic) | ||
| /// | ||
|
|
@@ -94,6 +101,22 @@ pub(crate) fn generic_not_last_base_class(checker: &Checker, class_def: &ast::St | |
|
|
||
| let mut diagnostic = checker.report_diagnostic(GenericNotLastBaseClass, bases.range()); | ||
|
|
||
| // Avoid suggesting a fix if any of the arguments is starred. This avoids tricky syntax errors | ||
| // in cases like | ||
| // | ||
| // ```python | ||
| // class C3(Generic[T], metaclass=type, *[str]): ... | ||
| // ``` | ||
| // | ||
| // where we would naively try to put `Generic[T]` after `*[str]`, which is also after a keyword | ||
| // argument, causing the error. | ||
| if bases | ||
| .arguments_source_order() | ||
| .any(|arg| arg.value().is_starred_expr()) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| // No fix if multiple `Generic[]`s are seen in the class bases. | ||
| if generic_base_iter.next().is_none() { | ||
| diagnostic.try_set_fix(|| generate_fix(generic_base, bases, checker)); | ||
|
|
@@ -109,12 +132,19 @@ fn generate_fix( | |
| let source = locator.contents(); | ||
|
|
||
| let deletion = remove_argument(generic_base, arguments, Parentheses::Preserve, source)?; | ||
| let insertion = add_argument( | ||
| locator.slice(generic_base), | ||
| arguments, | ||
| checker.comment_ranges(), | ||
| source, | ||
| ); | ||
|
|
||
| let argument = locator.slice(generic_base); | ||
| let comment_ranges = checker.comment_ranges(); | ||
|
|
||
| // adapted from `add_argument`, which doesn't automatically handle inserting before the first | ||
| // keyword argument. | ||
| let insertion = if let Some(ast::Keyword { range, value, .. }) = arguments.keywords.first() { | ||
| let keyword = parenthesized_range(value.into(), arguments.into(), comment_ranges, source) | ||
| .unwrap_or(*range); | ||
| Edit::insertion(format!("{argument}, "), keyword.start()) | ||
| } else { | ||
| add_argument(argument, arguments, comment_ranges, source) | ||
| }; | ||
|
|
||
| Ok(Fix::safe_edits(deletion, [insertion])) | ||
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we be adding this logic to
add_argument, so that it's also fixed for other rules that use that utility? If we don't want to do that in this PR, is it worth opening a followup issue for that?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I actually checked the other callers of
add_argument, and they were all adding keyword arguments! So I think it makes sense to fix this or add a note to the docs at the very least.I don't mind doing it here, but I guess it might churn some snapshots to move the existing calls to the front of the kwarg list.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy with doing it here or postponing to a followup -- either is fine by me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and did it here. It might have even shortened the net diff!
You're welcome to review again of course, but otherwise I'll just merge this when CI finishes. Thanks for the help!