Skip to content

Instantly share code, notes, and snippets.

@icio
Created January 6, 2016 14:20
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 icio/c0d3f7efd415071f725b to your computer and use it in GitHub Desktop.
Save icio/c0d3f7efd415071f725b to your computer and use it in GitHub Desktop.
Python enter_context
"""Imperative enter/exit control for python contextmanagers.
Where you'd prefer to use `with`:
with my_context(123) as f:
do_something()
but only have access to before and after hook-functions (as with Flask):
def before_hook():
pass # Enter the context.
def after_hook():
pass # Exit the context.
def handler():
return do_something()
you can use the `enter_context` function as an open/close pair of functions:
ctxt = threading.local()
def before_hook():
f, ctxt.close_context = enter_context(my_context, 123)
def after_hook():
ctxt.close_context()
def handler():
return do_something()
"""
from contextlib import contextmanager
from functools import partial
def main():
with context(123) as mgr:
print "middle: %r" % (mgr,)
print "---"
mgr, exit_context = enter_context(context, 456)
print "middle: %r" % (mgr,)
exit_context()
@contextmanager
def context(*args, **kwargs):
print "in"
yield {'args': args, 'kwargs': kwargs}
print "out"
def enter_context(func, *args, **kwargs):
def enter():
with func(*args, **kwargs) as f:
yield f
e = enter()
def exit():
try:
next(e)
except StopIteration:
pass
return next(e), exit
if __name__ == "__main__":
main()
@icio
Copy link
Author

icio commented Jan 6, 2016

$ python context_faker.py
in
middle: {'args': (123,), 'kwargs': {}}
out

---
in
middle: {'args': (456,), 'kwargs': {}}
out

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