Why does Subprocess.Popen run a different Python version to cmd.exe? - python

I have a script which won't run inside of Nuke's built-in Python interpreter, so I'm trying to launch in via the system's Python instead. I'm using subprocess.Popen to do this, but it still won't run inside a subprocess (missing modules), even though it runs fine at the command prompt (cmd.exe)
I think the problem is, that I just don't understand what environment my subprocess starts up in. It doesn't even run the expected version of Python.
In cmd.exe:
C:/Python27/python.exe -V
> Python 2.7.16
In Nuke:
import subprocess as sub
print sub.Popen("C:/Python27/python.exe -V", stderr=sub.PIPE).communicate()[1]
# Result: Python 2.7.13
print sub.Popen('C:/Python27/python.exe -c
"import sys;print(sys.executable)"',
stdout=sub.PIPE).communicate()[0]
# Result: C:\Python27\python.exe
Where is this lower version of Python coming from? It's probably not a coincidence that Nuke's built-in Python is also 2.7.13, but why would Popen run that and not the .exe I'm specifying?
Note: same result whether I give shell=True or shell=False

Related

Python3 as default python version

I am creating a script that will call an API and return some results. I have the script working with pycharm on my computer but I am running into a few problems but I want to focus on this problem first.
1) I am unable to set Python3 as my default python.
I am using a Mac. When I go into terminal I enter $ python --version and it returns Python 2.7.10
I then enter $ alias python=python3, and when I run $python --version it returns Python 3.7.2
When I create a py.script with the os module, it does not work. See my code below.
import os
os.system('alias python=python3')
print(os.system('python --version')
It prints 2.7.10
I also tried to run the os.system('alias python="python3"')
On -nix machines (including OSX), one way to change the version of the interpreter that the script runs with is to add a shebang as the first line of your script.
Eg.
#! /usr/bin/env python3
import sys
print(sys.version)
Then to run your script do:
~/$ chmod u+x myscript.py
~/$ ./myscript.py
You only need to run the chmod command the first time. It enables you to execute the file. Whenever you run your script directly (rather than as an argument to python) your script will be run using the version specified by the shebang.
welcome to SO! Pycharm needs you to specify which interpreter to use as default, as it wouldn't choose the system one by default.
So if you want python3, you can run which python3, and use the path as a settings for the current project. How to do that step by step is here:
https://www.jetbrains.com/help/pycharm/configuring-python-interpreter.html
Hope it help, post a comment if you need more details.
This isn't surprising, because os.system opens its own shell, and running alias in that way only affects the currently running terminal. Each call to os.system would be in a separate shell.
I'm not sure what your ultimate goal is, but you almost certainly don't need to change what python means to a shell to do it. If you DO, you'll have to run both commands at once.
import subprocess
cp = subprocess.run("alias python=python3 && /path/to/script")
Interesting - apparently os.system ignores the alias? Just checked it in Linux and got the same results.
Try sys instead of os:
import sys
print(sys.version)

How can I locate python2 path within python3 code?

I use both python 2 and python 3 on my machine. I take advantage of the she-bang notation at the top of my python scripts and use the new python launcher that came with python 3.
I would like to locate the python 2 path for python.exe from within a python 3 script running on windows.
sys.executable and similar commands won't work because it shows the path to the currently running python. It will not show the path to another version of python.
How about the following? It utilizes the new launcher to execute python2, and gives it a one-liner to print sys.executable, so it's the python2 interpreter running it.
import subprocess
print(str(subprocess.run(['py', '-2', '-c', 'import sys;print(sys.executable)'],
stdout=subprocess.PIPE).stdout, 'utf-8'))
Output:
$ python -V
Python 3.6.5
$ python get_two.py
C:\Python27\python.exe

Changing version of python when using nohup

I am trying to run a python program called compare.py with the linux nohup command which keeps the program running until it is done without interruption. my python program has packages which can only run on python 2.7 and when i use nohup command program is run in python 2.6. how do i change the version of python when using nohup?
Example: nohup python compare.py $
I tried doing:
alias python=python2.7
before starting program and version of python isn't switched. how do i switch the version of python to 2.7 when i run nohup?
The easiest way would be to use a shebang line to specify the interpretter. At the start of your Python file, put something like
#!/usr/bin/python2.7
# This should be a path to an interpreter that you know for sure is Python 2.7
Then, use chmod +x file.py to make the Python file itself executable, and omit the python part of your nohup command, eg. nohup ./compare.py.
I had the same issue with anaconda python. While using nohup python, it was using python 2.7 but generic python command in terminal was taking me to 3.6.
nohup ~/anaconda3/bin/python scriptname.py
Providing full path to python after nohup command will solve the issue

Why is OSX not running the python I get with whereis python

I have a machine running OSX Yosemite (it has been through several versions of OSX, which may make a difference).
I noticed an anomily with whether python could import libraries depending on whether the script was run directly, i.e.
./Myscript.py
Or by expressly calling python
python Myscript.py
Now, if I type
$whereis python
/usr/bin/python
And my shebang line in the script is
#!/usr/bin/python
So I assumed that the same version of python was running in both cases.
But after investigating I find
$python --version
Python 2.7.6
$/usr/bin/python --version
Python 2.7.10
So it would seem that the python being executed is not the one I get when I do a whereis
Can anyone please shed some light on this, and also clarify how to fix it? I really want to be running 2.7.10 in both cases, since right now when I install libraries they go into 2.7.6, but when I run scripts, they run 2.7.10 and can't see the libraries.
Thanks
Jon
Don't use whereis, that command ignores your PATH environment variable. From the manpage:
The whereis utility checks the standard binary directories for the specified programs, printing out the paths of any it finds.
Emphasis mine.
You have a PATH environment variable that includes a 'nonstandard' binary directory. Use which to find where python comes from:
$ which python
which gives you the actual binary used for your current shell configuration:
The which utility takes a list of command names and searches the path for each executable file that would be run had these commands actually been invoked.
You could use which -a to find all possible completions for the command:
$ which -a python
Also see “whereis” and “which” return different paths in Mac OS X on Super User.
Demo:
$ PATH=/opt/homebrew/bin:$PATH whereis python
/usr/bin/python
$ PATH=/opt/homebrew/bin:$PATH which -a python
/opt/homebrew/bin/python
/usr/bin/python
So even with PATH explicitly pointing to my homebrew directory, whereis ignores it. which finds it and lists it first (the -a argument made it look for more options).

When running a python script from the console what is the difference between py vs python

I have been reading about python, and I have certain doubts when using the shebang line. When I run:
py file_name.py
It executes the script using the python version that I have indicated in the shebang line, but when I execute,
python file_name.py
The last version of Python is used instead of the one that I have specified. I would like to know the difference between using python and py when running a script from the command line. My shebang line was #! python3.4
Does using either python or py have different implications or eventually both are the same?
(This answer assumes you're using Windows, but I expect it mostly applies to other OSes too, modulo some details)
"python.exe" is the actual interpreter. You have one for each version of Python on your system. Which version gets executed when you run "python" on the command line, depends on your PATH environment variable and your current working directory.
"py.exe" is the Python Launcher. You probably only have one, even if you have multiple Python installs. Mine is in C:\Windows. It looks at the script, decides what version it's using, and delegates the actual execution to the proper interpreter.
To see what version of Python are in use for each command, run these two commands:
python -c "import sys;print(sys.version)"
py -c "import sys;print(sys.version)"
If both show the same version, then on your system they are both currently the same. However, one or the other might be updated. I personally recommend to rely on neither, and to call the Python version that you want explicitly in your scripts.

Categories