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

The activate script in Windows is not correct for venvs created in git-bash #82764

Closed
Mo mannequin opened this issue Oct 24, 2019 · 9 comments
Closed

The activate script in Windows is not correct for venvs created in git-bash #82764

Mo mannequin opened this issue Oct 24, 2019 · 9 comments
Labels
OS-windows pending The issue will be closed if no feedback is provided type-bug An unexpected behavior, bug, or error

Comments

@Mo
Copy link
Mannequin

Mo mannequin commented Oct 24, 2019

BPO 38583
Nosy @pfmoore, @tjguk, @zware, @zooba, @mikofski

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:

assignee = None
closed_at = None
created_at = <Date 2019-10-24.14:32:03.287>
labels = ['type-bug', '3.9', 'OS-windows']
title = 'The activate script in Windows is not correct for venvs created in git-bash'
updated_at = <Date 2020-04-15.05:32:32.233>
user = 'https://bugs.python.org/Mo'

bugs.python.org fields:

activity = <Date 2020-04-15.05:32:32.233>
actor = 'bwanamarko'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Windows']
creation = <Date 2019-10-24.14:32:03.287>
creator = 'Mo'
dependencies = []
files = []
hgrepos = []
issue_num = 38583
keywords = []
message_count = 5.0
messages = ['355333', '355356', '355382', '356146', '366488']
nosy_count = 6.0
nosy_names = ['paul.moore', 'tim.golden', 'zach.ware', 'steve.dower', 'bwanamarko', 'Mo']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue38583'
versions = ['Python 3.9']

@Mo
Copy link
Mannequin Author

Mo mannequin commented Oct 24, 2019

When creating a virtual environment on Windows from git-bash (using python -m venv), VIRTUAL_ENV in the activate script is set using a windows style path (C:\some\path) instead of the bash style (/c/some/path).

This means the system python and pip get used, despite the user thinking they are working in a venv after sourcing activate.

As activate is a bash script, the paths in it should always be in the bash style, regardless of platform.

This is described in a stack overflow issue here: https://stackoverflow.com/questions/57758841/windows-virtualenv-created-via-gitbash-using-system-python

I have confirmed the behaviour in 3.7.3, 3.7.4, 3.7.5 and 3.8.0.

@Mo Mo mannequin added 3.7 (EOL) end of life 3.8 (EOL) end of life OS-windows type-bug An unexpected behavior, bug, or error labels Oct 24, 2019
@Mo
Copy link
Mannequin Author

Mo mannequin commented Oct 25, 2019

The issue comes as a result of abspath on line 59 of venv/init.py:
env_dir = os.path.abspath(env_dir)

This returns a Windows-style path, and os.path.abspath returning in this way is *probably* correct, as the OS is Windows, despite trying to forget that by using bash.

It is still my view that the activate script is a bash script, and therefore should only contain paths in that style, but the simple solution to this issue is to change the double quotes around the definition of $VIRTUAL_ENV in the activate script to single quotes. It works. The output of "which python" is a bit odd, but this is clearly a quirk beyond Python's control.

@zooba
Copy link
Member

zooba commented Oct 25, 2019

I agree this would be better, though it may not be that easy to do.

If you're running Windows Python from WSL, then your "bash style" path should be "/mnt/c/some/path", not "/c/some/path". So the answer isn't as simple as .replace('\\', '/').

I did some quick testing with posixpath and pathlib and neither has an obvious conversion from a Windows path to a POSIX path, though pathlib.PurePosixPath(pathlib.PureWindowsPath(p)) comes closest.

Perhaps the best approach here is to improve activate to determine its path when run, like we did for activate.ps1? Then we don't need to substitute the path in at creation time.

@zooba zooba added 3.9 only security fixes and removed 3.7 (EOL) end of life 3.8 (EOL) end of life labels Oct 25, 2019
@Mo
Copy link
Mannequin Author

Mo mannequin commented Nov 6, 2019

I had also tested with pathlib and posixpath and come to the same conclusion.

As suggested by you, I looked into activate determining path when run. I believe this should do the trick (My bashfoo isn't strong, this is mostly from https://stackoverflow.com/a/179231):

pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}"
if ([ -h "${SCRIPT_PATH}" ]); then
  while([ -h "${SCRIPT_PATH}" ]); do cd `dirname "$SCRIPT_PATH"`; 
  SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
cd .. > /dev/null
SCRIPT_PATH=`pwd`;
popd  > /dev/null

VIRTUAL_ENV="$SCRIPT_PATH"

@mikofski
Copy link
Mannequin

mikofski mannequin commented Apr 15, 2020

Would you consider just handling activate for windows directly in the lib/venv/init.py method "install_scripts(self, context, path)"

data = self.replace_variables(data, context)

    if not srcfile.endswith(('.exe', '.pdb')):

        # handle activate for Windows (ignore WSL)
        if srcfile == "activate":
            # from docs: on unix drive is always empty
            d, p = os.path.splitdrive(context.env_dir)
            d = d.replace(':', '')
            p = p.replace('\\', '/')
            if d:
                p = '/' + d + p
            data = data.decode('utf-8')
            data = data.replace('__VENV_DIR__', p)
            data = data.encode('utf-8')
    try:
        data = data.decode('utf-8')
        data = self.replace_variables(data, context)
        data = data.encode('utf-8')
    except UnicodeError as e:

IMHO I don't think the use of windows python in WSL is a realistic use-case, my preference would be to just make this fail. In fact I tried to use it, and I could not make it work.

  1. /mnt/c/path/to/python -m venv venv
    Error: [WinError 5] Access is denied: 'C:\WINDOWS\system32\venv'
  2. /mnt/c/path/to/python -m venv -m venv /mnt/c/some/path/to/venv
    fails silently, appears to do nothing, venv is not created
  3. /mnt/c/path/to/python -m venv -m venv 'C:/some/path/to/venv'
    makes directories at C:\some\path\to\venv, but can't be activated in WSL, that I can figure out
    source /mnt/c/some/path/to/venv/Scripts/activate
    : command not found
    -bash: /mnt/c/some/path/to/venv/Scripts/activate: line 4: syntax error near unexpected token $'{\r'' 'bash: /mnt/c/some/path/to/venv/Scripts/activate: line 4: deactivate () {

I guess I don't really understand why it would be useful to use the windows python in WSL, and if that's the only thing holding a quick fix for this, I guess, I would prefer to just handle windows python in windows in git-bash, and ignore WSL. Would you be open to that?

If so, I'm happy to submit a PR

thanks!

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@avoidik
Copy link

avoidik commented Nov 11, 2022

probably this is the only option

VIRTUAL_ENV='C:\Users\xyz\Projects\abc\.venvwin'
if ([ "$OSTYPE" = "cygwin" ] || [ "$OSTYPE" = "msys" ]) && $(command -v cygpath &> /dev/null) ; then
    VIRTUAL_ENV=$(cygpath -u "$VIRTUAL_ENV")
fi
export VIRTUAL_ENV

@daytonb
Copy link

daytonb commented Apr 21, 2023

I was looking into a different issue with activate script from Windows' Python in a cygwin terminal and came across this Github issue. I have 3 pieces of feedback on this issue.

  1. I tested the Windows Python 3.11 venv activate script from a git-bash terminal. Even though the output of which python is very strange (/c/Users/daytonb/Desktop/junk/\Users\daytonb\Desktop\junk\venv/Scripts/python), the pip and python executables you get are the ones in the virtual environment. We can, therefore, probably close this issue with no code changes.

  2. If we do want to address the contents of the environment variable and strange output of which python, then we could use the solution proposed by @avoidik above. It is precisely what's in the activate script written by virtualenv. I've confirmed that on my Win10 system, that works for activating a virtual environment in a git-bash terminal. If we merge that into Python's venv activate code, we could close this issue.

  3. Finally, I concur with @mikofski's comment above, that we don't need to worry about being able to use the Windows' Python virtual environments from within a WSL terminal. I don't think WSL has any bearing on closing this issue.

@zware
Copy link
Member

zware commented Apr 21, 2023

I'm pretty sure point 2 was addressed very recently in ebc8103 (GH-103325, gh-103088), can you confirm?

@zware zware added pending The issue will be closed if no feedback is provided and removed 3.9 only security fixes labels Apr 21, 2023
@daytonb
Copy link

daytonb commented Apr 24, 2023

Indeed! That code change addresses my point 2. I think we can close this issue.

@zooba zooba closed this as completed Apr 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OS-windows pending The issue will be closed if no feedback is provided type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants