Skip to content

[ruff] Handle extra arguments to deque (RUF037) - #18614

Merged
ntBre merged 10 commits into
mainfrom
brent/fix-ruf037
Jun 12, 2025
Merged

ntBre merged 10 commits into
mainfrom
brent/fix-ruf037

Conversation

@ntBre

@ntBre ntBre commented Jun 10, 2025 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #18612 by:

  • Bailing out without a fix in the case of *args, which I don't think we can fix reliably
  • Using an Edit::deletion from remove_argument instead of an Edit::range_replacement in the presence of unrecognized keyword arguments

I thought we could always switch to the Edit::deletion approach initially, but it caused problems when maxlen was passed positionally, which we didn't have any existing tests for.

The replacement fix can easily delete comments, so I also marked the fix unsafe in these cases and updated the docs accordingly.

Test Plan

New test cases derived from the issue.

Stabilization

These are pretty significant changes, much like those to PYI059 in #18611 (and based a bit on the implementation there!), so I think it probably makes sense to un-stabilize this for the 0.12 release, but I'm open to other thoughts there.

@ntBre ntBre added bug An issue describing something that isn't working, or a PR that fixes a bug fixes Related to suggested fixes for violations labels Jun 10, 2025
@github-actions

github-actions Bot commented Jun 10, 2025 •

Copy link
Copy Markdown
Contributor

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@ntBre
ntBre marked this pull request as ready for review June 10, 2025 19:52
65 65 | def f():
66 66 | deque([], *[10]) # RUF037 but no fix
67 |- deque([], **{"maxlen": 10}) # RUF037
67 |+ deque(**{"maxlen": 10}) # RUF037

@MichaReiser MichaReiser Jun 11, 2025 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nit picky, but I think this is unsafe if the dict contains an iterable keyword. The same if there are any other keywords around:

>>> from collections import deque
>>> a = deque(iterable=[1, 2])
>>> list(a)
[1, 2]
>>> list(a)
KeyboardInterrupt
>>> a = deque([1], iterable=[1, 2])
Traceback (most recent call last):
  File "<python-input-6>", line 1, in <module>
    a = deque([1], iterable=[1, 2])
TypeError: argument for deque() given by name ('iterable') and position (1)

We should mark the fix as unsafe if there are any other arguments.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow nice catch! I added this case:

def f():
    deque([], iterable=[])

and realized that I was mishandling the range passed to remove_argument because this was returning an Err! I was only passing the ArgOrKeyword::value not the whole ArgOrKeyword.

I fixed that, and then also marked the fix unsafe if we find an unrecognized number of arguments.

@ntBre ntBre mentioned this pull request Jun 11, 2025
1 of 2 tasks
@ntBre
ntBre merged commit 96171f4 into main Jun 12, 2025
@ntBre
ntBre deleted the brent/fix-ruf037 branch June 12, 2025 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug An issue describing something that isn't working, or a PR that fixes a bug fixes Related to suggested fixes for violations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RUF037 ignores extra arguments

2 participants