Keeping context-manager object alive through function calls

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Nov 11 02:18:59 EST 2015


On Wednesday 11 November 2015 09:36, Pablo Lucena wrote:

> I am running into a bit of an issue with keeping a context manager open
> through function calls. Here is what I mean:
[...]
> In order to keep the SSH session open and not have to re-establish it
> across function calls, I would like to do add an argument to "do_stuff"
> which can optionally return the SSH session along with the data returned
> from the SSH session, as follows:

That won't work. The whole point of the "with" statement is to automatically 
close the context manager when you leave the with statement. If you don't 
want it automatically closed, *don't use with*.

There's nothing wrong with manually opening and closing the connection, if 
that's what you need. Open the ssh connection, pass it to your various 
functions, and close it only when you are done with it.

Or, and this might be a better solution, move the with block up a level. 
Instead of putting it in "do_stuff" and the assorted other functions, open 
the connection *before* you call these functions:


def main():
    setup()
    with manager(device) as conn:
        do_stuff(conn)
        do_more_stuff(conn)
        do_even_more_stuff(conn)
    # Now we're finally done.
    sys.exit(0)



[...]
> I have tried converting "do_stuff" into a generator, such that its state
> is suspended and perhaps causing the context-manager to stay open:
[...]
> However this approach does not seem to be working in my case, as the
> context-manager gets closed, and I get back a closed socket.
> 
> Is there a better way to approach this problem? Maybe my generator needs
> some more work...I think using a generator to hold state is the most
> "obvious" way that comes to mind, but overall should I be looking into
> another way of keeping the session open across function calls?

You might be able to get some awful hack using generators working, but it 
will be ugly, confusing and fragile. This is a sign you are abusing the 
context manager and using it in a way that goes against the design of the 
feature. Consider some future maintainer (perhaps even yourself, in six 
months or a year), reading the code, and completely puzzled why the SSH 
connection isn't closed when the with block is exited.



-- 
Steve




More information about the Python-list mailing list