# ruff FURB129 on repo: fix changes the outcome of the project's command

Evidence sheet generated by fixhunt from a repository scan. 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 0.17.1 (fix labelled safe)
- Project: /home/sun/dev/diaghunt/demo/repo
- Command: `cd python && python3 -m unittest discover -s tests -t .` (exit 0 before, 1 after)
- Files changed by the fix: 1; reduced to 1 of 1 hunk(s) in python/toolbox/logs.py (delta debugging complete; the patch below was applied with git apply and reproduced the same difference)
- Sites reported by the rule in 1 changed file(s): 1 before, 0 after the fix
- Judge (Nemotron 3 Ultra, advisory): real, severity high. The fix replaces `fp.readlines()` with `fp`, changing the iteration from a pre-read list of lines to a live iterator over the file object. The program relies on `fp.seek(0)` inside the loop to restart reading from the beginning for each outer line, which works with `readlines()` because the outer iteration is over an in-memory list, but fails when iterating directly over `fp` because the file position is shared and the outer loop exhausts the iterator after the first inner pass.

## Change (reduced; applies to the project with `git apply -p1`)

```diff
--- a/python/toolbox/logs.py
+++ b/python/toolbox/logs.py
@@ -4,7 +4,7 @@
 def has_duplicate(path):
     """True when any line occurs more than once. Each line is compared against a fresh pass over the file."""
     with open(path) as fp:
-        for line in fp.readlines():
+        for line in fp:
             fp.seek(0)
             if sum(1 for other in fp if other == line) > 1:
                 return True
```

## Observed

```
exit 0 → 1
stderr last line before: OK
stderr last line after: FAILED (failures=1)
```

## Output of the command (last 40 lines)

Before:

```
(no stdout)
stderr:
..........
----------------------------------------------------------------------
Ran 10 tests in 0.007s

OK
```

After:

```
(no stdout)
stderr:
======================================================================
FAIL: test_duplicate_after_first_line (tests.test_logs.LogTests.test_duplicate_after_first_line)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/w/python/tests/test_logs.py", line 13, in test_duplicate_after_first_line
    self.assertTrue(has_duplicate(p))
AssertionError: False is not true

----------------------------------------------------------------------
Ran 10 tests in 0.007s

FAILED (failures=1)
```

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

(not written)

## Upstream search

Queries: "FURB129 fix", "FURB129 avoid readlines iteration", "FURB129 replace readlines with direct iteration", "FURB129 inefficient file reading pattern"

- duplicate: https://github.com/astral-sh/ruff/issues/29640
- related: https://github.com/astral-sh/ruff/issues/18843
- related: https://github.com/astral-sh/ruff/issues/17683
- related: https://github.com/astral-sh/ruff/issues/18231

## Reproduce

```sh
# /home/sun/dev/diaghunt/demo/repo: apply the change above (minimal.patch), then run the command
git apply -p1 minimal.patch
cd python && python3 -m unittest discover -s tests -t .
# or run the fixer itself on the changed files
ruff check --preview --isolated --select FURB129 --fix 'python/toolbox/logs.py'
```
