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'
from flask docs
There are two ways to implement a context manager. The first one is defining a class with implementations for the __enter__ and __exit__ methods. The second one is by creating a generator and using the contextlib. contextmanager decorator.
__exit__() method The __exit__ method takes care of releasing the resources occupied with the current code snippet. This method must be executed no matter what after we are done with the resources.
__enter__() is provided which returns self while object. __exit__() is an abstract method which by default returns None .
Context managers can be written using classes or functions(with decorators). Creating a Context Manager: When creating context managers using classes, user need to ensure that the class has the methods: __enter__() and __exit__().
Overview. The contextlib module of Python's standard library provides utilities for resource allocation to the with statement. The with statement in Python is used for resource management and exception handling. Therefore, it serves as a good Context Manager.
Decorators are very powerful and useful tool in Python since it allows programmers to modify the behavior of function or class. Decorators allow us to wrap another function in order to extend the behavior of wrapped function, without permanently modifying it.
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With