Error handling in context managers
Peter Otten
__peter__ at web.de
Tue Jan 17 03:34:13 EST 2017
Gregory Ewing wrote:
> Israel Brewster wrote:
>> The problem is that, from time to time, I can't get a connection, the
>> result being that cursor is None,
>
> That's your problem right there -- you want a better-behaved
> version of psql_cursor().
>
> def get_psql_cursor():
> c = psql_cursor()
> if c is None:
> raise CantGetAConnectionError()
> return c
>
> with get_psql_cursor() as c:
> ...
You still need to catch the error -- which leads to option (3) in my zoo,
the only one that is actually usable. If one contextmanager cannot achieve
what you want, use two:
$ cat conditional_context_raise.py
import sys
from contextlib import contextmanager
class NoConnection(Exception):
pass
class Cursor:
def execute(self, sql):
print("EXECUTING", sql)
@contextmanager
def cursor():
if "--fail" in sys.argv:
raise NoConnection
yield Cursor()
@contextmanager
def no_connection():
try:
yield
except NoConnection:
print("no connection")
with no_connection(), cursor() as cs:
cs.execute("insert into...")
$ python3 conditional_context_raise.py
EXECUTING insert into...
$ python3 conditional_context_raise.py --fail
no connection
If you want to ignore the no-connection case use
contextlib.suppress(NoConnection) instead of the custom no_connection()
manager.
More information about the Python-list
mailing list