Samuele Pedroni wrote:
>
> Given that we have os.environ maybe
> we should implement os.path.expandvars too.
We could probably just steal the CPython version...
Hmm. Two CPython versions (ntpath, posixpath):
They both appear to work, but the ntpath version is richer - it allows quoting:
Jython 2.1a1 on java1.3.0 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>> sys.path.append( "d:/Program Files/Python/Lib" )
>>> import ntpath
>>> import posixpath
>>> p1 = "My '$PATH' is $PATH"
>>> ntpath.expandvars( p1 )
"My '$PATH' is d:\\netscape\\server4\\ias\\usr\\java\\bin;D:\\Netscape\\Server4\\ias\\usr\\java\\jre\\bin;d:\\netscape\\server4\\ias\\bin;d:\\netscape\\server4\\ias\\APPS\\bin;D:\\Perl\\bin\\;D:\\JDK1.3\\BIN;D:\\CYGNUS\\CYGWIN-B20\\H-I586-CYGWIN32\\BIN;D:\\WINNT\\SYSTEM32;D:\\WINNT;;f:\\forte\\install\\bin;f:\\forte\\objectivity\\bin;f:\\forte\\userapp\\wfclient\\cl1;f:\\forte\\userapp\\ofcustom\\cl0;f:\\forte\\userapp\\wfcustom\\cl0;f:\\forte\\userapp\\wfenvdef\\cl1;f:\\forte\\userapp\\wfclien1\\cl1;f:\\forte\\userapp\\wfaccess\\cl1;e:\\javacc2.0\\bin;.;e:\\work\\kb\\bin;d:\\users\\kbutler\\bin;d:/jdk1.2.2\\bin;e:\\work\\build\\bin;e:\\ant\\bin;d:\\perl\\bin;w:\\src\\bin;w:\\3rd-party\\NT;w:\\bin"
>>> posixpath.expandvars( p1 )
"My 'd:\\netscape\\server4\\ias\\usr\\java\\bin;D:\\Netscape\\Server4\\ias\\usr\\java\\jre\\bin;d:\\netscape\\server4\\ias\\bin;d:\\netscape\\server4\\ias\\APPS\\bin;D:\\Perl\\bin\\;D:\\JDK1.3\\BIN;D:\\CYGNUS\\CYGWIN-B20\\H-I586-CYGWIN32\\BIN;D:\\WINNT\\SYSTEM32;D:\\WINNT;;f:\\forte\\install\\bin;f:\\forte\\objectivity\\bin;f:\\forte\\userapp\\wfclient\\cl1;f:\\forte\\userapp\\ofcustom\\cl0;f:\\forte\\userapp\\wfcustom\\cl0;f:\\forte\\userapp\\wfenvdef\\cl1;f:\\forte\\userapp\\wfclien1\\cl1;f:\\forte\\userapp\\wfaccess\\cl1;e:\\javacc2.0\\bin;.;e:\\work\\kb\\bin;d:\\users\\kbutler\\bin;d:/jdk1.2.2\\bin;e:\\work\\build\\bin;e:\\ant\\bin;d:\\perl\\bin;w:\\src\\bin;w:\\3rd-party\\NT;w:\\bin' is
d:\\netscape\\server4\\ias\\usr\\java\\bin;D:\\Netscape\\Server4\\ias\\usr\\java\\jre\\bin;d:\\netscape\\server4\\ias\\bin;d:\\netscape\\server4\\ias\\APPS\\bin;D:\\Perl\\bin\\;D:\\JDK1.3\\BIN;D:\\CYGNUS\\CYGWIN-B20\\H-I586-CYGWIN32\\BIN;D:\\WINNT\\SYSTEM32;D:\\WINNT;;f:\\forte\\install\\bin;f:\\forte\\objectivity\\bin;f:\\forte\\userapp\\wfclient\\cl1;f:\\forte\\userapp\\ofcustom\\cl0;f:\\forte\\userapp\\wfcustom\\cl0;f:\\forte\\userapp\\wfenvdef\\cl1;f:\\forte\\userapp\\wfclien1\\cl1;f:\\forte\\userapp\\wfaccess\\cl1;e:\\javacc2.0\\bin;.;e:\\work\\kb\\bin;d:\\users\\kbutler\\bin;d:/jdk1.2.2\\bin;e:\\work\\build\\bin;e:\\ant\\bin;d:\\perl\\bin;w:\\src\\bin;w:\\3rd-party\\NT;w:\\bin"
I'd recommend we steal the ntpath.py version, and also suggest that we (who is "we"?) contact python-dev w/ a request to unify the two functions...
Note that neither the documentation for posixpath nor for ntpath describe the quoting behavior above.
Here is ntpath.expandvars:
# Expand paths containing shell variable substitutions.
# The following rules apply:
# - no expansion within single quotes
# - no escape character, except for '$$' which is translated into '$'
# - ${varname} is accepted.
# - varnames can be made out of letters, digits and the character '_'
# XXX With COMMAND.COM you can use any characters in a variable name,
# XXX except '^|<>='.
varchars = string.letters + string.digits + '_-'
def expandvars(path):
"""Expand shell variables of form $var and ${var}.
Unknown variables are left unchanged."""
if '$' not in path:
return path
res = ''
index = 0
pathlen = len(path)
while index < pathlen:
c = path[index]
if c == '\'': # no expansion within single quotes
path = path[index + 1:]
pathlen = len(path)
try:
index = string.index(path, '\'')
res = res + '\'' + path[:index + 1]
except string.index_error:
res = res + path
index = pathlen -1
elif c == '$': # variable or '$$'
if path[index + 1:index + 2] == '$':
res = res + c
index = index + 1
elif path[index + 1:index + 2] == '{':
path = path[index+2:]
pathlen = len(path)
try:
index = string.index(path, '}')
var = path[:index]
if os.environ.has_key(var):
res = res + os.environ[var]
except string.index_error:
res = res + path
index = pathlen - 1
else:
var = ''
index = index + 1
c = path[index:index + 1]
while c != '' and c in varchars:
var = var + c
index = index + 1
c = path[index:index + 1]
if os.environ.has_key(var):
res = res + os.environ[var]
if c != '':
res = res + c
else:
res = res + c
index = index + 1
return res
kb
|