Skip to content

[flake8-bugbear] Allow B901 in pytest hook wrappers#21931

Merged
ntBre merged 3 commits intoastral-sh:mainfrom
assadyousuf:fix-b901-pytest-hookimpl-wrapper
Feb 20, 2026
Merged

[flake8-bugbear] Allow B901 in pytest hook wrappers#21931
ntBre merged 3 commits intoastral-sh:mainfrom
assadyousuf:fix-b901-pytest-hookimpl-wrapper

Conversation

@assadyousuf
Copy link
Contributor

Summary

Stop raising return-in-generator with pytest hook wrappers (@hookimpl(wrapper=True)). They are specifically designed to use this pattern: https://docs.pytest.org/en/stable/how-to/writing_hook_functions.html#hook-wrappers-executing-around-other-hooks

Before: return-in-generator reports would surface with pytest hook wrappers

After: specifically check for pytest hook wrappers before reporting return-in-generator

Testing:
Wrote some tests to cover different cases

@ntBre ntBre added rule Implementing or modifying a lint rule preview Related to preview mode features labels Dec 12, 2025
@astral-sh-bot
Copy link

astral-sh-bot bot commented Dec 17, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+0 -24 violations, +0 -0 fixes in 5 projects; 50 projects unchanged)

PlasmaPy/PlasmaPy (+0 -5 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

- .github/scripts/authors_in_cff.py:40:10: FURB101 `Path.open()` followed by `read()` can be replaced by `pathlib.Path("CITATION.cff").read_text()`
- .github/scripts/citation_updater.py:69:10: FURB103 [*] `Path.open()` followed by `write()` can be replaced by `citation_rst_file.write_text(citation_rst_text)`
- docs/_author_list_from_cff.py:193:10: FURB103 [*] `Path.open()` followed by `write()` can be replaced by `pathlib.Path(rst_file).write_text(authors_rst, encoding="utf-8")`
- docs/_global_substitutions.py:217:10: FURB103 [*] `Path.open()` followed by `write()` can be replaced by `pathlib.Path(rst_file).write_text(content, encoding="utf-8")`
- tests/utils/data/test_downloader.py:191:10: FURB103 [*] `Path.open()` followed by `write()` can be replaced by `filepath.write_text("Not data")`

langchain-ai/langchain (+0 -3 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

- libs/partners/chroma/langchain_chroma/vectorstores.py:489:14: FURB101 `Path.open()` followed by `read()` can be replaced by `Path(uri).read_bytes()`
- libs/standard-tests/langchain_tests/conftest.py:70:14: FURB101 [*] `Path.open()` followed by `read()` can be replaced by `cassette_path.read_bytes()`
- libs/standard-tests/langchain_tests/conftest.py:88:14: FURB103 [*] `Path.open()` followed by `write()` can be replaced by `cassette_path.write_bytes(data)`

scikit-build/scikit-build-core (+0 -6 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

- src/scikit_build_core/ast/ast.py:88:10: FURB101 `Path.open()` followed by `read()` can be replaced by `Path(sys.argv[1]).read_text(encoding="utf-8-sig")`
- src/scikit_build_core/ast/tokenizer.py:77:10: FURB101 `Path.open()` followed by `read()` can be replaced by `Path(sys.argv[1]).read_text(encoding="utf-8-sig")`
- src/scikit_build_core/metadata/regex.py:58:10: FURB101 `Path.open()` followed by `read()` can be replaced by `Path(input_filename).read_text(encoding="utf-8")`
- tests/test_dynamic_metadata.py:274:10: FURB103 [*] `Path.open()` followed by `write()` can be replaced by `Path("__init__.py").write_text("__version__ = '0.1.0'")`
- tests/test_dynamic_metadata.py:290:10: FURB103 [*] `Path.open()` followed by `write()` can be replaced by `Path("version.hpp")....`
- tests/test_dynamic_metadata.py:326:10: FURB103 [*] `Path.open()` followed by `write()` can be replaced by `Path("version.hpp")....`

indico/indico (+0 -1 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

- indico/vendor/django_mail/message.py:369:14: FURB101 `Path.open()` followed by `read()` can be replaced by `path.read_bytes()`

pytest-dev/pytest (+0 -9 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

- src/_pytest/faulthandler.py:102:9: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior
- src/_pytest/helpconfig.py:152:5: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior
- src/_pytest/setuponly.py:36:9: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior
- src/_pytest/warnings.py:109:9: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior
- src/_pytest/warnings.py:118:9: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior
- src/_pytest/warnings.py:128:9: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior
- src/_pytest/warnings.py:89:9: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior
- src/_pytest/warnings.py:98:9: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior
- testing/conftest.py:91:5: B901 Using `yield` and `return {value}` in a generator function can lead to confusing behavior

Changes by rule (3 rules affected)

code total + violation - violation + fix - fix
B901 9 0 9 0 0
FURB103 8 0 8 0 0
FURB101 7 0 7 0 0

Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This looks great to me overall. I just had a couple of small suggestions besides the snapshots needing to be updated.

@ntBre ntBre changed the title Fixes #21881: return-in-generator (B901) - should not be reported on pytest hook wrappers [flake8-bugbear] Allow B901 in pytest hook wrappers Dec 17, 2025
@ntBre ntBre enabled auto-merge (squash) February 20, 2026 15:26
@ntBre ntBre merged commit b9e29dd into astral-sh:main Feb 20, 2026
41 checks passed
knutwannheden pushed a commit to openrewrite/ruff that referenced this pull request Feb 20, 2026
)

## Summary
Stop raising return-in-generator with pytest hook wrappers
(@hookimpl(wrapper=True)). They are specifically designed to use this
pattern:
https://docs.pytest.org/en/stable/how-to/writing_hook_functions.html#hook-wrappers-executing-around-other-hooks

Before: return-in-generator reports would surface with pytest hook
wrappers

After: specifically check for pytest hook wrappers before reporting
return-in-generator

Testing:
Wrote some tests to cover different cases

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Related to preview mode features rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

return-in-generator (B901) - should not be reported on pytest hook wrappers

2 participants