ruff UP018: fix changes program behavior
Hypothesis Nemotron 3 Super predicted to fire fired 1×
Rewriting int(5) to 5 removes a constructor call that might be used in a forward reference or string annotation evaluated at runtime via typing.get_type_hints().
Program
Output
int(5)
5
- fired
- 1 before · 0 after
- runs
- each version twice, same file name, no network
Judge Nemotron 3 Ultra advisory real · medium
The rule rewrites the string literal 'int(5)' inside a type annotation to '5', changing the annotation's stored value from 'int(5)' to '5'. Since annotations are accessible at runtime via __annotations__, this alters program behavior for code that inspects annotations, which is a plausible use case.
Explanation Nemotron 3 Super unverified
The annotation string `'int(5)'` was changed to `'5'`, altering its literal value; accessing `f.__annotations__['x']` returns this string directly, so the output changes from `int(5)` to `5`. This modification affects runtime behavior because annotations are preserved as strings and inspected explicitly. Changing their content violates semantic equivalence even if the type meaning seems similar, as the program depends on the exact annotation text. Thus the fix is not semantics‑preserving despite being labeled safe.
Reproduce
- file
prog.py(the before program)- minimized program
- r1-p003.py
- evidence sheet
- r1-p003.md
- regression fixture
- r1-p003.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 UP018 --fix prog.py python3 prog.py
Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra
UP018 fix · UP018 annotation string literal · ruff UP018 forward reference simplification · annotation quote removal numeric literal
no duplicate or related report 0 hits triaged
Details
- program
- type_annotation_runtime_eval
- hazard
- Rewriting int(5) to 5 removes a constructor call that might be used in a forward reference or string annotation evaluated at runtime via typing.get_type_hints().
- oracle
stdout before: int(5) stdout after: 5- run
- 2026-10-17T21-17-21-549Z-ajve-ruff-UP018
generated program (4 lines) and the fix's diff
--- orig.py 2026-10-17 17:17:29.537631778 -0400 +++ fixed.py 2026-10-17 17:17:29.697622187 -0400 @@ -1,4 +1,4 @@ from __future__ import annotations -def f(x: 'int(5)'): +def f(x: '5'): return x print(f.__annotations__['x'])
rule documentation given to the models
# native-literals (UP018)
Derived from the **pyupgrade** linter.
Fix is always available.
## What it does
Checks for unnecessary calls to `str`, `bytes`, `int`, `float`, `bool`, and `complex`.
## Why is this bad?
The mentioned constructors can be replaced with their respective literal
forms, which are more readable and idiomatic.
## Example
```python
str("foo")
```
Use instead:
```python
"foo"
```
## Fix safety
The fix is marked as unsafe if it might remove comments.
## References
- [Python documentation: `str`](https://docs.python.org/3/library/stdtypes.html#str)
- [Python documentation: `bytes`](https://docs.python.org/3/library/stdtypes.html#bytes)
- [Python documentation: `int`](https://docs.python.org/3/library/functions.html#int)
- [Python documentation: `float`](https://docs.python.org/3/library/functions.html#float)
- [Python documentation: `bool`](https://docs.python.org/3/library/functions.html#bool)
- [Python documentation: `complex`](https://docs.python.org/3/library/functions.html#complex)