fixhunt

ruff G010: fix changes program behavior

fix-changes-behaviorlabelled safeintended-change · lowduplicate
Findings / 2026-10-17T20-24-12-113Z-iye4-ruff-G010 / r1-p001ruff 0.17.111 → 6 lines2026-10-17 20:24 UTC

Hypothesis Nemotron 3 Super predicted to fire fired 1×

When multiple logger-like objects exist (e.g., `access_logger` and `error_logger`), the tool might incorrectly apply the fix based on naming heuristics even if only one is a true logger per `lint.logg

Program

before
1import logging
2error_logger = logging.getLogger('error')
3try:
4 error_logger.warn('error msg') # Should become .warning
5except Exception as e:
6 print(f'Error: {type(e).__name__}: {e}')
after
1import logging
2error_logger = logging.getLogger('error')
3try:
4 error_logger.warning('error msg') # Should become .warning
5except Exception as e:
6 print(f'Error: {type(e).__name__}: {e}')

Output

stdout beforeexit 0
(no stdout)
/w/prog.py:4: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead
stdout afterexit 0
(no stdout)
error msg
fired
1 before · 0 after
runs
each version twice, same file name, no network

Judge Nemotron 3 Ultra advisory intended-change · low

The rule rewrites the deprecated .warn() method to .warning() as documented. The stderr difference occurs because the DeprecationWarning emitted by the old code disappears after the fix, which is exactly the semantic change the rule intends to make.

Explanation Nemotron 3 Super unverified

The original call to `warn` emits a deprecation warning via Python’s warnings system; replacing it with `warning` suppresses that specific warning because the newer method does not trigger deprecation notices. Since the program’s observable output includes stderr (where the warning appears), removing it changes behavior—what was printed to stderr before (`DeprecationWarning`) is absent after the rewrite, making the transformation not semantics‑preserving under the language’s full execution model, which accounts for all side effects including warnings.

Reproduce

file
prog.py (the before program)
minimized program
r1-p001.py
evidence sheet
r1-p001.md
regression fixture
r1-p001.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 G010 --fix prog.py
python3 prog.py

Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra

G010 fix · ruff G010 logger warn method · logging warning deprecation fix · error_logger.warn to warning

Details

program
Multiple logger-like objects - heuristic misapplication
hazard
When multiple logger-like objects exist (e.g., `access_logger` and `error_logger`), the tool might incorrectly apply the fix based on naming heuristics even if only one is a true logger per `lint.logg
oracle
stderr before: /w/prog.py:4: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead stderr after: error msg
run
2026-10-17T20-24-12-113Z-iye4-ruff-G010
generated program (11 lines) and the fix's diff
1import logging
2# Simulate lint.logger-objects containing only ['error_logger']
3error_logger = logging.getLogger('error')
4access_logger = logging.getLogger('access') # Not in lint.logger-objects
5# Rule should fire on error_logger.warn but NOT on access_logger.warn
6try:
7 error_logger.warn('error msg') # Should become .warning
8 access_logger.warn('access msg') # Should NOT be changed (heuristic overreach)
9except Exception as e:
10 print(f'Error: {type(e).__name__}: {e}')
11print('Done')
--- orig.py	2026-10-17 16:24:27.826896136 -0400
+++ fixed.py	2026-10-17 16:24:28.077895473 -0400
@@ -4,8 +4,8 @@
 access_logger = logging.getLogger('access')  # Not in lint.logger-objects
 # Rule should fire on error_logger.warn but NOT on access_logger.warn
 try:
-    error_logger.warn('error msg')   # Should become .warning
-    access_logger.warn('access msg') # Should NOT be changed (heuristic overreach)
+    error_logger.warning('error msg')   # Should become .warning
+    access_logger.warning('access msg') # Should NOT be changed (heuristic overreach)
 except Exception as e:
     print(f'Error: {type(e).__name__}: {e}')
 print('Done')
rule documentation given to the models
# logging-warn (G010)

Derived from the **flake8-logging-format** linter.

Fix is always available.

## What it does
Checks for uses of `logging.warn` and `logging.Logger.warn`.

## Why is this bad?
`logging.warn` and `logging.Logger.warn` are deprecated in favor of
`logging.warning` and `logging.Logger.warning`, which are functionally
equivalent.

## Known problems

This rule detects uses of the `logging` module via a heuristic.
Specifically, it matches against:

- Uses of the `logging` module itself (e.g., `import logging; logging.info(...)`).
- Uses of `flask.current_app.logger` (e.g., `from flask import current_app; current_app.logger.info(...)`).
- Objects whose name starts with `log` or ends with `logger` or `logging`,
  when used in the same file in which they are defined (e.g., `logger = logging.getLogger(); logger.info(...)`).
- Imported objects marked as loggers via the [`lint.logger-objects`] setting, which can be
  used to enforce these rules against shared logger objects (e.g., `from module import logger; logger.info(...)`,
  when [`lint.logger-objects`] is set to `["module.logger"]`).

## Example
```python
import logging

logging.warn("Something happened")
```

Use instead:
```python
import logging

logging.warning("Something happened")
```

## Options
- `lint.logger-objects`

## References
- [Python documentation: `logging.warning`](https://docs.python.org/3/library/logging.html#logging.warning)
- [Python documentation: `logging.Logger.warning`](https://docs.python.org/3/library/logging.html#logging.Logger.warning)