Extend B019 to alru_cache and async methods - #570
Merged
Conversation
B019 warns about functools.lru_cache/cache on methods because the cache holds instance references and prevents garbage collection. The same problem applies to async_lru.alru_cache, which is the async equivalent, and to plain lru_cache/cache used on async methods (which the check previously skipped because it only visited sync function defs). Add async_lru.alru_cache and alru_cache to the recognised cache decorators and run the check on async def methods too.
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request expands flake8-bugbear’s B019 check to also detect cache decorators on async def instance methods, including async_lru.alru_cache, addressing the memory-leak risk described in #488.
Changes:
- Run the B019 check for
ast.AsyncFunctionDefnodes in addition toast.FunctionDef. - Extend B019’s recognized cache decorators to include
async_lru.alru_cache/alru_cache. - Update the B019 eval test file and README/changelog text to cover async-method scenarios.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
bugbear.py |
Runs B019 on async method definitions and recognizes async_lru.alru_cache / alru_cache decorators. |
tests/eval_files/b019.py |
Adds async-method test cases for cache/lru_cache and alru_cache (including called forms) and preserves classmethod/staticmethod negatives. |
README.rst |
Updates B019 documentation and changelog entry to reflect async and alru_cache coverage. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
cooperlees
approved these changes
Aug 19, 2026
cooperlees
left a comment
Collaborator
There was a problem hiding this comment.
Tests pass and it all looks good to me. So thanks!
Comment on lines
+10
to
+11
| import async_lru | ||
| from async_lru import alru_cache |
Collaborator
There was a problem hiding this comment.
Does this need to be a dep for the test running? How does this not cause an error or am I forgetting we have some import mocking magic?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This extends B019 to cover
async_lru.alru_cacheand cache decorators onasync defmethods, as suggested in #488.alru_cacheis the async port offunctools.lru_cache(maintained by aio-libs), so when it decorates a method it keeps instance references alive in exactly the same way and leads to the same memory leak B019 is meant to catch. While looking into it I noticed B019 only ran on synchronous function definitions, so even a plain@lru_cache/@cacheon anasync defmethod slipped through. I addedasync_lru.alru_cacheandalru_cacheto the recognised decorators and wired the check intovisit_AsyncFunctionDef, so all of these now report on both sync and async methods.I extended
tests/eval_files/b019.pywith an async class coveringalru_cache,async_lru.alru_cache, their called forms, andlru_cache/cacheon async methods, plus the classmethod/staticmethod negatives to make sure those still don't fire. The README description and change log are updated to match.Closes #488