Cmder: Virtualenv in Powershell cannot be activated

Created on 23 Dec 2016  路  13Comments  路  Source: cmderdev/cmder

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
PowerShell In Progress 馃摉 Needs Documentation

Most helpful comment

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. 馃檪

All 13 comments

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.

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.

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

2017-01-18 23_09_44-cmder

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

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

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

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

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.

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.

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. 馃檪

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!

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

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?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Joe1992w picture Joe1992w  路  3Comments

brunowego picture brunowego  路  3Comments

GlassGruber picture GlassGruber  路  3Comments

luisrudge picture luisrudge  路  3Comments

jordanrobinson picture jordanrobinson  路  3Comments