Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

manually open context manager

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

like image 550
luckydonald Avatar asked Aug 06 '18 11:08

luckydonald


People also ask

How do you implement a context manager?

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.

What does __ exit __ do in Python?

__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.

What should __ exit __ return?

__enter__() is provided which returns self while object. __exit__() is an abstract method which by default returns None .

Which methods are required to implement context management protocol?

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__().

What is Contextlib?

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.

What does Contextmanager decorator do?

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.


2 Answers

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)
like image 90
Netwave Avatar answered Oct 30 '22 05:10

Netwave


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.

like image 28
L3viathan Avatar answered Oct 30 '22 05:10

L3viathan