File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -295,10 +295,14 @@ class switchenv(SwitchDecorator):
295295 the context manager, so should be used cautiously.
296296 """
297297 def __init__ (self , params ):
298- self .previous = dict (os .environ )
299298 self .params = params
299+ self .previous = {}
300300
301301 def __enter__ (self ):
302+ # Snapshot the environment upon entering, not upon construction, since the
303+ # same object is reused across entries, most notably as a decorator
304+ self .previous = dict (os .environ )
305+
302306 # Prevent having multiple conflicting device vars, e.g
303307 # switching CUDA_VISIBLE_DEVICES but having NVIDIA_VISIBLE_DEVICES set.
304308 from devito .arch .archinfo import device_vars
Original file line number Diff line number Diff line change @@ -344,3 +344,33 @@ def test_switchenv():
344344
345345 # Make sure the switchenv does not persist to verify switchenv works as intended
346346 assert dict (os .environ ) == previous_environ
347+
348+
349+ def test_switchenv_reuse ():
350+ # Save previous environment
351+ previous_environ = dict (os .environ )
352+
353+ try :
354+ # A switchenv is constructed once, when the decorator is applied, and then
355+ # reused on every call of the decorated function
356+ @switchenv ({'TEST_VAR' : 'foo' })
357+ def foo ():
358+ return os .environ ['TEST_VAR' ]
359+
360+ # Set after the decorator has been applied, so it is not visible to an
361+ # environment snapshot taken at construction time
362+ os .environ ['TEST_VAR_LATE' ] = 'bar'
363+
364+ assert foo () == 'foo'
365+ assert os .environ .get ('TEST_VAR' ) is None
366+ assert os .environ ['TEST_VAR_LATE' ] == 'bar'
367+
368+ # Same story for a switchenv reused as a context manager
369+ cm = switchenv ({'TEST_VAR' : 'foo' })
370+ os .environ ['TEST_VAR_LATER' ] = 'baz'
371+ with cm :
372+ assert os .environ ['TEST_VAR' ] == 'foo'
373+ assert os .environ ['TEST_VAR_LATER' ] == 'baz'
374+ finally :
375+ os .environ .clear ()
376+ os .environ .update (previous_environ )
You can’t perform that action at this time.
0 commit comments