Reputation: 6856
My question is, how can I execute any context manager without using with
?
Python has the idea of context managers,
instead of
file = open('some_file', 'w')
try:
file.write('Hola!')
finally:
file.close()
# end try
you can write
with open('some_file', 'w') as opened_file:
opened_file.write('Hola!')
# end with
While in most cases the second one is the golden solution, however for the specific cases of testing in unit tests as well exploring in the interactive console, the first one can be much better used, as you can write it line by line.
>>> file = open('some_file', 'w')
>>> file.write('Hola!')
>>> file.close()
My question is, how can I execute any with
context manager like this, best suited for exploring?
My actual use case follows below, but please try to give a answer which is generic and will work for other context managers too.
import flask
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
assert flask.request.path == '/'
assert flask.request.args['name'] == 'Peter'
Upvotes: 19
Views: 6452
Reputation: 42718
You can still use with
syntax in the interactive console, however a context is based on 2 magic methods __enter__
and __exit__
, so you can just use them:
class MyCtx(object):
def __init__(self, f):
self.f = f
def __enter__(self):
print("Enter")
return self.f
def __exit__(*args, **kwargs):
print("Exit")
def foo():
print("Hello")
usually you do:
with MyCtx(foo) as f:
f()
Same as:
ctx = MyCtx(foo)
f = ctx.__enter__()
f()
ctx.__exit__()
Here you have the live example
Remember that contexts __exit__
method are used for managing errors within the context, so most of them have a signature of __exit__(exception_type, exception_value, traceback)
, if you dont need to handle it for the tests, just give it some None
values:
__exit__(None, None, None)
Upvotes: 21
Reputation: 27283
You can call app.test_request.context('/?name=Peter')
to a variable (e.g. ctx
), and then call ctx.__enter__()
on it to enter the context manager, and ctx.__exit__(None, None, None)
to perform the cleanup. Note that you lose the safety guarantees of context managers, unless you put the ctx.__exit__
in a finally
clause.
Upvotes: 1