Python shutil.which not working with wsl.exe - python

I am trying to use shutil.which to check if the Linux Subsystem is installed on Windows 10.
Using the Windows where command in Command Prompt, I can see the location of the wsl.exe executable.
C:\Users\spike>where wsl
C:\Windows\System32\wsl.exe
The above shows that WSL does exist, and is in my system PATH.
When I use the which function in Python, it says that the executable was not found.
print(which("wsl")) # Returns None
Just to make sure that which works, I test it on cmd.exe.
print(which("cmd")) # Returns "C:\Windows\System32\cmd.exe"
That works. Well, what if I make a system shell call with the command that did work?
print(system("where wsl")) # Returns 1
Exit code 1, the command wsl was not found.
So I test it on cmd.exe again.
print(system("where cmd")) # Returns 0
Okay, so that does work. What is the problem?
For each Python 3 example assume these imports.
from shutil import which
from os import system
Why can Python not find wsl.exe even though it is proven to exist?
Thanks.

Credit to #eryksun, who helped solve this in the comments.
The issue is that I am using 32 bit Python, and wsl.exe is only in C:/Windows/System32. The problem with this is that Python is looking in C:/Windows/SysWOW64 for the executable instead.
wsl.exe is only 64-bit, and you're looking in SysWOW64 instead of the real System32 because you're using 32-bit Python. – eryksun
Because WSL only supports 64-bit systems, I ended up just running my code with 64-bit Python. However, and alternate solution if you only use Py32 would be to access SysWOW64 directly, using the system root environment variable and os.path.join.
In Windows 7+, the real System32 directory is accessible in a 32-bit process as "SysNative". Unfortunately this virtual directory isn't available in a native 64-bit process, so you need to first check whether it exists. For example: sysnative = os.path.join(os.environ['SystemRoot'], 'SysNative'); if os.path.exists(sysnative): .... – eryksun

Now you can install python in 64 bit and everything will work just fine. (Be careful that when the python installer runs, there should be written 64 bit packages and other things as 64 bits [right where the loading bar is])

Related

How do i know if a script is to be run with Python 2 or Python 3 [duplicate]

How do I, in the main.py module (presumably), tell Python which interpreter to use? What I mean is: if I want a particular script to use version 3 of Python to interpret the entire program, how do I do that?
Bonus: How would this affect a virtualenv? Am I right in thinking that if I create a virtualenv for my program and then tell it to use a different version of Python, then I may encounter some conflicts?
You can add a shebang line the to the top of the script:
#!/usr/bin/env python2.7
But that will only work when executing as ./my_program.py.
If you execute as python my_program.py, then the whatever Python version that which python returns will be used.
In re: to virtualenv use: virtualenv -p /usr/bin/python3.2 or whatever to set it up to use that Python executable.
Perhaps not exactly what you asked, but I find this to be useful to put at the start of my programs:
import sys
if sys.version_info[0] < 3:
raise Exception("Python 3 or a more recent version is required.")
I would use the shebang #!/usr/bin/python (first line of code) with the serial number of Python at the end
Then run the Python file as a script, e.g., ./main.py from the command line, rather than python main.py.
It is the same when you want to run Python from a Linux command line.
While the OP may be working on a nix platform this answer could help non-nix platforms. I have not experienced the shebang approach work in Microsoft Windows.
Rephrased: The shebang line answers your question of "within my script" but I believe only for Unix-like platforms. Even though it is the Unix shell, outside the script, that actually interprets the shebang line to determine which version of Python interpreter to call. I am not sure, but I believe that solution does not solve the problem for Microsoft Windows platform users.
In the Microsoft Windows world, the simplify the way to run a specific Python version, without environment variables setup specifically for each specific version of Python installed, is just by prefixing the python.exe with the path you want to run it from, such as C:\Python25\python.exe mymodule.py or D:\Python27\python.exe mymodule.py
However you would need to consider the PYTHONPATH and other PYTHON... environment variables that would point to the wrong version of Python libraries.
For example, you might run:
C:\Python2.5.2\python.exe mymodule
Yet, the environment variables may point to the wrong version as such:
PYTHONPATH = D:\Python27
PYTHONLIB = D:\Python27\lib
Loads of horrible fun!
So a non-virtualenv way, in Windows, would be to use a batch file that sets up the environment and calls a specific Python executable via prefixing the python.exe with the path it resides in. This way has additional details you'll have to manage though; such as using command line arguments for either of the "start" or "cmd.exe" command to "save and replace the "console" environment" if you want the console to stick around after the application exits.
Your question leads me to believe you have several Python modules, each expecting a certain version of Python. This might be solvable "within" the script by having a launching module which uses the subprocess module. Instead of calling mymodule.py you would call a module that calls your module; perhaps launch_mymodule.py
launch_mymodule.py
import sys
import subprocess
if sys.argv[2] == '272':
env272 = {
'PYTHONPATH': 'blabla',
'PYTHONLIB': 'blabla', }
launch272 = subprocess.Popen('D:\\Python272\\python.exe mymodule.py', env=env272)
if sys.argv[1] == '252'
env252 = {
'PYTHONPATH': 'blabla',
'PYTHONLIB': 'blabla', }
launch252 = subprocess.Popen('C:\\Python252\\python.exe mymodule.py', env=env252)
I have not tested this.
You can't do this within the Python program, because the shell decides which version to use if you a shebang line.
If you aren't using a shell with a shebang line and just type python myprogram.py it uses the default version unless you decide specifically which Python version when you type pythonXXX myprogram.py which version to use.
Once your Python program is running you have already decided which Python executable to use to get the program running.
virtualenv is for segregating python versions and environments, it specifically exists to eliminate conflicts.
For those using pyenv to control their virtual environments, I have found this to work in a script:
#!/home/<user>/.pyenv/versions/<virt_name>/bin/python
DO_STUFF
I had this problem and just decided to rename one of the programs from python.exe to python2.7.exe. Now I can specify on command prompt which program to run easily without introducing any scripts or changing environmental paths.
So i have two programs: python2.7 and python (the latter which is v.3.8 aka default).
While working with different versions of Python on Windows,
I am using this method to switch between versions.
I think it is better than messing with shebangs and virtualenvs
install python versions you desire
go to Environment Variables > PATH
(I assume that paths of python versions are already added to Env.Vars.>PATH)
suppress the paths of all python versions you dont want to use
(don't delete the paths, just add a suffix like "_sup")
call python from terminal
(so Windows will skip the wrong paths you changed,
and will find the python.exe at the path you did not suppressed,
and will use this version after on)
switch between versions by playing with suffixes

Eclipse running 64-bit Python, rather than 32-bit

I am running OS X Lion, Python 2.7, and I am trying to setup Pygame to work with PyDev in Eclipse. I set up PyDev to use a custom-installed Python (not the default one). I forced this install to use 32-bit, which works fine in the Terminal - I can import Pygame, and other modules. However, when I use it in PyDev, it gives me a no matching architecture error. It also appears to be running in 64-bit mode.
The paths to the interpreter are the same.
import sys
print ("%x" % sys.maxsize, sys.maxsize > 2**32)
prints out ('7fffffff', False) while using Terminal, but in Eclipse/PyDev it prints out ('7fffffffffffffff', True)
The two paths (using sys.executable) are:
In Terminal it is:
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
And in Eclipse it is
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
The path to the interpreter I used is: /Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
I also tried manually specifying the interpreter in Terminal - Using the above path. It worked.
The default python that comes with the system is /usr/bin/python
I am using a 32-bit version of Eclipse classic as shown by an answer to this question.
Does anyone have any idea what is wrong?
You need to instruct eclipse to use 32-bit python.
Right-click on your project -> properties -> PyDen/Interpreter grammar and select "Click here to configure an interpreter not listed"
After you add your new python binary (e.g. C:\Python27\python.exe), you go back to the interpreter menu in the properties window and you select this interpreter from the corresponding drop-down menu.
I solved this by using a method describe in an answer to another question.
The answer said to go to your plugins/org.python.pydev/pysrc and open interpreterInfo.py. Then you replace all the instances of sys.executable with the path to the interpreter you want.
In my case, this meant changing them to /Library/Frameworks/Python.framework/Version/2.7/bin/python2.7
After that, open up eclipse and create a new interpreter with the same path, and it should work.

How to install python 3.2.3 on Windows 7 enterprise

although I have been using python a long time very easily in a Linux environment, I have tremendous trouble to even install it correctly in a windows environment. I hope this is a question to be asked here, as it is not directly a programming question.
Especially, I have the following problems:
When on the command line, python is not a recognized command. Do I have to set the Windows path manually myself? If so, how to do that?
When starting a python script, should this be done with python.exe or pythonw.exe? What is the difference?
I also tried to install ipython several times, it never got installed (even after following the starting ipythonenter link description here thread.
When starting a script with python.exe, a window pops up and closes immediately. I saw some hints in putting in a readline command, which is of no help if there is a syntax error in the script. So how to be able to keep the window open, or how to run the command on the cmd.exe?
Thank you for any help on these items.
Alex
1) Look here: www.computerhope.com/issues/ch000549.htm
2) It has already been answered, always try to use search before asking question:
pythonw.exe or python.exe?
4) When using cmd.exe just navigate to your script folder using dir for changing directories and C:,D:,etc. for changing drives. Then run script by typing just the script name. When installed correctly, Python automatically launches .py scripts with python, so you don't have to write 'python' before script name. When run in cmd, window will stay open. If you want it to stay open even when launching script with double-click, use function waiting for user input, see here How to keep a Python script output window open?
You might want to use Python3.3, there is a new launcher for Python scripts in it. By that, you can start Python scripts with py <scriptname> which has the benefit of being installed in your path (C:\Windows\system32) and you can use a shebang to tell whether the script is for Python2 or Python3.
Also
In addition to the launcher, the Windows installer now includes an
option to add the newly installed Python to the system PATH
(contributed by Brian Curtin in issue 3561).

Eclipse / PyDev overrides #sys, cannot find Python 64bits interpreter

I'm working in a multiuser environment with the following setup:
Linux 64bits environment (users can login in to different servers).
Eclipse (IBM Eclipse RSA-RTE) 32bits. So Java VM, Eclipse and PyDev is 32bits.
Python 3 interpreter is only available for 64bits at this moment.
In the preferences for PyDev, I want to set the path to the Python interpreter like this:
/app/python/#sys/3.2.2/bin/python
In Eclipse/PyDev, #sys points to i386_linux26 even if the system actually is amd64_linux26. So if I do not explicitly write amd64_linux26 instead of #sys, PyDev will not be able to find the Python 3 interpreter which is only available for 64bits. The link works as expected outside Eclipse/PyDev, e.g. in the terminal.
Any ideas how to force Eclipse/PyDev to use the real value of #sys?
Thanks in advance!
I don't really think there's anything that can be done on the PyDev side... it seems #sys is resolved based on the kind of process you're running (not your system), so, if you use a 64 bit vm (I think) it should work...
Other than that, you may have to provide the actual path instead of using #sys...

Cross-platform way to specify Python interpreter when running with execv

I am currently running a Python scripts both on Linux and Windows 7. The file is executed in an execv style with which I mean that the interpreter is defined in the beginning of the file in a command.
In Windows system, the interpreter specification is:
#!C:\Python26\python.exe
However in Linux this needs to be
#!/usr/bin/python
I would like to run this script in both systems without having to change this line again and again.
I have tried out the following:
#!C:\Python26\python.exe
#!/usr/bin/python
as well as:
#!C:\Python26\python.exe;/usr/bin/python
So: is there any way I could specify multiple interpreters?
Depending on what you're trying to do, this might be a bit heavy-weight, but 0install can run your program will the appropriate Python interpreter for your platform. In your program's XML description, do something like this (e.g. if you want Python >= 2.6, < 3):
<command name="run" path="myprog.py">
<runner interface="http://repo.roscidus.com/python/python">
<version not-before="2.6" before="3"/>
</runner>
</command>
See: http://www.0install.net/local-feeds.html
This will also make 0install download a suitable version of Python if the user doesn't have it already.
Note that you may want to do this even if you're only targetting Linux, because with Python 3 there is no single #! line that works on all platforms (some platforms, e.g. Arch, require "python2" not "python", while others, e.g. Debian, don't provide "python2", only "python").
#!/usr/bin/env python
That will call the env program to search your PATH for a Python executable.
If you need to ensure a specific version of Python you can do e.g.:
#!/usr/bin/env python3.11
Is there any way I could specify multiple interpreters ?
You don't need to. On Windows (at least as long as you don't have CygWin or similar installed), the Shebang line is treated as a normal Python comment; that means, it is ignored. Windows knows that it should run .py and .pyw files with the Python interpreter, because it is told that upon installation of Python.

Categories