Skip to content

Instantly share code, notes, and snippets.

@isidentical
Created February 12, 2019 15:29
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 isidentical/cc0bf03d762e47ba2674d4f680926e5a to your computer and use it in GitHub Desktop.
Save isidentical/cc0bf03d762e47ba2674d4f680926e5a to your computer and use it in GitHub Desktop.
Simple contextlib.contextmanager implementation
class ContextManager:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
self.gen = self.func(*args, **kwargs)
return self
def __enter__(self):
return next(self.gen)
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is None:
pass
else:
self.gen.throw(exc_type, exc_val, exc_tb)
def contextmanager(f):
return ContextManager(f)
@contextmanager
def my_func(tot):
a_list = []
try:
yield a_list
finally:
print(tot, a_list)
with my_func(15) as l:
l.append(1)
l.append(2)
c=lambda f:(lambda *a,**k:type('H',(),{'__init__': lambda s,f,*a,**k:setattr(s,'g',f(*a, **k)),'__enter__':lambda s:next(s.g),'__exit__':lambda s, t, v, b:t if t is None else s.g.throw(t,v,b)})(f, *a, **k))
@c
def my_func(tot):
a_list = []
try:
yield a_list
finally:
print(tot, a_list)
with my_func(15) as l:
l.append(1)
l.append(2)
exec("c=%sf:(%s`:type('H',(),{'__init__':%ss,f,`:setattr(s,'g',f(`)),'__enter__':%ss:next(s.g),'__exit__':%ss,t,v,b:t if t is None else s.g.throw(t,v,b)})(f,`))".replace('`','*a,**k')%(("lambda ",)*5))
@c
def managed_file(name):
try:
f = open(name, 'w')
yield f
finally:
f.close()
with managed_file('naber.txt') as f:
f.write('naber')
Copy link

ghost commented Feb 12, 2019

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is not None:
            self.gen.throw(exc_type, exc_val, exc_tb)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment