Home > Enterprise >  python3 command in Subprocess.Popen() not responding after converting python file to macOS executabl
python3 command in Subprocess.Popen() not responding after converting python file to macOS executabl

Time:10-21

Because my project is too big, this is a small example where you show the output of the command run on subprocess on tkinter. It works fine! But when I convert it to a macOS application it doesn't work and I think I have found out that error is happening in line where I call subprocess.Popen(). I am using py2app to convert my app to an executable so everyone can use it without installing python.

Below is my code for the tkinter application:

hello.py:

import subprocess
from tkinter import *

root = Tk()

l = Label(root, text="hello")
l.pack()

process = subprocess.Popen(
    "python3 test.py",
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    shell=True
)

l.config(text=process.communicate()[0])
root.mainloop()

As you see I will run test.py in subprocess.Popen() which simply contains print("Hello World")

Below is setup.py where I use py2app and setuptools to convert hello.py into a macOS application:

from setuptools import setup

APP = ['hello.py']
DATA_FILES = ['test.py']
OPTIONS = {}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

The Problem is that it doesn't work only as an executable file. However, this problem is too broad. So I experimented with my code and checked which line is causing it. I found out subprocess.Popen() line is where it is causing that problem. Ok is it subprocess.Popen() that's causing the error? Well I tried to use basic terminal commands like ls and they worked fine. Now its very clear that command python3 is where the problem is generating.

Please help me resolve this problem. I guess the subprocess.Popen() cannot access the python command when it is in the executable file. Is there a way for it access it even when its converted to macOS application?

EDIT!!!:

I FOUND THE ERROR! How can I not think about stderr! I tried displaying stderr(do this: l.config(text=process.communicate()[1])) on the tkinter window it shows this:

Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

Current thread 0x000000010096c580 (most recent call first):
<no Python frame>

Please help me resolve this problem. Thanks in advance.

CodePudding user response:

Try starting the python executable directly, not using shell:

In [10]: import sys, subprocess
    ...: 
    ...: def run_python(*args, inp: str = '', python: str = sys.executable):
    ...:     with subprocess.Popen(
    ...:         ((python,)   args),  # <- use the same interpreter executable
    ...:         shell=False,  # <- start it directly
    ...:         stdin=subprocess.PIPE,  # <- don't forget stdin
    ...:         stdout=subprocess.PIPE,
    ...:         stderr=subprocess.PIPE,
    ...:     ) as proc:
    ...:         return proc.communicate(inp)
    ...: 
    ...: out, err = run_python('-c', 'print("Hello world!")')
    ...: print((out, err))
(b'Hello world!\n', b'')
  • Related