The prefix context manager (and probably others that are using _setenv) don't behave as expected when not called immediately prior to __enter__(). This means that the context manager isn't usable with contextlib.nested. Here's an example:
from contextlib import nested
from fabric import prefix, state
with nested(prefix('echo 1'), prefix('echo 2')):
print state.env.command_prefixes
Expected Output:
Actual Output:
The reason is because the new values are being stored at the time prefix is called—not when the context is entered. So, in the example above, when prefix is called the first time, it defines the context manager as setting command_prefixes to the current value ([]) plus ['echo 1']. When it's called the second time, the current value of command_prefixes is still an empty list (because the first context hasn't been entered yet), so the context manager is defined as setting command_prefixes to ['echo 2']. Therefore, entering the second context manager clobbers any effect of entering the first.
The fix, I think, is to defer the getting of command_prefixes until the context is entered.
The
prefixcontext manager (and probably others that are using_setenv) don't behave as expected when not called immediately prior to__enter__(). This means that the context manager isn't usable withcontextlib.nested. Here's an example:Expected Output:
Actual Output:
The reason is because the new values are being stored at the time
prefixis called—not when the context is entered. So, in the example above, whenprefixis called the first time, it defines the context manager as settingcommand_prefixesto the current value ([]) plus['echo 1']. When it's called the second time, the current value ofcommand_prefixesis still an empty list (because the first context hasn't been entered yet), so the context manager is defined as settingcommand_prefixesto['echo 2']. Therefore, entering the second context manager clobbers any effect of entering the first.The fix, I think, is to defer the getting of
command_prefixesuntil the context is entered.