[Python-Dev] PEP 370 - per-user scripts directory on Windows

Steve Dower Steve.Dower at microsoft.com
Tue Feb 10 18:45:49 CET 2015


So I've enumerated the problems with PATH on Windows before (and my subsequent dislike for modifying it through the installer), but here's the dot-point summary for those who haven't seen it.

* System-wide values always precede per-user values
* Most-recently-installed values always precede existing values (within the system/user separation above)
* It's impossible to specify per-user values from a system-wide installer
* The system-wide value has a length limit that silently breaks PATH if you exceed it
* It's difficult for users to modify PATH themselves (mostly due to bad UI in Windows)

The py.exe launcher solves many of these problems, but does not help with installed scripts. It's trivially easy to end up in a place where this would fail:

    pip install --user spam
    spam

The *only* case where this will work reliably (without manual user configuration) is where Python 3.5 is the only installed version on the machine, and it was installed by the current user just for them.

As we've seen from earlier discussions, the main beneficiaries of having Python on PATH are those using the command-line. Most scripts are going to make assumptions or work unnecessarily hard to find the actual location of the Python version they need.

My best idea for dealing with this is to add another script alongside the py.exe launcher called `activate-py`.[1] This script would take the same command-line version argument as py.exe and use it to update the current prompt's PATH correctly. Specifically, I expect the script would actually use py.exe to invoke the requested Python and get the paths directly from sysconfig, which will ensure that the order of precedence always matches.

Users would need to run `activate-py`, `activate-py -2` or `activate-py -3.5` (etc.) when they start their session.[2] This parallels venv's `activate` command, though because this would be a global command I believe the `-py` suffix is necessary. The example above becomes:

    activate-py -3.5
    pip install --user spam
    spam

A `deactivate-py` command would also be added to revert the changes, though I don't expect that to be part of most workflows.

Another benefit is that shell scripts could call `activate-py` rather than trying to detect whether Python is already on the path or requiring a PYTHON variable to be set. (I seem to write these scripts all the time and know that I'd benefit from it.)

This is yet another attempt to try and change user behaviour, which I'm not thrilled about, but I'm really starting to feel that this is the best way out of a bad situation. It differs from the solutions used on Linux, though there may be some value in this approach there too. Thought/votes/suggestions?

Cheers,
Steve


[1]: Actually multiple scripts to handle cmd.exe/PowerShell, but this is an implementation detail. Users would simply type `activate-py` and the shells know which one to use.

[2]: We can easily add Start Menu shortcuts (e.g. "Python 3.5 (32-bit) Command Prompt") and run it for them, though that is not a critical part of this proposal.


More information about the Python-Dev mailing list