files = [stack.enter_context(open(f"file_{i}.bin", "wb")) for i in range(5)]
with ExitStack() as stack:
for i in range(5):
file = stack.enter_context(open(f"file_{i}.bin", "wb")
file_.write(bytes(i.to_bytes(1, "little")))
Anyway, as the docs for ExitStack say:
class itercontext(ExitStack):
def __init__(self, *cms):
self._contexts = []
super().__init__()
self._contexts.extend(self.enter_context(cm) for cm in cms)
def __iter__(self):
yield from self._contexts
… or, if you prefer to think about failure handling in the @contextmanager style:
@contextmanager
def itercontext(*cms):
with ExitStack() as stack:
contexts = [stack.enter_context(cm) for cm in cms]
# It may take a comment to convince readers that there's nothing for try/finally to do here?
yield contexts
There are a few convenience helpers that could be added to ExitStack to make these even easier to write, or even to make it usable out of the box for a wider range of scenarios. An enter_contexts(cms) function could make it clear exactly what failure does to the rest of the cms iterable. Or enter_contexts(*cms), which forces an iterator to be consumed before entering anything (as your example does). Or even __init__(*cms). It could expose its managers and/or contexts as an attribute. Ir could even be an iterable or sequence of its contexts. Then, you could just use ExitStack directly as your desired itercontext.
But I don't know that those are worth adding to ExitStack, or even to a higher-level wrapper in the stdlib. I think the real problem isn't that it's too hard for novices to do this themselves as-needed, it's that it's too hard for them to discover ExitStack, to grok what it does, and to realize how easy it is to expand on. Once they get that, they can write itercontext, and anything else they need, themselves. But until they do, they'll try to write what you wrote, and either get it wrong in far worse ways or just give up.
I'm not sure how to fix that. (More links to it in the docs, more examples in its own docs, rewrite the "low-level" sentence so it sounds more like an invitation than a warning, a HOWTO, vigorous proselytizing…?) But I don't think adding one or two wrappers (or, worse, less-powerful partial workalikes) to the same module would help.