@contextlib.contextmanager<EOL>def envcontext(patch, _env=None):
env = os.environ if _env is None else _env<EOL>before = env.copy()<EOL>for k, v in patch:<EOL><INDENT>if v is UNSET:<EOL><INDENT>env.pop(k, None)<EOL><DEDENT>elif isinstance(v, tuple):<EOL><INDENT>env[k] = format_env(v, before)<EOL><DEDENT>else:<EOL><INDENT>env[k] = v<EOL><DEDENT><DEDENT>try:<EOL><INDENT>yield<EOL><DEDENT>finally:<EOL><INDENT>env.clear()<EOL>env.update(before)<EOL><DEDENT>
In this context, `os.environ` is modified according to `patch`.

    `patch` is an iterable of 2-tuples (key, value):
        `key`: string
        `value`:
            - string: `environ[key] == value` inside the context.
            - UNSET: `key not in environ` inside the context.
            - template: A template is a tuple of strings and Var which will be
              replaced with the previous environment