ruff UP038: tool crashes
Hypothesis Nemotron 3 Super predicted not to fire did not fire
Rewriting isinstance(x, (int,)) to int | is invalid syntax; the | operator requires two operands, so the fix must not apply to 1-tuples.
Program
Output
(no stdout)
(not run)
- fired
- 0 before · 0 after
- runs
- each version twice, same file name, no network
Judge Nemotron 3 Ultra advisory program-bug · low
The rule UP038 has been removed from ruff entirely, so the linter crashes when trying to apply it. The program itself is trivial (x = 5) and contains no isinstance or issubclass calls, so the fix cannot meaningfully apply. The crash is a tooling/environment issue, not a semantic change from a rewrite.
Explanation Nemotron 3 Super unverified
The rewrite does nothing—it leaves x=5 unchanged—but claims to apply a fix that no longer exists (rule UP038 was removed). Since the tool attempts to enforce a non-existent rule, it crashes instead of producing any output. Thus, the behavior differs: the original program runs fine, while the "fixed" version triggers a tool crash due to missing rule selection, altering execution outcome despite identical source code. No actual code change occurred; the difference arises from the tool’s failure to handle the invalid rule reference. This makes the fix unsafe because it introduces instability without modifying semantics.
Reproduce
- file
prog.py(the before program)- minimized program
- r1-p006.py
- evidence sheet
- r1-p006.md
- regression fixture
- r1-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 UP038 --fix prog.py python3 prog.py
Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra
UP038 fix · ruff UP038 assignment expression · rule UP038 variable initialization pattern · linter crash due to missing UP038
- related astral-sh/ruff/issues/13051 Existing report is about outdated documentation for UP038 fix safety, not a crash when selecting a removed rule.
- related astral-sh/ruff/issues/7871 Existing report is about UP038 rewriting code to be slower, not a crash due to rule removal.
- duplicate astral-sh/ruff/issues/18349 Existing report describes the same defect: selecting deprecated/removed rule UP038 causes an error/crash.
Details
- program
- Singleton Tuple Rewrite Produces Invalid Syntax
- hazard
- Rewriting isinstance(x, (int,)) to int | is invalid syntax; the | operator requires two operands, so the fix must not apply to 1-tuples.
- oracle
lint crashed: ruff failed Cause: Rule `UP038` was removed and cannot be selected.- run
- 2026-10-17T21-20-52-142Z-httm-ruff-UP038
generated program (2 lines) and the fix's diff
rule documentation given to the models
# non-pep604-isinstance (UP038) Derived from the **pyupgrade** linter. Fix is always available. ## Removed This rule was removed as using [PEP 604] syntax in `isinstance` and `issubclass` calls isn't recommended practice, and it incorrectly suggests that other typing syntaxes like [PEP 695] would be supported by `isinstance` and `issubclass`. Using the [PEP 604] syntax is also slightly slower. ## What it does Checks for uses of `isinstance` and `issubclass` that take a tuple of types for comparison. ## Why is this bad? Since Python 3.10, `isinstance` and `issubclass` can be passed a `|`-separated union of types, which is consistent with the union operator introduced in [PEP 604]. Note that this results in slower code. Ignore this rule if the performance of an `isinstance` or `issubclass` check is a concern, e.g., in a hot loop. ## Example ```python isinstance(x, (int, float)) ``` Use instead: ```python isinstance(x, int | float) ``` ## Options - `target-version` ## References - [Python documentation: `isinstance`](https://docs.python.org/3/library/functions.html#isinstance) - [Python documentation: `issubclass`](https://docs.python.org/3/library/functions.html#issubclass) [PEP 604]: https://peps.python.org/pep-0604/ [PEP 695]: https://peps.python.org/pep-0695/