ruff G010: fix changes program behavior
Hypothesis Nemotron 3 Super predicted to fire fired 1×
generators vs lists, iterators consumed once, lazy vs eager evaluation
Program
Output
Second consumption: [None, None] /w/prog.py:3: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead
Second consumption: [None, None] Processing 0
- fired
- 1 before · 0 after
- runs
- each version twice, same file name, no network
Judge Nemotron 3 Ultra advisory intended-change · low
The rule replaces the deprecated `logger.warn` with `logger.warning`, which the documentation states are functionally equivalent. The observed difference is the removal of the DeprecationWarning on stderr, which is exactly the semantic change the rule intends to make.
Explanation Nemotron 3 Super unverified
The original generator expression uses `logger.warn`, which emits a deprecation warning to stderr when called; this occurs during each iteration of the generator. After rewriting to `logger.warning`, the deprecated method is replaced with its non-deprecated counterpart, so no warning is emitted. Since the first consumption of the generator (implicit in printing) now produces no stderr output, while the second consumption still yields the same list, the overall program behavior differs—specifically, the absence of the deprecation warning in stderr changes the observable output. Thus, the rewrite alters side effects and is not semantics-preserving.
Reproduce
- file
prog.py(the before program)- minimized program
- r2-p004.py
- evidence sheet
- r2-p004.md
- regression fixture
- r2-p004.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 generator expression · Oracle warning deprecation logger usage · fix changes behavior logger.warn to warning
- duplicate astral-sh/ruff/issues/12295 same rule G010 and same construct: accessing the deprecated `Logger.warn` method which should be rewritten to `Logger.warning`
- related astral-sh/ruff/issues/7248 tracks implementation of flake8-logging rules including G010 but is a meta-issue not a specific defect report
- related astral-sh/ruff/issues/2186 documents rule aliasing where G010 is an alias of PGH002 but does not describe a defect
- related astral-sh/ruff/issues/13673 reports G rules not working with loguru, same rule family but different logger library
- duplicate astral-sh/ruff/issues/17219 explicitly closed as duplicate of issue 12295 which is the same Logger.warn access defect
- related astral-sh/ruff/issues/21889 BLE001 false positive with logging.warning call, same logging method but different rule and defect type
- related astral-sh/ruff/issues/6972 G004 false positive with imported logger instances, same rule family but different construct and rule
Details
- program
- Generator consumed once, logger.warn inside generator expression
- hazard
- generators vs lists, iterators consumed once, lazy vs eager evaluation
- oracle
stderr before: /w/prog.py:3: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead stderr after: Processing 0- run
- 2026-10-17T20-24-12-113Z-iye4-ruff-G010
generated program (6 lines) and the fix's diff
--- orig.py 2026-10-17 16:24:36.818872876 -0400 +++ fixed.py 2026-10-17 16:24:37.063872256 -0400 @@ -1,6 +1,6 @@ import logging logger = logging.getLogger() logger.setLevel(logging.INFO) -gen = (logger.warn(f'Processing {x}') for x in range(2)) +gen = (logger.warning(f'Processing {x}') for x in range(2)) print('First consumption:', list(gen)) print('Second consumption:', list(gen))
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)