Skip to content

Instantly share code, notes, and snippets.

@plq
Last active January 1, 2016 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plq/8164035 to your computer and use it in GitHub Desktop.
Save plq/8164035 to your computer and use it in GitHub Desktop.
Outsmarting context managers with coroutines
enter 1
enter 2
2 yo
exit 1 (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x6c7b48>)
hey
enter 1
enter 2
2 yo
exit 2 (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x7fdd928e6bd8>)
exit 1 (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x7fdd928e6c68>)
hey
enter 1
enter 2
2 yo
exit 1 (<class 'Exception'>, Exception(), <traceback object at 0x7f54fd7c96c8>)
exit 2 (<class 'GeneratorExit'>, GeneratorExit(), <traceback object at 0x7f54fd7c9b00>)
hey
enter 1
enter 2
2 yo
exit 2 (<class 'Exception'>, Exception(), <traceback object at 0x7f4449629830>)
exit 1 (<class 'Exception'>, Exception(), <traceback object at 0x7f4449629878>)
hey
#!/usr/bin/env python2
from __future__ import print_function
from inspect import isgenerator
def coroutine(func):
def start(*args, **kwargs):
ret = func(*args, **kwargs)
try:
next(ret)
except StopIteration:
return None
return ret
return start
class Cmgr(object):
def __init__(self, no):
self.no = no
def __enter__(self):
print("enter", self.no)
def __exit__(self, *args):
print("exit ", self.no, args)
@coroutine
def yo_gen2():
with Cmgr(2):
while True:
val = yield
print(2, val)
@coroutine
def yo_gen():
with Cmgr(1):
ret = yo_gen2()
if isgenerator(ret):
try:
while True:
val = yield
ret.send(val)
except Exception as e:
try:
ret.throw(e)
except:
pass
finally:
raise
gen = yo_gen()
gen.send("yo")
try:
gen.throw(Exception())
except Exception as e:
print(e)
a = raw_input('hey')
#!/usr/bin/env python2
from __future__ import print_function
def coroutine(func):
def start(*args, **kwargs):
ret = func(*args, **kwargs)
try:
next(ret)
except StopIteration:
return None
return ret
return start
class Cmgr(object):
def __init__(self, no):
self.no = no
def __enter__(self):
print("enter", self.no)
def __exit__(self, *args):
print("exit ", self.no, args)
@coroutine
def yo_gen2():
with Cmgr(2):
while True:
val = yield
print(2, val)
@coroutine
def yo_gen():
with Cmgr(1):
ret = yo_gen2()
while True:
val = yield
ret.send(val)
gen = yo_gen()
gen.send("yo")
try:
gen.throw(Exception())
except Exception as e:
print(e)
a = raw_input('hey')
#!/usr/bin/env python3
from __future__ import print_function
def coroutine(func):
def start(*args, **kwargs):
ret = func(*args, **kwargs)
try:
next(ret)
except StopIteration:
return None
return ret
return start
class Cmgr(object):
def __init__(self, no):
self.no = no
def __enter__(self):
print("enter", self.no)
def __exit__(self, *args):
print("exit ", self.no, args)
def yo_gen2():
with Cmgr(2):
while True:
val = yield
print(2, val)
@coroutine
def yo_gen():
with Cmgr(1):
yield from yo_gen2()
gen = yo_gen()
gen.send("yo")
try:
gen.throw(Exception())
except Exception as e:
print(e)
a = input('hey')
#!/usr/bin/env python3
from __future__ import print_function
def coroutine(func):
def start(*args, **kwargs):
ret = func(*args, **kwargs)
try:
next(ret)
except StopIteration:
return None
return ret
return start
class Cmgr(object):
def __init__(self, no):
self.no = no
def __enter__(self):
print("enter", self.no)
def __exit__(self, *args):
print("exit ", self.no, args)
@coroutine
def yo_gen2():
with Cmgr(2):
while True:
val = yield
print(2, val)
@coroutine
def yo_gen():
with Cmgr(1):
ret = yo_gen2()
while True:
val = yield
ret.send(val)
gen = yo_gen()
gen.send("yo")
try:
gen.throw(Exception())
except Exception as e:
print(e)
a = input('hey')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment