# ruff C413: fix changes program behavior

Internal evidence sheet generated by fixhunt. Not an issue text. A human re-verifies, checks the duplicates
below, and writes the upstream report in their own words following the project's AI policy.

- Tool: ruff ruff 0.17.1
- Rule: C413 (tool labels the fix: unknown, this fix reported as safe)
- Oracle: fix-changes-behavior
- Judge (Nemotron 3 Ultra, advisory): real, severity high. The rule documentation explicitly states the fix is safe for `list()` cases because it does not change behavior, but the program demonstrates that removing `list()` changes object identity when `sorted` is monkey-patched to return a cached instance. The rewrite alters runtime semantics in plausible code that intercepts the built-in function.
- Program: minimized from 13 to 12 lines

## Reproducer

```python
import builtins
original_sorted = builtins.sorted
cache = []
def cached_sorted(*args, **kwargs):
    if not cache:
        cache.append(original_sorted(*args, **kwargs))
    return cache[0]
builtins.sorted = cached_sorted
x = [3, 1, 2]
a = list(sorted(x))
b = sorted(x)
print(a is b)
```

## Commands

```sh
python3 prog.py
ruff check --preview --isolated --select C413 --fix prog.py
python3 prog.py
```

## Observed

```
stdout before:
False
stdout after:
True
```

## Diff applied by the fix

```diff
--- orig.py	2026-10-22 13:28:22.351908845 -0400
+++ fixed.py	2026-10-22 13:28:24.399942978 -0400
@@ -7,6 +7,6 @@
     return cache[0]
 builtins.sorted = cached_sorted
 x = [3, 1, 2]
-a = list(sorted(x))
+a = sorted(x)
 b = sorted(x)
 print(a is b)
```

## Why the rewrite is not equivalent (model draft, verify before use)

The original code calls `list(sorted(x))`, which creates a new list from the iterator returned by `sorted`. Since `cached_sorted` returns the same cached list object on every call (after the first), both `a` and `b` refer to that same list only if `a` does not copy it. However, `list(sorted(x))` produces a distinct list instance, so `a` is a copy while `b` is the cached list—making `a is b` false. After the fix, `a = sorted(x)` directly assigns the cached list to `a`, so both `a` and `b` reference the identical cached object, making `a is b` true. The change removes the list-copying step, altering object identity.

## Upstream search

Queries: "C413 fix", "C413 list constructor redundant", "ruff C413 unnecessary list call", "list() around function call avoidable"

- related: https://github.com/astral-sh/ruff/issues/10245
  C414 issue about sorted(reversed(iterable)) and other safety concerns, different construct than list(sorted(...))
- related: https://github.com/astral-sh/ruff/issues/20632
  C413 documentation about fix safety mentions stable sorting but not list() call removal changing identity
- related: https://github.com/astral-sh/ruff/issues/2772
  C413 incorrect double reverse assumption, same rule but different construct (reversed(sorted(...)) vs list(sorted(...)))

<details><summary>All hits</summary>

- [github, open] C414 --fix is also unsafe for sorted(reversed(iterable)), and other issues encountered when comparing with shed — https://github.com/astral-sh/ruff/issues/10245
- [github, closed] unused-function-argument not silenced by prefixed underscore if variable name is "次" — https://github.com/astral-sh/ruff/issues/28721
- [github, closed] C413 documentation implies the fix is unsafer than it is — https://github.com/astral-sh/ruff/issues/20632
- [github, closed] C413 fix is wrong when a newline appears between `sorted` and the opening parenthesis — https://github.com/astral-sh/ruff/issues/15789
- [github, closed] Policy for linter fixes that can drop comments — https://github.com/astral-sh/ruff/issues/9790
- [github, closed] Pack of fuzzer Autofix/Infinite loop errors [2] — https://github.com/astral-sh/ruff/issues/8402
- [github, closed] C413 fix for reversed(sorted(..., reverse=...)) needs parentheses when key is a boolop to avoid changing semantics — https://github.com/astral-sh/ruff/issues/10335
- [github, closed] Pack of fuzzer Autofix/Infinite loop errors — https://github.com/astral-sh/ruff/issues/7455
- [github, closed] `C413` breaks reversed(sorted(generator expression)) — https://github.com/astral-sh/ruff/issues/7289
- [github, closed] Fixed code unformatted — https://github.com/astral-sh/ruff/issues/8619
- [tavily] Incorrect double reverse in sorted rule C413 · Issue #2772 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/2772
- [tavily] Ruff (and flake8) doesn't report a situation where a variable ... — https://github.com/astral-sh/ruff/issues/2493

</details>
