The arguments to a generator function which is declared as a
contextmanager are stored inside the context manager, and
thus are kept alive, even when it is used as a regular context
manager, and not as a function decorator (where it needs
the original arguments to recreate the generator on each
call).
This is a possible unnecessary memory leak, so this changes
contextmanager.__enter__ to release the saved arguments,
as that method being called means that particular CM instance
isn't going to need to recreate the underlying generator.
Patch by Martin Teichmann.
Adds a simpler and faster alternative to ExitStack for handling
single optional context managers without having to change the
lexical structure of your code.
contextlib.AbstractContextManager now supports anti-registration
by setting __enter__ = None or __exit__ = None, following the pattern
introduced in bpo-25958.
contextlib._GeneratorContextManager.__exit__ includes a special case to deal with
PEP 479 RuntimeErrors created when `StopIteration` is thrown into the context
manager body.
Previously this check was too permissive, and undid one level of chaining on *all*
RuntimeError instances, not just those that wrapped a StopIteration instance.
managed by a contextlib.ExitStack() and one of the exit stack
generators catches and raises it in a chain, do not re-raise the
original exception when exiting, let the new chained one through.
This avoids the PEP 479 bug described in issue25782.
managed by a contextlib.ExitStack() and one of the exit stack
generators catches and raises it in a chain, do not re-raise the
original exception when exiting, let the new chained one through.
This avoids the PEP 479 bug described in issue25782.
Raise PendingDeprecationWarning when generator raises StopIteration
and no __future__ import is used. Fix offenders in the stdlib
and tests.
See also issue 22906.
Thanks to Nick Coghlan and Berker Peksag for reviews.
- Alex J Burke noticed a debugging raise in the commit that
fixed the original bug reported in issue 20317
- this showed that multiple iterations through the affected
loop wasn't actually being tested