Skip to content

Conversation

@ntBre
Copy link
Contributor

@ntBre ntBre commented Jun 10, 2025

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 Something isn't working fixes Related to suggested fixes for violations labels Jun 10, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Jun 10, 2025

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
Copy link
Member

@MichaReiser MichaReiser Jun 11, 2025

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
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
2 tasks
@ntBre ntBre merged commit 96171f4 into main Jun 12, 2025
34 checks passed
@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 Something isn't working fixes Related to suggested fixes for violations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RUF037 ignores extra arguments

3 participants