How to list all Python versions installed in the system?
Asked Answered
M

3

9

I need to present the user a list of Python installations to choose from for executing something. I suppose in Windows I could get this information from registry. Don't know about Linux and Mac.

Any hints? Or maybe you even know a place where I could find Python code for this?

EDIT: it is not important that I find really all interpreters. Finding interpreters from standard locations would be actually fine. Agreed, it's not something too difficult, but I was just hoping that maybe someone has code for this lying around or that I've overlooked a function for that in stdlib.

Montague answered 29/1, 2014 at 14:51 Comment(10)
Operating system? Or you mean a cross-platform solution?Migratory
What exactly is your problem? There might be an easier solution to your actual problem, than to find all the installed versions.Marlomarlon
My program needs to work in Windows, Linux and MacMontague
I don't think that there is a reliable way to figure this out. As @Marlomarlon said, where is this requirement coming from?Ammadis
Just OS also does not help. For example - it is so different between the linux flavors even if Aivar says "OS is linux". On top of that in a OS like linux someone may choose to install N number of different versions compiled from tarball. Only way to do it fool-proof is traversing the whole file system and check whether each file found is a python executable (what if someone has named python executable as java!) and then query the version if it is python executable. Huh ... too much pain, not recommended to try it!Grandson
@Marlomarlon -- I'm writing a Python IDE and I want to let user to choose the interpreter for executing the program.Montague
You can definitely identify the python version on path. Ask the user to choose the python installation location if the user does not want to use the one on the path. Anything else will be too painful and not fool proof.Grandson
You could search for python executables with os.walk() but this will be very slow if you aren't clever in figuring out where to searchRootstock
Can't be done, don't bother. If you want to find a few candidates, look in environment variables, find the python 2 and 3 from which, and have a dig around in ~/.virtualenvs. A command like find / -name "python" 2> /dev/null will find files named python, which may or may not be python interpreters. Any way you do this, you are going to have to let the user specify their own, with a dialog.Cycad
@Cycad I think the first line sentence answers this better :) Because he wants a X-platform solution...Marlomarlon
M
0

Not sure this is entirely possible, but here's a dirty fix:

from subprocess import *
from time import sleep

for i in range(2, 4):
    x = Popen('python' + str(i) + ' --version', shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
    while x.poll() == None:
        sleep(0.025)
    print('Exit code of ' + str(i) + ' is:',x.poll())
    x.stdout.close()
    x.stdin.close()

The exit code will tell you if Python2 or Python3 is installed. You could add a second iterator for python versions 2.4, 2.4, 3.1, 3.2 etc etc. Or just keep them in a list, whichever you prefer for this already dirty fix.

Migratory answered 29/1, 2014 at 14:55 Comment(15)
If we are really going down that path, why not just for i in (2, 3):?Marlomarlon
Bad answer. This will fail to work because it tries to start process with python executable name "python1", "python2" etc. Obviously in an installation there is very slim chance of someone naming the python executables like that!Grandson
@Marlomarlon I am checking the exit code, the print() statement contains the x.poll() which is the exit code.Migratory
@Grandson This will not fail because each operating system contains an alias for the highest Python version when executing with Python2 and Python3, i use it every day in my scripts and it works like a clock. I just never check for exit codes because i know it is installed.Migratory
@Grandson Also, in Windows it might be different depending on your installation. If so, you could easily change this to an absolute path like C:/Python + str(i) + '/python.exe`.Migratory
The OS/OS flavor you have used happens to have those short cuts/links. But, don't rely on them being available in "each operating system" - they will not be.Grandson
@Grandson But then again, there's no way to reliably determine the installed applications that happens to be cross-platform, i sad this was a dirty fix but it will work for all operating systems except with a slight modification needed in order for it to work with Windows. But if that's the case it's an easy control with os.name or .platform.Migratory
@Migratory Very sorry ... my almost 2 decades of programming experience does not align with this statement!Grandson
This could do for Linux/Mac, thanks for the idea! What do you think, would there be any reason to make it more indirect, like running "which python3.1" instead of trying to run "python3.1"?Montague
@Grandson as if decades was a reason for good manners and code. Considering there is NO other solution to the question asked.. How do you propose we solve the issue?Migratory
@Montague The only reason for not running which python3.1 is i simply wanted it to be as cross-platform as possible, and since --version will exit the python process and not hang your application, i just went with it :) If which feels better i'd go with it!Migratory
There is no fool-proof solution to such a problem. Read my comments below the question to understand what kind of failure situations exist. If one takes all that pain it can be made fool proof. But it becomes impractical. I have also suggested a practical alternative which most of the IDEs do.Grandson
@Torxed, sure, I looked over the --version. But unfortunately Python for Windows doesn't use executables named with version numbers, seems I need to dig into Registry in Win.Montague
@Montague Or you could just iterate over C:\ if you know the users use the default installation location. Or use the dir | find combo in windows to locate each python.exe process because going into the registry will require windows specific libraries. Again, this is only if you want to keep it cross-platform, folder searches is cross platform, registry isn't :)Migratory
@Migratory My drive C: is ~150 GiB; you better not try to walk through the file system looking for possible python.exe for a stupid IDE. You will end up being deleted for eternity before you even reached the first executable.Monroe
M
4

I'm writing a Python IDE and I want to let user to choose the interpreter for executing the program.

Just do it like other IDEs then and simply supply a dialog where users can add interpreters they want to be able to run the code with.

Eclipse does this for example for Java Runtimes, and it’s perfectly fine to have it like that. Especially for languages like Python where virtual environments are an important thing which each have their own exectutable.

You certainly can come up with a one-time detection that checks some common locations. For Windows, this would obviously be the registry, as the py.exe launcher requires the interpreters to be registered there—at least the system-wide ones. On Unix machines, you could check the common bin/ folders, most prominently /usr/local/bin/ which is the standard location where Python installs itself. You could also check the PATH for Python executables. But all those things should be considered carefully and only offer an initial setup. There are always edge cases where a user didn’t do the “standard thing” where your detection will fail. For example I don’t have my Python interpreters in my path, and a linux server I access I have installed Python into a non-standard folder in my home directory. And finally, just because it looks like Python doesn’t mean it is Python.

Yes, you can do some guesswork to come up with an initial set of interpreters, but really don’t spend too much time on it. In the end, you won’t be able to detect everything perfectly anyway. And you will miss virtual environments—which might be very crucial to the project the user is working on in your IDE.

So instead of wasting time on bad detection, spend more time on creating a manual dialog to register interpreters. You will need that anyway, and a good interface can make it very easy—even for beginners—to use it.

Monroe answered 29/1, 2014 at 15:6 Comment(8)
Not entirely sure how this helps the user? :) Except that you wrote the same thing the OP did but the other way around. "Eclipse has this" and the user wrote "I want what eclipse has" (sort of). I'd assume you'd need to write some sort of example of HOW you do it in order to score points on SO, but i guess an choppy answer with examples gives you minus points while a textual representation of the problem gives you bonuses :PMigratory
@Migratory This is the solution to the XY problem posed by OP, not the answer to the question (which is how it should be done)Rootstock
@Monroe -- good point! I need to think about that. But if possible, I'd like to avoid extra configuration, because my IDE is meant for beginners.Montague
Here's the link in case someone is interested: bitbucket.org/aivarannamaa/thonnyMontague
@Migratory I fail to see where OP wrote anything like that…? Also, “how” is not really a question, is it? I said have a dialog where users can add interpreters (manually!); that’s really not hard work at all and someone who is writing an IDE will easily be able to come up with some good interface for users to register interpreters, no?Monroe
@Montague Well, for the initial start, you could try to check some standard paths (/usr/local/bin/python on Linux; registry on Windows etc) and pre-register those. But in the end, you can’t possibly detect them all. If I create a new virtual environment, that’s essentially just copy/pasting that happens. There is no way the OS will know about it, so you simply can’t detect it. So go the simple but effective way and ask the user.Monroe
Furthermore, I can make an executable which looks as much like a python interpreter as you want it to, but isn't.Cycad
@Monroe I think you're on the right track. I would default to the interpreter on the path. Then, if they want to change it, they can supply the path to the interpreter they want to use. As for determining whether it is Python, you could always invoke it and run some basic tests.Tillett
M
0

Not sure this is entirely possible, but here's a dirty fix:

from subprocess import *
from time import sleep

for i in range(2, 4):
    x = Popen('python' + str(i) + ' --version', shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
    while x.poll() == None:
        sleep(0.025)
    print('Exit code of ' + str(i) + ' is:',x.poll())
    x.stdout.close()
    x.stdin.close()

The exit code will tell you if Python2 or Python3 is installed. You could add a second iterator for python versions 2.4, 2.4, 3.1, 3.2 etc etc. Or just keep them in a list, whichever you prefer for this already dirty fix.

Migratory answered 29/1, 2014 at 14:55 Comment(15)
If we are really going down that path, why not just for i in (2, 3):?Marlomarlon
Bad answer. This will fail to work because it tries to start process with python executable name "python1", "python2" etc. Obviously in an installation there is very slim chance of someone naming the python executables like that!Grandson
@Marlomarlon I am checking the exit code, the print() statement contains the x.poll() which is the exit code.Migratory
@Grandson This will not fail because each operating system contains an alias for the highest Python version when executing with Python2 and Python3, i use it every day in my scripts and it works like a clock. I just never check for exit codes because i know it is installed.Migratory
@Grandson Also, in Windows it might be different depending on your installation. If so, you could easily change this to an absolute path like C:/Python + str(i) + '/python.exe`.Migratory
The OS/OS flavor you have used happens to have those short cuts/links. But, don't rely on them being available in "each operating system" - they will not be.Grandson
@Grandson But then again, there's no way to reliably determine the installed applications that happens to be cross-platform, i sad this was a dirty fix but it will work for all operating systems except with a slight modification needed in order for it to work with Windows. But if that's the case it's an easy control with os.name or .platform.Migratory
@Migratory Very sorry ... my almost 2 decades of programming experience does not align with this statement!Grandson
This could do for Linux/Mac, thanks for the idea! What do you think, would there be any reason to make it more indirect, like running "which python3.1" instead of trying to run "python3.1"?Montague
@Grandson as if decades was a reason for good manners and code. Considering there is NO other solution to the question asked.. How do you propose we solve the issue?Migratory
@Montague The only reason for not running which python3.1 is i simply wanted it to be as cross-platform as possible, and since --version will exit the python process and not hang your application, i just went with it :) If which feels better i'd go with it!Migratory
There is no fool-proof solution to such a problem. Read my comments below the question to understand what kind of failure situations exist. If one takes all that pain it can be made fool proof. But it becomes impractical. I have also suggested a practical alternative which most of the IDEs do.Grandson
@Torxed, sure, I looked over the --version. But unfortunately Python for Windows doesn't use executables named with version numbers, seems I need to dig into Registry in Win.Montague
@Montague Or you could just iterate over C:\ if you know the users use the default installation location. Or use the dir | find combo in windows to locate each python.exe process because going into the registry will require windows specific libraries. Again, this is only if you want to keep it cross-platform, folder searches is cross platform, registry isn't :)Migratory
@Migratory My drive C: is ~150 GiB; you better not try to walk through the file system looking for possible python.exe for a stupid IDE. You will end up being deleted for eternity before you even reached the first executable.Monroe
H
0

I suggest that you look for all occurances of python.exe.
To do that in Windows, open a command window (WIN+R, enter cmd.exe and press return), then type:

dir c:\python.exe /s | find "Directory"

Directory of c:\Python310
Directory of c:\Python310\Lib\venv\scripts\nt
Directory of c:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.3.1.12.Python.win-x64\7.0.9\tools
Directory of c:\Program Files\dotnet\packs\Microsoft.NET.Runtime.Emscripten.3.1.12.Python.win-x64\7.0.9\tools\Lib\venv\scripts\nt
Directory of c:\Program Files\PostgreSQL\15\pgAdmin 4\python
...

The command will run for a while. You can see you will find it in many places, even where you didn't expect.

Holloway answered 31/8, 2023 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.