NAM107: a generator under a name that sounds like a list¶
Junior¶
A function with yield in it is a generator. Calling it returns an iterator that produces values one at a time, and only once. A caller who thinks they got a list can loop over it a second time and get nothing.
def collect_entry(root): # NAM107: contains yield
for path in root.iterdir():
yield path
def iter_entries(root): # says it is lazy
for path in root.iterdir():
yield path
To fix it, name it with a lazy prefix such as iter_, walk_ or generate_, or end the name with a plural (entries).
This check is off unless you turn it on with --select NAM107.
Senior¶
The bug from an unexpected generator surfaces two loops later, far from the function: the second for finds the iterator exhausted, or len() raises a TypeError. A name that says "lazy" or "many" warns the caller to wrap it in list() when they need to reuse it.
It stays quiet on:
- a plural last word:
items,values,user_records. - a lazy prefix:
iter_,walk_,gen_,generate_,stream_,scan_,traverse_,produce_,yield_,enumerate_,chunk_. - dunders.
- a
yieldthat belongs to a protocol: a pytest fixture, a@contextmanager, an@asynccontextmanager, a pluggy@hookimplwrapper. There the noun name is correct (db_session,client).
The check is opt-in because it reports too much in some codebases. In a protocol-heavy library, a generator method is often the interface itself, such as an auth flow that yields requests.
Expert¶
The leading underscores come off before the prefix test, so _walk counts as lazy. The suggested name keeps a private name private: _entry suggests _iter_entry. The plural test is crude: the last word ends in s and not in ss, so status passes for a plural and class doesn't.
The corpus rate is what keeps it opt-in: 17.08 per thousand functions in httpx, 14.75 in rich and 10.82 in click, against 2.22 in CPython. The false-positive class is the undecorated protocol generator: an abstract method on a base class, or a generator-based flow where yield request is the API. Telling those apart from a misnamed helper needs either decorator conventions that don't exist yet, or knowledge of the base class, which this AST-only design doesn't have. It stays opt-in until a narrower detector brings the rate down.