Skip to content

C414 --fix is also unsafe for sorted(reversed(iterable)), and other issues encountered when comparing with shed #10245

@jakkdl

Description

@jakkdl

C414 is marked as unsafe fix, but only because of dropping comments: https://docs.astral.sh/ruff/rules/unnecessary-double-cast-or-process/#fix-safety

EDIT: I noticed now that C413 has an extensive warning about safety with regards to stable sorting https://docs.astral.sh/ruff/rules/unnecessary-call-around-sorted/#fix-safety - so the fix is perhaps just that it should be copied over?

But it also breaks sorting stability in some cases, autofixing sorted(reversed(iterable)) to sorted(iterable).

full shell command:

$ ruff check --select=C414 --fix --unsafe-fixes --isolated - <<< 'sorted(reversed(iterable))'  
sorted(iterable)
Found 1 error (1 fixed, 0 remaining).

ruff version: 0.3.0
platform: linux

And a full minimal example where the problem is demonstrated. Assertions pass before autofixing with ruff, but fail afterwards.

from __future__ import annotations
from dataclasses import dataclass
@dataclass
class MyClass:
    a: int
    b: int
    def __lt__(self, other: MyClass) -> bool:
        return self.a < other.a

first = MyClass(1, 1)
second = MyClass(1, 2)

# ruff will remove the reversed call in the line below, breaking the assertion
assert sorted(reversed((first, second))) == [second, first]
assert sorted((first, second)) == [first, second]

Found in the process of replacing some of sheds libcst code mods with ruff Zac-HD/shed#105
CodeMod in question: https://github.com/Zac-HD/shed/blob/692a429bff19c3e1a798b97cb45396160dc138eb/src/shed/_codemods.py#L275-L315

Unrelated to this specific issue: That codemod also handles cases of combining reverse:
sorted(sorted(iterable, reverse=True), reverse=False) -> sorted(iterable, reverse=False)
sorted(sorted(iterable, reverse=False), reverse=True) -> sorted(iterable, reverse=True)

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions