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

bpo-35003: bin/activate should always be present #18083

Closed
wants to merge 2 commits into from

Conversation

earonesty
Copy link

@earonesty earonesty commented Jan 20, 2020

Ensures that the common bin/activate, used by shell scripts on all platforms, is always present on all platforms.

Possibly this should be an option, but that seems like overkill.

https://bugs.python.org/issue35003

@earonesty earonesty marked this pull request as ready for review January 20, 2020 22:28
@vsajip
Copy link
Member

vsajip commented Jan 21, 2020

The Scripts/bin thing is not specific to venv - for whatever reason, the original Windows implementation chose to use "Scripts" rather than "bin" for the executables directory under Windows, and I don't think it can be changed now without affecting backward compatibility. The venv code just fits into the existing, wider theme. My guess is you would need to propose a PEP to move everything over from "Scripts" to "bin" in the Windows Python world, and show that it would not break any existing code anywhere - seems like a tall order.

This issue was already rejected before you added your PR so I'm not sure why you went to the trouble of creating a PR. Thanks for trying to help, but I think this PR should be closed for the above reasons.

@gaborbernat
Copy link
Contributor

IMHO we should not copy, that would just be confusing. If anything we should make the bin folder a junction for the Scripts.

@earonesty
Copy link
Author

earonesty commented Jan 22, 2020

I don't think we don't want to junction "all" the files, only those that are bash-shell-related... otherwise we'd have to change the PEP and we're back to all the reasons why it was rejected in the first place.

A soft-link (if available) to bin/activate is OS-neutral, and allows the existing documentation to be factually correct (right now some documentation assumes bin/activate is available for bash..., which it isn't.)

Plus, junctions are not always available on all systems, although that's not my primary concern.

The primary issue is the thousands of developers around the world using bash in CI that have had to solve this rather absurd problem in thousands of different ways (if os == nt, if -e Scripts/ if uname == Linux, embedded in make files, embedded in bash scripts. I've seen them all.

The rest of Scripts/ belongs where it is.

@pfmoore
Copy link
Member

pfmoore commented Jan 22, 2020

The primary issue is the thousands of developers around the world using bash in CI that have had to solve this rather absurd problem in thousands of different ways

IMO, It's a platform difference. If you're developing on both Windows and Unix, you need to be aware of platform differences (even if you try to use some sort of Unix-lookalike that provides bash, it still can't hide the fact that you're not on Unix totally) and Scripts vs bin is just one of many such differences.

Yes, it's an absurd and annoying difference, but the reasons it exists are historical, and changing it now is (as @vsajip said) likely to be way too big an exercise. Patching over just one part of the problem may help some specific cases, but overall will be more confusing, not less. (Why is activate in bin, but not, for example, pip.exe? Why does activate add Scripts to PATH rather than bin?)

@gaborbernat
Copy link
Contributor

Plus, junctions are not always available on all systems, although that's not my primary concern.

I thought we only target here Windows, that always has junctions.

A soft-link (if available) to bin/activate is OS-neutral,

Soft links don't work always on Windows so that can't be.

right now some documentation assumes bin/activate is available for bash

Sounds to me like a bad assumption, and should be fixed in the documentation.

The only way I can see for us to improve on this is to generate the bin, but that mirrors and is always whatever Script is (aka Windows NTFS junction).

@vsajip
Copy link
Member

vsajip commented Jan 23, 2020

I'm closing this, as having things in bin on Windows could be confusing and is counter to normal practice for Python on Windows. If there are gaps in the documentation (e.g. references to bin without mentioning that Scripts is used on Windows) they can be addressed there.

@vsajip vsajip closed this Jan 23, 2020
@earonesty
Copy link
Author

it is not a "platform difference", the platform in this case is bash, which is available on windows

@vsajip
Copy link
Member

vsajip commented Mar 4, 2020

which is available on windows

Not in general. Python uses Scripts on WIndows, and bin on POSIX. That has been the convention since Python has been on Windows, AFAIK.

@anton-danielsson
Copy link

Could we please revisit this?
Having "bin/activate" would makes things much easier for generic bash scripts running on both Windows and Linux/POSIX.
Note that "Scripts/activate" will also be there.

@vsajip
Copy link
Member

vsajip commented Sep 1, 2021

Could we please revisit this?

Nothing has changed since the original analysis of this. bash is available on Windows only in limited scenarios. It's not clear that better documentation couldn't resolve any confusion. Python on Windows has not abandoned the Scripts folder in favour of bin.

@anton-danielsson
Copy link

But I don't understand we can't create both Scripts/activate and bin/activate?
I think the preferred way would be to just create a copy of it, why muck around with junctions/symlinks to save 3KB?
An alternative to a copy would be something like:

bin/activate:

# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly

scriptdir=`dirname "$BASH_SOURCE"`

. $scriptdir/../Scripts/activate

@vsajip
Copy link
Member

vsajip commented Sep 6, 2021

Like it or not, the convention is to use Scripts on Windows, bin on POSIX. Most people seem to have managed with this convention just fine, so there seems no need to muddy the water. From the Zen of Python:

Special cases aren't special enough to break the rules.

@anton-danielsson
Copy link

I guess you can argue if running bash (msys/git-bash/whatever) on Windows is POSIX or Windows ;)
I still haven't heard any argument why simply coping and having both Scripts/activate and bin/activate would not be a good solution?

Just so the original problem statement is understood, read the original post in: pypa/virtualenv#1418
I experience the same issue as the original author.
We have CI runners that run on Windows, Linux and MacOS.
At the top level we have bash scripts (they run on all platforms).
The only special nasty logic we need is that Windows has to source the virtual env differently. It's really annoying.

Sorry for being so persistent, I just think it's silly to not make this small and simple fix.

@pombredanne
Copy link
Contributor

I would like to challenge the status quo and kindly ask that we revisit this issue. I opened pypa/virtualenv#2404 to this effect.

A previous pypa/virtualenv#1418 was closed after the issue was closed here.

@pombredanne
Copy link
Contributor

One of the key issue is CI automation where Windows needs to be special cased making this a PITA.

@vsajip I would return your quote from the Zen of Python ;) :

