On 2/11/2022 2:01 PM, Paul Moore wrote:
On Fri, 11 Feb 2022 at 16:37, Christopher Barker <python...@gmail.com> wrote:
On Fri, Feb 11, 2022 at 12:28 AM Serhiy Storchaka <storch...@gmail.com> wrote:
expandvars() does not operate on paths, it operates on strings and
bytestrings. There is nothing path-specific here. Expanding environment
variables consists of three distinct steps:
sure -- but it does live in os.paths now, the docs talk about paths, and it is
useful for paths -- so it seems a fine idea to have that functionality in
pathlib.
One way that tying it to paths is bad is that it ignores the path
structure. If environment variable a is "d1/f1" and b is "d2/f2" then
"${a}x${b}" is "d1/f1xd2/f2", which could be very confusing to someone
who sees the value of b and expects the result to be a file in a
directory called d2. Yes, I know that the documentation could make
this clear (the docs in os.path don't, BTW) and I know that it's no
different than the os.path version, but adding an expandvars method to
pathlib feels like throwing good money after bad...
Let's leave it where it is and keep the status quo, or fix it
*properly* and put it somewhere more logical like shlex. Personally I
don't use it that often, so I'm fine with just leaving it alone.
I'd like to see a Path.expandvars(), something like:
--------------------------------------
import os
def _expand_part(part, allow_sep_in_env_var):
# Expand environment variables in 'part'. If allow_sep_in_env_var is
# False, the resulting string cannot contain a path separator.
s = os.path.expandvars(part)
if s == part:
return part
if not allow_sep_in_env_var and os.path.sep in s:
raise ValueError(f"expanded variable {part!r} may not contain a
path separator")
return s
def expandvars(path, allow_sep_in_env_var=False):
return type(path)(
*list(_expand_part(part, allow_sep_in_env_var) for part in
path.parts)
)
from pathlib import Path
os.environ["USER"] = "foo"
os.environ["a"] = "d1/f1"
os.environ["b"] = "d1/f1"
print(f'{expandvars(Path("/usr/local/bin")) = }')
print(f'{expandvars(Path("/home/${USER}")) = }')
print(f'{expandvars(Path("${a}x${b}"), True) = }')
print(f'{expandvars(Path("${a}x${b}")) = }')
--------------------------------------
Output:
expandvars(Path("/usr/local/bin")) = PosixPath('/usr/local/bin')
expandvars(Path("/home/${USER}")) = PosixPath('/home/foo')
expandvars(Path("${a}x${b}"), True) = PosixPath('d1/f1xd1/f1')
Traceback (most recent call last):
File "expandpaths.py", line 26, in <module>
print(f'{expandvars(Path("${a}x${b}")) = }')
File "expandpaths.py", line 14, in expandvars
return type(path)(*list(_expand_part(part, allow_sep_in_env_var)
for part in path.parts))
File "expandpaths.py", line 14, in <genexpr>
return type(path)(*list(_expand_part(part, allow_sep_in_env_var)
for part in path.parts))
File "expandpaths.py", line 10, in _expand_part
raise ValueError(f'expanded variable {part!r} may not contain a
path separator')
ValueError: expanded variable '${a}x${b}' may not contain a path separator
It would no doubt have to do something trickier with forward and back
slash detection after the expansion.
Eric
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/python-ideas@python.org/message/RQYAAGKGYAVG74X5QCFABKRJBJUL5P35/
Code of Conduct: http://python.org/psf/codeofconduct/