Skip to content

Instantly share code, notes, and snippets.

@igniteflow
Last active December 12, 2023 16:43
Show Gist options
  • Save igniteflow/7267431 to your computer and use it in GitHub Desktop.
Save igniteflow/7267431 to your computer and use it in GitHub Desktop.
A Python context manager for setting/unsetting environment variables
from contextlib import contextmanager
"""
Usage:
with env_var('MY_VAR', 'foo'):
# is set here
# does not exist here
"""
@contextmanager
def env_var(key, value):
os.environ[key] = value
yield
del os.environ[key]
@tbradley-sans
Copy link

This looks great, and seems like exactly what I need. But why not use the built-in patch.dict?
https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch.dict

@m000
Copy link

m000 commented Sep 25, 2022

This further improves over @jdemaeyer's snippet. It allows using the context manager to temporarily unset an env variable (e.g. with environ(HOME=None)).

Also, because it uses pop(), it will not choke if an environment variable that was added by the context manager has been deleted by the wrapped code.

import os
from contextlib import contextmanager


@contextmanager
def environ(**env):
    originals = {k: os.environ.get(k) for k in env}
    for k, val in env.items():
        if val is None:
            os.environ.pop(k, None)
        else:
            os.environ[k] = val
    try:
        yield
    finally:
        for k, val in originals.items():
            if val is None:
                os.environ.pop(k, None)
            else:
                os.environ[k] = val

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment