I recently encountered an elusive bug, which eventually I tracked down to the fact that environment variables are not replaced in a certain string even though it is set by calling os.path.expandvars(original string).
Turns out, the problem is that expandvars() doesn’t expand variables who are enclosed within a string literal. I couldn’t find it documented anywhere but facts are, this is the case.
>>> import os >>> os.environ['VAR1'] = 'Value1' >>> s1 = "this is '%VAR1%'" >>> os.path.expandvars(s1) "this is '%VAR1%'" >>> s2 = "this is %VAR1%" >>> os.path.expandvars(s2) 'this is Value1'
It may be a good idea in some cases, but for me it was quite an annoyance.
So, how to overcome this?
Here’s a small method I use to replace variables regardless if they are quoted or not. It may not be perfect, but it serves the purpose.
def expand_all_vars(s): s_out = os.path.expandvars(s) # look for non replaced variables regex = r"%([^\s]+?)%" matches = re.finditer(regex, s_out) for matchNum, match in enumerate(matches): var = match.group(0) var_stripped = var.replace('%','') if var_stripped in os.environ: s_out = s_out.replace(var, os.environ[var_stripped]) return s_out