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
Store the venv prompt in pyvenv.cfg #79842
Comments
When creating the pyvenv.cfg file, the prompt setting should be stored there so that tools can introspect on it (e.g. VS Code could read the value to tell users the name of the venv they have selected in the status bar). |
Adding my comment from the PR review: Dealing with leading/trailing whitespace could get interesting here. All the other values can be trimmed at both ends, while this one (currently) must have one space removed from the start. Perhaps we should insert the repr of the prompt instead? Or at least double-quote it and escape internal quotes and backslashes? |
Currently, the prompt is enclosed in parentheses, both in the venv and when storing: PS N:\projects\cpython> python -m venv testvenv --prompt=" prompt with spaces " Contents of pyvenv.cfg: I also tested using quotes in the prompt, which lead to opening bpo-35667. Here's a prompt that itself has parentheses: It seemed to me that the parenthesis would allow the retrieval of both the original prompt definition and how it looked in display. Maybe my tests didn't demonstrate this clearly? |
Your tests actually went the other way. This one puts a trailing space after the prompt and expected it to be there in the file, but also ensured that exactly one space was added at the start.
In the line "prompt = (My prompt) ", we need to define which of the spaces at either end of the value should be retained by tools trying to use the same prompt. The obvious assumption is to strip both ends, which would break your test. The next most obvious is to quote the string value (e.g. write repr(context.prompt) instead of the prompt directly). Also, I'm pretty sure I saw some advice once to use multiple lines worth of prompt, which probably breaks many shells but presumably works okay in Bash. You'll need to handle that case as well - again, repr() will do it naturally by encoding newlines an "\n". Anyone reading the string will have to do the equivalent of Python's literal_eval(), but that's pretty manageable in exchange for avoiding a whole lot of edge cases. |
Steve, thanks for explaining that. I understand what you're saying now. It's funny but because the context prompt has the space added at the end when it's created ( |
First, Cheryl, thanks for taking this on! I think one way to potentially simplify this whole situation about the whitespace for the prompt is to actually store the raw value that gets passed into EnvBuilder instead of the prompt as formatted for the activation scripts. I personally only want that initial value anyway and not the formatted version for the prompt for us in VS Code. Plus if we document that the value that we save in the pyvenv.cfg will be stripped then that should help with this. Otherwise I say go with the repr as Steve suggested, but I would still like to have access to the unformatted value (and probably not bother setting it if a custom value isn't provided to facilitate relocating venvs). |
One other aspect of this may be the confusion that ensues when changing the setting doesn't change the prompt when you activate it. It would be possible (though not necessarily trivial) to update the activate scripts to read the prompt from the file, though I don't think it's necessary. But we'll get a bug report sooner or later anyway. Maybe if the setting is called "provided-custom-prompt" that will imply enough that it's a optional record of the prompt rather than an active configuration setting? |
I've made the changes suggested by Brett to store the raw value instead of the formatted prompt. I also have been looking into issues Steve raised about using the prompt value from One thing that I did find which may be a current bug is:
--upgrade changes the prompt on And for reference, there is another bug issue for storing the --prompt value in an environment variable (bpo-35328). |
I think upgrading the scripts to read from pyvenv.cfg is a separate issue per activation script (e.g. an issue for PowerShell, an issue for fish, etc.) as this could be done piecemeal. One benefit to doing this is it would help move towards the activation scripts becoming static and thus skipping the string substitution when writing the files to disk. |
This issue broke x86 Gentoo Installed with X 3.x buildbot: https://buildbot.python.org/all/#/builders/103/builds/2208 ERROR: test_prompt (test.test_venv.BasicTest) Traceback (most recent call last):
File "/buildbot/buildarea/cpython/3.x.ware-gentoo-x86.installed/build/target/lib/python3.8/test/test_venv.py", line 123, in test_prompt
builder.create(self.env_dir)
File "/buildbot/buildarea/cpython/3.x.ware-gentoo-x86.installed/build/target/lib/python3.8/venv/__init__.py", line 70, in create
self.setup_scripts(context)
File "/buildbot/buildarea/cpython/3.x.ware-gentoo-x86.installed/build/target/lib/python3.8/venv/__init__.py", line 278, in setup_scripts
self.install_scripts(context, path)
File "/buildbot/buildarea/cpython/3.x.ware-gentoo-x86.installed/build/target/lib/python3.8/venv/__init__.py", line 354, in install_scripts
with open(dstfile, 'wb') as f:
PermissionError: [Errno 13] Permission denied: '/buildbot/tmp/tmpdir/tmph7_oob5e/bin/Activate.ps1' Please either fix or revert the change. |
Presumably the issue is in the test and not the main change itself. Is this another case where Linux can't run venv tests inside a venv? |
Sorry about that. I'll work on a fix and test it on the buildbots first. There are some tests with pyvenv.cfg that are skipped if it happens in a venv (@skipInVenv decorator), but the test right above this one (test_defaults) does not use the decorator and it checks pyvenv.cfg, so I think test_prompt might just need to do some cleanup first. |
Maybe you can just call builder.create_configuration() from the test and pass in enough context that it doesn't have to create a real venv? That would also make the test faster. |
It may also be that the directory exists already - the previous test explicitly removes it before calling create(). |
Steve, thanks for the suggestions. Looking at the other tests, I've added the code to explicitly remove the directory and I also slightly reorganized the create. Not all the tests use the I tried to submit the tests just to the buildbots based on the devguide, but they were failing for other reasons, so I made the PR. I don't think we'll know if this fixes the bots until the PR is merged, but if one of you could take a look and approve it, I'd appreciate it. And then I'll keep my fingers crossed. :-) |
The PR looks good to me. Are you able to test this test running from in a venv? I'm not at all clear why it would work there when the others fail (there's another issue looking at this, since it's only Linux that doesn't support venv-in-venv, but the tests are mostly all skipped anyway) |
Thanks Steve. The venv tests run for me from inside a venv on Windows 10 from a command prompt. From Powershell, all the tests fail with the following when run from inside a venv: I haven't tried on linux. |
Yeah, that failure on Windows is due to not correctly detecting a venv made from a build tree, rather than a venv from a proper install. I have a fix for that in the other bug. If it got that far, it means it used the correct prefix path, so it'll be fine. |
Looks like the buildbot is happy now. Thank you everyone! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: