fixhunt

ruff G010: fix changes program behavior

fix-changes-behaviorlabelled safeintended-change · lowno match
Findings / 2026-10-17T20-24-12-113Z-iye4-ruff-G010 / r1-p007ruff 0.17.18 → 4 lines2026-10-17 20:24 UTC

Hypothesis Nemotron 3 Super predicted to fire fired 1×

If `warn` is part of a larger identifier like `warning_prefix`, the replacement would produce `warning_prefixing`, causing a NameError or unintended variable reference.

Program

before
1import logging
2logger = logging.getLogger('test')
3warning_prefix = 'pre-' # Variable containing substring 'warn'
4logger.warn(warning_prefix + 'fix') # Correctly becomes .warning
after
1import logging
2logger = logging.getLogger('test')
3warning_prefix = 'pre-' # Variable containing substring 'warn'
4logger.warning(warning_prefix + 'fix') # Correctly becomes .warning

Output

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

Judge Nemotron 3 Ultra advisory intended-change · low

The rule intentionally rewrites the deprecated `logger.warn` method to `logger.warning` to eliminate the DeprecationWarning, which is the documented purpose of the rule. The stderr output changes from showing a deprecation warning to showing only the logged message 'pre-fix', demonstrating the fix works as intended.

Explanation Nemotron 3 Super unverified

The original call to `logger.warn` produced a deprecation warning on stderr due to the outdated method name; replacing it with `logger.warning` eliminates that warning while preserving the same log output, so the program’s observable behavior changes by suppressing the deprecation message, even though the intended logging action remains identical. This alteration of side effects means the fix is not strictly semantics‑preserving.

Reproduce

file
prog.py (the before program)
minimized program
r1-p007.py
evidence sheet
r1-p007.md
regression fixture
r1-p007.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 warn method call · logging.warn deprecation replacement · method name change to warning

no duplicate or related report 31 hits triaged

Details

program
`warn` as substring in larger identifier
hazard
If `warn` is part of a larger identifier like `warning_prefix`, the replacement would produce `warning_prefixing`, causing a NameError or unintended variable reference.
oracle
stderr before: /w/prog.py:4: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead stderr after: pre-fix
run
2026-10-17T20-24-12-113Z-iye4-ruff-G010
generated program (8 lines) and the fix's diff
1import logging
2logger = logging.getLogger('test')
3warning_prefix = 'pre-' # Variable containing substring 'warn'
4# Rule should ONLY replace .warn(...) -> .warning(...), NOT touch identifiers
5# So: logger.warn(warning_prefix + 'fix') -> logger.warning(warning_prefix + 'fix')
6# SAFE: no substring replacement in identifiers
7logger.warn(warning_prefix + 'fix') # Correctly becomes .warning
8print(f'Prefix: {warning_prefix}')
--- orig.py	2026-10-17 16:24:30.005890406 -0400
+++ fixed.py	2026-10-17 16:24:30.271889712 -0400
@@ -4,5 +4,5 @@
 # Rule should ONLY replace .warn(...) -> .warning(...), NOT touch identifiers
 # So: logger.warn(warning_prefix + 'fix') -> logger.warning(warning_prefix + 'fix')
 # SAFE: no substring replacement in identifiers
-logger.warn(warning_prefix + 'fix')  # Correctly becomes .warning
+logger.warning(warning_prefix + 'fix')  # Correctly becomes .warning
 print(f'Prefix: {warning_prefix}')
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)