ruff UP009: fix changes program behavior
Hypothesis Nemotron 3 Super predicted to fire fired 1×
context managers that are not files, objects with write() but no close()
Program
Output
line 5
line 4
- fired
- 1 before · 0 after
- runs
- each version twice, same file name, no network
Judge Nemotron 3 Ultra advisory real · low
Removing the encoding declaration shifts all subsequent line numbers up by one, which changes the value returned by inspect.currentframe().f_lineno. The rule documentation presents the rewrite as semantically equivalent, but the program observes its own source location, so the behavior changes.
Explanation Nemotron 3 Super unverified
Removing the encoding declaration changes how Python interprets source file bytes; while ASCII‑compatible here, the specification treats its absence as a different decoding step, which can affect line numbering in error reporting and debugging tools. The `inspect.currentframe().f_lineno` value depends on the exact line count as seen by the interpreter after decoding, so dropping the declaration shifts the perceived line number by one, causing the printed value to change from 5 to 4. This alters observable output, violating semantic equivalence.
Reproduce
- file
prog.py(the before program)- minimized program
- r2-p006.py
- evidence sheet
- r2-p006.md
- regression fixture
- r2-p006.py the minimized program with a header stating the observed change, for the tool's test suite
python3 prog.py ruff check --preview --isolated --select UP009 --fix prog.py python3 prog.py
Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra
UP009 fix · ruff UP009 encoding declaration removal · ruff UP009 UTF-8 comment deletion behavior · ruff UP009 file encoding pragma auto-fix
- related astral-sh/ruff/issues/14704 Same UP009 rule but different defect: that report involves a non-UTF-8 declaration after the UTF-8 one, while this finding removes a lone UTF-8 declaration and shifts line numbers.
Details
- program
- Non-file context manager relying on line numbers for ID
- hazard
- context managers that are not files, objects with write() but no close()
- oracle
stdout before: line 5 stdout after: line 4- run
- 2026-10-17T21-13-56-323Z-xzoc-ruff-UP009
generated program (12 lines) and the fix's diff
--- orig.py 2026-10-17 17:14:13.288784170 -0400 +++ fixed.py 2026-10-17 17:14:13.502765787 -0400 @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- class DebugCM: def __enter__(self): import inspect
rule documentation given to the models
# utf8-encoding-declaration (UP009)
Derived from the **pyupgrade** linter.
Fix is always available.
## What it does
Checks for unnecessary UTF-8 encoding declarations.
## Why is this bad?
[PEP 3120] makes UTF-8 the default encoding, so a UTF-8 encoding
declaration is unnecessary.
## Example
```python
# -*- coding: utf-8 -*-
print("Hello, world!")
```
Use instead:
```python
print("Hello, world!")
```
[PEP 3120]: https://peps.python.org/pep-3120/