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

Virtualenv in Powershell cannot be activated #1207

Closed
abhnvkmr opened this issue Dec 23, 2016 · 13 comments
Closed

Virtualenv in Powershell cannot be activated #1207

abhnvkmr opened this issue Dec 23, 2016 · 13 comments

Comments

@abhnvkmr
Copy link

On the latest version, when I run the Activate.ps1 script to enable the virtualenv, Cmder throws the following error. Virtualenvs work fine on regular PowerShell.

Cannot write to function prompt because it is read-only or constant.
At C:\Code\Python\env-web\Scripts\Activate.ps1:70 char:1
+ function global:prompt {
+ ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (prompt:String) [], SessionStateUnauthorizedAccessException
    + FullyQualifiedErrorId : FunctionNotWritable
@ymotongpoo
Copy link

ymotongpoo commented Jan 3, 2017

Same issue is happening here as well. Though I used venv instead of virtualenv, both tools work similarly. I think the cause of issue is located in Activate.ps1 generated by python3 -m venv command; The concrete part of the cause is (eliminated blank lines):

# Set the prompt to include the env name
# Make sure _OLD_VIRTUAL_PROMPT is global
function global:_OLD_VIRTUAL_PROMPT {""}
copy-item function:prompt function:_OLD_VIRTUAL_PROMPT
function global:prompt {
    Write-Host -NoNewline -ForegroundColor Green '(slack-cleaner) '
    _OLD_VIRTUAL_PROMPT
}

** Appendix (Just in case that dev team is not using Python)
python3 -m venv is the builtin command to generate independent development environment, and when on creating new venv environment, it generates Activate.ps1 that activates the environment.

Please find detailed description on venv here.

@Jackbennett
Copy link
Contributor

Jackbennett commented Jan 18, 2017

The last cmder added some protection from anything overwriting global:prompt because I was a little concerned about any script running to hijack it.

Fix virtualenv

If you use virtualenv set $env:VIRTUAL_ENV_DISABLE_PROMPT = 1 all it does is print your projects folder, you've already got that in the console anyway. Tested on python 3.6.

$env will do the current process. Set a user env variable or add $env:VIRTUAL_ENV_DISABLE_PROMPT = 1 to user-profile.ps1

Workaround venv

A quick test and python -m venv seems to ignore $env:VIRTUAL_ENV_DISABLE_PROMPT = 1 and it writes the prompt anyway.

So it looks like you have two options;

  1. Remove the function global:prompt from activate.ps1
  2. Comment out -options readonly from setting the prompt in cmder profile for now and it will let you clobber function:\prompt again.
  3. use virtualenv with the above fix.

I'll have to have a think how to accommodate virtualenv. Going to leave this issue open I think until an update is in the works.

@Jackbennett
Copy link
Contributor

We'll see how this python issue 29308 gets on.

@strig
Copy link

strig commented Jan 19, 2017

2017-01-18 23_09_44-cmder

I tried option 2 and my prompt was in Chinese (?), did I do something wrong?

@Jackbennett
Copy link
Contributor

Well I'm impressed. Is that with just the commented out line or what happens after you then run activate?

Will you post the results of this please; (this with print the code for prompt())
ls function:\prompt | select -expandproperty definition

@strig
Copy link

strig commented Jan 20, 2017

It happens when I open up a new powershell tab and type something. Doesn't seem to have anything to do with virtualenv. Virtualenv now activates normally, however, so it does work.

The result of that command is:

Write-Host -NoNewline -ForegroundColor Green '(venv) '
_OLD_VIRTUAL_PROMPT

@malvadeza
Copy link

Had the same problem, but I was able to fix it with just commenting the -Options ReadOnly portion only, leaving the rest how it was.
But don't know if it is the right way

@Jackbennett
Copy link
Contributor

Doh silly me, @malvadeza you are quite correct. Updated the workaround comment to make sense.

Looks like venv will get a patch to support VIRTUAL_ENV_DISABLE_PROMPT = 1 so you only need to work around till that's released.

I assuming no one is going to miss it. It's only the folder name and cmder already has that path. Unless you're using python -m venv prompt="Custom Title"

Even so, removing readonly isn't the end of the world.

@Jackbennett
Copy link
Contributor

I don't really know how python gets released but I presume this fix will get into 3.6.1
https://hg.python.org/cpython/rev/aef895fef120

So I'd recommend setting $env:VIRTUAL_ENV_DISABLE_PROMPT = 1 for the future. put that in your cmder profile if you want it to only effect cmder. Needs a nicer solution if anyone's using prompt="custom name" with venv as you'll then be missing that name prepended to the console line.

@gluons
Copy link

gluons commented Apr 21, 2018

I face the same problem.

Thanks.

I confirm that removing -Options ReadOnly from Set-Item -Path function:\prompt -Value $Prompt -Options ReadOnly.
virtualenv prompt is back.

If anyone don't know where it is, go to vendor/profile.ps1.

I just write more detail.
Hope anyone who face this issue may see my comment and found that line quickly. 🙂

@sql-sith
Copy link

sql-sith commented Feb 1, 2019

Just to share my perspective on this, that part of the prompt is not just the same folder name that I have in my prompt. It is the folder name of my Python virtual environment. Everybody knows that, but my point is that when I leave that directory to do something else, it's important to me to see a visual reminder of whatever venv I have activated. This is partly because venv doesn't announce itself when you start Python, and because that virtual env is going to be active if you start Python from anywhere. So kudos to @gluons for the clear and complete explanation and to @malvadeza who first noticed this would work!

@Jackbennett
Copy link
Contributor

I didn't know that's how venv worked, in that case maybe cmder should keep the environment variable in the path whilst set.

@sql-sith
Copy link

sql-sith commented Feb 7, 2019

It would be an easy change, and I'd personally be in favor - although removing the Options ReadOnly option from the Prompt function worked fine for me, so it's also an easy fix for us. Maybe it could be a config option?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants