Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I handle None's in context managers in python?

In Python, the following pattern is quite common.

thing = x and load_thing(x)

which propagates None through your code (if x is None then so is thing). This is useful because later in your code you can check if thing is None and have different logic.

I'm not sure how to make this play well with context managers: the following code does not work (because if x is None, with None as y is not valid (because None does not have __enter__)

with x and load_thing(x) as y:
    f(y)

The best thing I've come up with is this, but I think the people reading my code might curse me (no sense of fun I tell you, no sense of fun).

@contextlib.contextmanager
def const_manager(x):
    yield x


with (const_manager(x) if x is None else load_thing(x)) as y:
    f(y)

Is there a more pythonic alternative? Besides layers and layers of function definitions and calls.

like image 689
Att Righ Avatar asked Oct 27 '25 06:10

Att Righ


1 Answers

Put the test in your wrapper context manager.

@contextlib.contextmanager
def default_manager(cm, x):
    if x is None:
        yield x
    else:
        yield cm(x)


with default_manager(load_thing, x) as y:
    f(y)

You might also consider using contextlib.nullcontext instead.

with (load_thing if x is not None else nullcontext)(x) as y:
    f(y)
like image 148
chepner Avatar answered Oct 29 '25 20:10

chepner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!