Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use path names containing dollar signs #63

Open
zooba opened this issue Oct 18, 2021 · 5 comments
Open

Cannot use path names containing dollar signs #63

zooba opened this issue Oct 18, 2021 · 5 comments
Labels
bug Something isn't working deferred Deferred until distutils adoption is established

Comments

@zooba
Copy link
Contributor

zooba commented Oct 18, 2021

(Migrated from https://bugs.python.org/issue33193 - the below text is from a reply with more useful context than the OP)

An exotic case, but it also affects Linux:

python3.7 -m venv 'at$test'
Error: Command '['/home/maier/at$test/bin/python3.7', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 2.
[maier@nb19 ~]$ mkdir 'at$test'
mkdir: cannot create directory ‘at$test’: File exists
[maier@nb19 ~]$ cd 'at$test'
[maier@nb19 at$test]$ bin/python -m ensurepip
Collecting setuptools
Collecting pip
Installing collected packages: setuptools, pip
Exception:
Traceback (most recent call last):
  File "/usr/lib64/python3.7/distutils/util.py", line 187, in subst_vars
    return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s)
  File "/usr/lib64/python3.7/re.py", line 198, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "/usr/lib64/python3.7/distutils/util.py", line 184, in _subst
    return os.environ[var_name]
  File "/usr/lib64/python3.7/os.py", line 678, in __getitem__
    raise KeyError(key) from None
KeyError: 'test'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/tmpppaapmyk/pip-9.0.1-py2.py3-none-any.whl/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/tmp/tmpppaapmyk/pip-9.0.1-py2.py3-none-any.whl/pip/commands/install.py", line 342, in run
    prefix=options.prefix_path,
  File "/tmp/tmpppaapmyk/pip-9.0.1-py2.py3-none-any.whl/pip/req/req_set.py", line 784, in install
    **kwargs
  File "/tmp/tmpppaapmyk/pip-9.0.1-py2.py3-none-any.whl/pip/req/req_install.py", line 851, in install
    self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
  File "/tmp/tmpppaapmyk/pip-9.0.1-py2.py3-none-any.whl/pip/req/req_install.py", line 1064, in move_wheel_files
    isolated=self.isolated,
  File "/tmp/tmpppaapmyk/pip-9.0.1-py2.py3-none-any.whl/pip/wheel.py", line 247, in move_wheel_files
    prefix=prefix,
  File "/tmp/tmpppaapmyk/pip-9.0.1-py2.py3-none-any.whl/pip/locations.py", line 153, in distutils_scheme
    i.finalize_options()
  File "/usr/lib64/python3.7/distutils/command/install.py", line 307, in finalize_options
    self.expand_basedirs()
  File "/usr/lib64/python3.7/distutils/command/install.py", line 486, in expand_basedirs
    self._expand_attrs(['install_base', 'install_platbase', 'root'])
  File "/usr/lib64/python3.7/distutils/command/install.py", line 480, in _expand_attrs
    val = subst_vars(val, self.config_vars)
  File "/usr/lib64/python3.7/distutils/util.py", line 189, in subst_vars
    raise ValueError("invalid variable '$%s'" % var)
ValueError: invalid variable '$'test''

So the venv actually gets created, but it's ensurepip which chokes on the $.

@zooba
Copy link
Contributor Author

zooba commented Oct 18, 2021

Presumably the "real" fix here for CPython will be in pip and will eventually be adopted into ensurepip, but the underlying issue belongs to distutils.

@jaraco
Copy link
Member

jaraco commented Dec 12, 2021

This issue might have been fixed incidentally in #23, except that backward compatibility for $ substitutions was retained.

@jaraco
Copy link
Member

jaraco commented Dec 12, 2021

But more important is that literal characters in the path should never trigger substitutions.

@jaraco jaraco added the bug Something isn't working label Dec 12, 2021
@jaraco
Copy link
Member

jaraco commented Dec 12, 2021

I started to explore how it might be possible to allow these characters to pass without triggering substitutions, but then I realized that it's currently possible for someone to pass values that the intend to be substituted, like:

setup.py install --install-purelib '$userbase/foo' ...
# or
setup.py install --install-purelib '{userbase}/foo' ...

And in that case, distutils would substitute the userbase value just as it does for sysconfig-supplied parameters.

I'm not sure if that's a supported use-case or an incidental behavior that should be disallowed.

If use-cases demand that substitutions be allowed for supplied parameters (and not just those from sysconfig or defaults), then it will be impossible to distinguish $userbase (literal) from $userbase (intended substitution) when supplied.

I think it's going to be difficult to solve this until we can have this codebase widely adopted, so I'm going to defer this until after Setuptools is using it by default.

@jaraco jaraco added the deferred Deferred until distutils adoption is established label Dec 12, 2021
@smartYSC
Copy link

smartYSC commented Oct 9, 2023

We are seeing this issue as well. But we made the (questionable) decision to use a $ sign in the user name of the executing user (on Windows).

To work around the issue decribed above we would set the environment variable test to $test. This works, because the substitution is only executed once and not recursively. Then it finds the variable and substitutes it with the original string, effectively doing nothing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working deferred Deferred until distutils adoption is established
Projects
None yet
Development

No branches or pull requests

3 participants