Description
openedon Mar 25, 2019
Is your feature request related to a problem?
If you decorate a generator function with @contextlib.contextmanager
and use the context manager cm
inside a generator function, the context manager's __exit__
will not be always be called because the generator raises GeneratorExit
, which ends the generator that defines cm
.
Notice that cm exit
never appears, as cm
's __exit__
is never called.
from __future__ import generator_stop
import contextlib
import weakref
import sys
@contextlib.contextmanager
def cm():
print("cm enter")
a = yield
print('cm exit')
def genfunc():
with cm():
print("stepping")
yield
def main():
gen = genfunc()
ref = weakref.ref(gen, print)
next(gen)
if __name__ == "__main__":
main()
Output:
cm enter
stepping
<weakref at 0x7f4739e38e08; dead>
Describe the solution you'd like
Generator functions decorated with @contextlib.contextmanager
should not be used in generators unless the context manager has finally:
@contextlib.contextmanager
def cm():
try:
yield
finally:
# cleanup code here
...
or specifically handles GeneratorExit
:
@contextlib.contextmanager
def cm():
try:
yield
except GeneratorExit:
# cleanup code here
...
Additional context
Add any other context about the feature request here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment