python / cpython

The Python programming language
https://www.python.org
Other
61.99k stars 29.81k forks source link

venv: activate.bat fails for venv with special characters in PATH #88706

Open 36062553-c025-46c9-8c38-18df84134152 opened 3 years ago

36062553-c025-46c9-8c38-18df84134152 commented 3 years ago
BPO 44540
Nosy @pfmoore, @tjguk, @zware, @eryksun, @zooba
Files
  • activate.bat
  • deactivate.bat
  • 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: ```python assignee = None closed_at = None created_at = labels = ['type-bug', '3.9', '3.10', '3.11', 'library', 'OS-windows'] title = 'venv: activate.bat fails for venv with special characters in PATH' updated_at = user = 'https://bugs.python.org/MB113' ``` bugs.python.org fields: ```python activity = actor = 'eryksun' assignee = 'none' closed = False closed_date = None closer = None components = ['Library (Lib)', 'Windows'] creation = creator = 'MB113' dependencies = [] files = ['50483', '50484'] hgrepos = [] issue_num = 44540 keywords = [] message_count = 2.0 messages = ['396776', '408073'] nosy_count = 6.0 nosy_names = ['paul.moore', 'tim.golden', 'zach.ware', 'eryksun', 'steve.dower', 'MB113'] pr_nums = [] priority = 'normal' resolution = None stage = 'needs patch' status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue44540' versions = ['Python 3.9', 'Python 3.10', 'Python 3.11'] ```

    36062553-c025-46c9-8c38-18df84134152 commented 3 years ago

    If your virtual env Scripts folder is in a path with a special character (for batch-scripts) it will give this error:

    The system cannot find the path specified.

    In my case it was a '&' in my path.

    Now I see that the fix from specifically this issue: https://bugs.python.org/issue36634 has caused my problems.

    So in the end neither works. set "VIRTUAL_ENV=VENV_DIR__" doesn't work with quotes set VIRTUAL_ENV=VENV_DIR__ doesn't work with 'special chars' (&*)

    eryksun commented 2 years ago

    There's no parsing problem with delayed expansion (e.g. "!VAR!" instead of %VAR%) and for loop variables (e.g. "%%a"). The solution is thus to execute in a local scope that enables delayed expansion and command extensions [1].

    That's easy enough, but then there's the problem of how to evaluate the set commands in the global scope, without the help of delayed expansion to prevent parsing errors. I did some research, and apparently the common trick is to end the local scope inside of a for /f loop. Then subsequent set "%%a" statements in iterations of the loop execute in the global scope.

    The final problem is building the command to execute in the local scope, for which the for /f loop iterates the output lines. set var returns a line with "var=value", which can be passed back into set "%%a". So I decided to build up a sequence of & concatenated set var and echo var= (clear) statements in an EXPORTS variable.

    I added default values for PROMPT ($P$G) and PATH (%SystemRoot%;%SystemRoot%\System32), for when they're not defined. I made sure that deactivate.bat does not leave these defaults in place. The original values, whether defined or not, should be restored exactly as they were.

    All of this adds to the length of the scripts. They're roughly doubled in size. But there should be no more problems with an odd number of quotes and/or special characters in any of the variables that get set.

    --- [1] The activate.bat and deactivate.bat scripts have been naively relying on the default enabled state of command extensions, e.g. for /f loops and if defined statements.

    eryksun commented 1 year ago

    Note issue #96894 in regards to the global use of echo off. Here is an archive that contains versions of "activate.bat" and "deactivate.bat" that do not use echo off.