Special cases aren't special enough to break the rules.

Therefore I see no reason to make a special case for Windows.

@vsajip
Copy link
Member

vsajip commented Aug 16, 2022

Look, it wasn't my original decision, and Scripts is used by default for Python on Windows (independently of how venv works).

C:\Users\Vinay>dir AppData\Local\Programs\Python\Python39\"
 Volume in drive C is Windows
 Volume Serial Number is F4E1-7AFC

 Directory of C:\Users\Vinay\AppData\Local\Programs\Python\Python39

09/04/2021  07:14    <DIR>          .
09/04/2021  07:14    <DIR>          ..
09/04/2021  07:13    <DIR>          DLLs
09/04/2021  07:13    <DIR>          include
09/04/2021  07:13    <DIR>          Lib
09/04/2021  07:13    <DIR>          libs
06/04/2021  14:14            32,628 LICENSE.txt
06/04/2021  14:15         1,054,193 NEWS.txt
06/04/2021  14:14           101,552 python.exe
06/04/2021  14:14            59,568 python3.dll
06/04/2021  14:14         4,459,696 python39.dll
06/04/2021  14:14           100,016 pythonw.exe
04/05/2021  19:31    <DIR>          Scripts
09/04/2021  07:13    <DIR>          Tools
06/04/2021  14:14            96,144 vcruntime140.dll
06/04/2021  14:14            36,752 vcruntime140_1.dll
               8 File(s)      5,940,549 bytes
               8 Dir(s)  63,443,410,944 bytes free

@pfmoore
Copy link
Member

pfmoore commented Aug 16, 2022

Agreed. Changing this would have far more implications than being a simple change to venv/virtualenv. Like it or not, code that special cases the layouts for Windows vs Unix is widespread, and changing the layout would cause significant disruption. It's not impossible, but the benefits would have to be equally significant at this point.

If you want to address this, the best way would probably be to start with introducing APIs somewhere that "hide" the difference, so that things like the CI automation you mention can be written in a platform agnostic way. We can then promote those APIs and hope that over time, existing code will migrate to them. Once sufficient time has passed, we could change the scheme and tell any remaining users hard coding the locations to use the APIs. Of course, at this point, the main justification for changing the scheme has beel lost, as the APIs enable platform-agnostic code anyway 🙂

Also, if you want to proceed with this, remember to consider what tools like pip and installer need to do in order to follow the new convention. And if you're proposing symlinks between Scripts and bin, consider what tools should do if symlinks aren't available (either because the filesystem doesn't support them, or the OS doesn't have them enabled). And how should tools that manage environments detect what convention to use "from the outside" (not all tools are written to use the Python interpreter from a given environment)?

I completely agree that having different layouts is an annoying wart. But I think you're hugely underestimating the amount of work to change things at this point.

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

Successfully merging this pull request may close these issues.

8 participants