> There is no greater hell than talking them through installing a working Python environment. It’s impossible.
I give a lot of Python professional trainings, and I get to do that regularly, in very diverse situations. It's indeed full of gotchas.
Since it's not going to be solved quickly, meanwhile, here is what works if you need to help people setuping python:
1 - Install Python correctly
The first version Python download link for windows is 32 bits. You want 64 bits, so you should actually not click on that. Also, make sure they use the latest minor release possible, as early ones can have weird bugs. Tell people to install from the app store if they are on windows 10, or give them a link to the proper (non web) installer.
Linux: python versions may not be available for their linux distro. Use EPEL for Centos or deadsnake for Ubunto. Other Linux users chose something exotic and must be able to deal with it.
Mac: brew is fine. Official installer too.
Cause: Python support is crazy good. It support 32 bits. 3.4 supports Windows XP. 2.7 supported Atari and Solaris! So there are a lot of installers, and a lot of versions. But also because the official Python website does a poor job at directing the user.
2 - Run Python correctly
This is the great lie of Python running. You cannot just use the "python" command, which is what every doc and tutorials tell you to do.
On linux and mac, tell them to use the suffixed PythonX.Y command, with X.Y being the version of python they need. E.G: python3.6.
On windows, tell them to use the "py -X.Y" command. E.G: py -3.6
Tell them anytime they see a tutorial with "python" in it, they should replace it mentally with "PythonX.Y" or "py -X.Y" depending of who you have in front of you.
Cause: people often ends up with have several versions of Python installed on the same machine, so you can't tell them to just use the "python" command. Of course, windows and unix never agreed an on naming convention. What's more, the Windows situation can lead to a PATH problem, and "python" may not be found, while "py" will always be. We are talking about providing the "py" command everywhere.
3 - Install tools correctly
Introduce them to pip. Tell them to never, ever install stuff using admin rights with it, even if told to by documentation or tutorials. No "sudo". No "run console as admin".
If you need to install a tool, such as black, mypy, pylint, etc., outside of a venv, use "--user" to install it for the current user. This requires no admin rights.
Also, don't use the pip command directly. Use "-m" so that you always know from which python you are installing the command for. E.G:
python3.6 -m pip install black --user # unix
py -3.6 -m pip install black --user # windows
Then mention that it's only for tools, not libs. Only install libs in venv. Some tools also should just not be installed at the system level such as jupyter or pytest because they depends on their env.
Cause: installing with admin rights can destroy your python installation. Also, pip may not be in the PATH, or be attached to the wrong version of Python. It's also because we are twisting a lib packaging tool into providing programs.
This is not specific to python. Node had to introduce a whole know command, npx, to solve the same problem, and the ones bellow. It actually takes a command name, and if it doesn't exist locally, but is registered on npm, download the package that seems to contain it, install it in a temp folder with all its deps, then immediately attempt to run it in isolation.
4 - Use tools correctly
It's another lie from docs and tutorials. If you install a tool, just calling the command may fail.
If you installed a command outside of a venv like above, then you should call it using "-m". E.G:
python3.6 -m black # or py -3.6 -m black
Cause: again, you don't know how the PATH is setup, so there is no guaranty that the command will be available, or ran from the proper python version. People can have completely messed up machines and there is nothing you can do about it. So don't depend on the PATH.
5 - Use venv correctly
The solution to all those shenanigans are the venv. Once you are in a venv, you don't need to tell the version of python, you don't need "py", "-m" or "--user". You can call commands directly. You can just use "python".
But first, people need venv installed. It's installed by default on Windows and Mac, but on linux, it's often a package to install like python3-venv, python3-pip or python3-setuptool.
Do not "pip install virtualenv": people will get confused between the tools.
So, make them create a venv: "pythonX.Y -m venv name_of_the_venv" (or py -X.Y).
Show them how to use the python/pip from the venv WITHOUT activating it, so that they understand how it works and show them the that unix have ./bin and windows ./Scripts.
Then show activation, and tell them to install pytest/jupyter and Co inside. Show them that it solves all the previous problems, so that they are motivated to use them.
Tell them to NOT put their code in the venv folder. And that they can't move or rename a venv. Show them "pip freeze > requirements.txt" + "pip install -r requirements.txt" as an alternative.
Cause: historically python didn't have the venv module, and people used to pip install virtualenv, which mean we still have docs about it, and the name stuck. Having a long history makes things complicated. And once again, the differences between Windows and Unix bites us, but that's the cost of being portable. It's not Python-specific. The fact you can't move a venv is an artefact of the venv design that the community never solved.
# Variant
People may want or need to use anaconda or the python embedded in a system (blender, qgis, etc). Then it's a whole different cycle of problems and solutions, so I won't talk about it here, this post is long enought.
Again, Python diversity is playing against it: you don't have one popular python distrib like with nodejs or cRuby. You also have commercial Python distribs, and some are used a lot in the corporate world.
Diversity make things more resilient and encourage innovation. But it makes thing harder.
# Pyproject and setup.cfg
They have nothing to do with all that. They are useful if you want to _produce_ a package to share your code with other devs.