Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issues with the "subprocess" module in Python 3.9.1 (or 3.9.2) - "subprocess.Popen" doesn't work

When my script has the .pyw extension, the function subprocess.Popen doesn't work, but if I use the .py extension, it works. Actually the extension is not so important, the main point is if I use the terminal or not to run the script, if I don't use it I have the issue, otherwise no issues.

This wird behaviout happens only in my PC with Python 3.9.1 or 3.9.2 (the last version currently available). However I have another PC with Python 3.9.0, and there the issue doesn't exist.

I'll give you an example. here I have two scripts, below is the first one named main_script.pyw:

from tkinter import *
from tkinter import ttk
import sys, subprocess

def MyFunction():
    subprocess.Popen(["start", sys.executable, "script.py"], shell=True)

parent=Tk()
parent.geometry("300x250+370+100")
parent.title("Test")

TestButton=ttk.Button(parent, text="start", width=16, command=MyFunction)
TestButton.place(x=10, y=10)

parent.mainloop()

Here is the second one named script.py:

a=input("give me a number: ")

Both of them are placed in the same directory. The user can start the second script using the function subprocess.Popen only if the extension of the main script is .py, otherwise he can't. How can I solve the issue? Is it a BUG?

I attached a GIF too:

enter image description here

UPDATE! 1 I tried to install Python 3.9.0 in a virtual machine, and there I found the same issue described before! so, I can't understand why in my PC, with the same version, the script works. if I type python --version in my terminal the output is Python 3.9.0. Here is another GIF to show you that it works:

enter image description here

In the installation path (C:\Users\USER_NAME\AppData\Local\Programs\Python), I saw two folders, Python39 and Python38-32. Probably the second one is a refuse from an old installation, I don't know, but maybe it helps to make the script work. What do you think?

I just want to run CLI scripts via Tkinter as you saw in the last GIF (without using the terminal of course). How can I reach my goal?

UPDATE! 2 I'm not sure but, maybe it's a Windows issue. I tried to run Google Chrome using the subprocess.Popen(["start", sys.executable, "script.py"], shell=True) instruction (before you have to open the terminal in the Chrome installation folder C:\Program Files\Google\Chrome\Application) and it worked only in my PC where I never have issues, but with the other one Chrome didn't start, and in the terminal I got this output (I use ConEmu as terminal):

>>> subprocess.Popen(["start", sys.executable, "chrome.exe"], shell=True) 
<Popen: returncode: None args: ['start', 'C:\\Users\\aquer\\AppData\\Local\\...>

SyntaxError: Non-UTF-8 code starting with '\x83' in file C:\Program Files\Google\Chrome\Application\chrome.exe on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Current directory:
C:\Program Files\Google\Chrome\Application

Command to be executed:
"C:\Users\USER_NAME\AppData\Local\Programs\Python\Python39\python.exe"   chrome.exe

ConEmuC: Root process was alive less than 10 sec, ExitCode=1.
Press Enter or Esc to close console...

I tried to open the terminal in Admin mode but, also in this case, Google Chrome didn't start. Where is the issue from your point of viewes?

like image 873
TurboC Avatar asked Mar 07 '21 21:03

TurboC


People also ask

Is Popen deprecated?

popen is not really deprecated; There is an error in the standard library and os.

How subprocess popen works in Python?

The subprocess module defines one class, Popen and a few wrapper functions that use that class. The constructor for Popen takes arguments to set up the new process so the parent can communicate with it via pipes. It provides all of the functionality of the other modules and functions it replaces, and more.

What is the difference between subprocess run and Popen?

The main difference is that subprocess. run() executes a command and waits for it to finish, while with subprocess. Popen you can continue doing your stuff while the process finishes and then just repeatedly call Popen. communicate() yourself to pass and receive data to your process.

What does the popen () return on success?

If successful, popen() returns a pointer to an open stream that can be used to read or write to a pipe. If unsuccessful, popen() returns a NULL pointer and sets errno to one of the following values: Error Code. Description.


1 Answers

I think that it is because for .py files Windows uses python.exe and for .pyw files Windows uses pythonw.exe. The problem is that sys.executable has the file location of the program used to start the main python file (python.exe when the extension is .py and pythonw.exe when the extension is .pyw). So the problem is that you are trying to start the .py program using the python executable that is for .pyw file extensions.

In cmd:

>>> import sys
>>> sys.executable
'C:\\Program Files\\Python37\\python.exe'

in IDLE (doesn't have the terminal window):

>>> import sys
>>> sys.executable
'C:\\Program Files\\Python37\\pythonw.exe'

Therefore, you have to decide which program (python.exe or pythonw.exe) you want to use. You can do it based on the file extension.

like image 63
TheLizzard Avatar answered Oct 19 '22 20:10

TheLizzard