the shortest context manager

2013.Apr.15

I once had a piece of code that looked like this:

1
2
with context() as ctx:
	f(ctx)

In analysing this code, I wanted to temporarily remove the context manager, but I didn’t want to unindent the following code.

The simplest way to do this would probably have been:

1
2
3
# with context() as ctx:
if True:
	f()

However, I started wondering: what’s the shortest context manager we can write?

What’s the shortest context manager we can write: * if we allow or disallow imports * if we require or don’t require it to provide a value

In each case, we will not require the context manager to actually do any work. I will call the context manager noop to emphasise this point. Additionally, we’ll look for the shortest piece of code, ignoring whitespace and the names of variables we can control. (I could call the context manager n instead of noop, but this shortening doesn’t bear any meaning.)

1
2
3
4
5
# allowing imports
from contextlib import contextmanager
noop = contextmanager(lambda: (yield)) 
with noop():
	pass
1
2
3
4
# disallowing imports
noop = type('', (), {'__enter__': int, '__exit__': max})
with noop():
	pass

The following might be useful as a way to temporarily disable a context manager and pass a mock context object (… but actually not that useful.)

1
2
3
4
5
6
# allowing imports and returning a specific value
value = object()
from contextlib import contextmanager
noop = contextmanager(lambda: (yield value)) 
with noop() as val:
	print val
1
2
3
4
5
6
# disallowing imports and returning a specific value
value = object()
noop = type('', (), {'__enter__': lambda _: value, '__exit__': max})
{}.__get__
with noop() as val:
	print val

Can you write one any shorter? Send me an e-mail.

I suspect there may be a shorter way to write the last one.