Skip to content

Commit

Permalink
Repair hermetic_environment_as for C-level environment variable acce…
Browse files Browse the repository at this point in the history
…ss. (#5898)

Relates to #5893
  • Loading branch information
kwlzn authored Jun 1, 2018
1 parent e8c8076 commit 7d3bbed
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/python/pants/util/contextutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,31 @@ def setenv(key, val):
setenv(key, val)


def _purge_env():
# N.B. Without the use of `del` here (which calls `os.unsetenv` under the hood), subprocess32
# invokes or other things that may access the environment at the C level may not see the
# correct env vars (i.e. we can't just replace os.environ with an empty dict).
# See https://docs.python.org/2/library/os.html#os.unsetenv for more info.
for k in os.environ.keys():
del os.environ[k]


def _restore_env(env):
for k, v in env.items():
os.environ[k] = v


@contextmanager
def hermetic_environment_as(**kwargs):
"""Set the environment to the supplied values from an empty state."""
old_environment, os.environ = os.environ, {}
old_environment = os.environ.copy()
_purge_env()
try:
with environment_as(**kwargs):
yield
finally:
os.environ = old_environment
_purge_env()
_restore_env(old_environment)


@contextmanager
Expand Down
10 changes: 10 additions & 0 deletions tests/python/pants_test/util/test_contextutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ def test_hermetic_environment(self):
with hermetic_environment_as(**{}):
self.assertNotIn('USER', os.environ)

def test_hermetic_environment_subprocesses(self):
self.assertIn('USER', os.environ)
with hermetic_environment_as(**dict(AAA='333')):
output = subprocess.check_output('env', shell=True)
self.assertNotIn('USER=', output)
self.assertIn('AAA', os.environ)
self.assertEquals(os.environ['AAA'], '333')
self.assertIn('USER', os.environ)
self.assertNotIn('AAA', os.environ)

def test_simple_pushd(self):
pre_cwd = os.getcwd()
with temporary_dir() as tempdir:
Expand Down

0 comments on commit 7d3bbed

Please sign in to comment.