I am trying to hide some try/except complexity with a contextmanager. Here is an easy example:
from contextlib import contextmanager
import mpd
mpdclient = mpd.MPDClient()
mpdclient.connect("localhost", 6600)
@contextmanager
def mpdcontext():
try:
yield
except mpd.ConnectionError:
mpdclient.connect("localhost", 6600)
with mpdcontext():
mpdclient.status()
with mpdcontext():
mpdclient.lsinfo()
Now, as I understood, the block in the with statement is executed when yield is called. In my case, if this raises an exception, I reconnect to mpd. Can I somehow execute the with-block again after this reconnect?
Thanks
Short answer is you can't yield twice from a context manager. You could consider using a decorator that wraps what you're trying to execute and will retry and reconnect a set number of times before giving up. Here's a trivial (non-production use) example just to illustrate:
import mpd
import functools
HOST = "localhost"
PORT = 6600
mpdclient = mpd.MPDClient()
mpdclient.connect(HOST, PORT)
def withreconnect(retries=1):
def _wrapper(func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
for _ in range(retries + 1): # Loop retries + first attempt
try:
return func(*args, **kwargs)
except mpd.ConnectionError:
mpdclient.connect(HOST, PORT)
return _wrapped
return wrapped
@withreconnect() # Reconnect 1 time, default
def status():
mpdclient.status()
@withreconnect(retries=3) # Reconnect 3 times
def lsinfo():
mpdclient.lsinfo()
Edit: added call to decorator, in the no-argument case
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