When running any Python script without side-packages using QProcess, the script is executed successfully. But when running the same script with dependencies (e.g.* import numpy*), it throws a ModuleNotFoundError.
script.py: import subprocess
v = subprocess.run(["pip", "-V"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if v.stdout:
print(v.stdout)
else:
print("Error:", v.stderr)
try:
f = subprocess.check_output(['pip', 'freeze'], stderr=subprocess.STDOUT)
f_str = f.decode('utf-8')
print(f_str) #**"numpy==1.26.4" was listed**
except subprocess.CalledProcessError as e:
print("Error: ", e.output.decode('utf-8'))
import numpy as np **#Error occured here**
v = subprocess.run(["pip", "-V"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if v.stdout:
print(v.stdout)
else:
print("Error:", v.stderr)
how the script was executed using QProcess:
import subprocess
from PySide6.QtCore import QProcess
class ProcessManager(QWidget):
#...
def start_process(self, abs_filepath, args):
dir, fname = os.path.split(abs_filepath)
deps_dir = os.path.join(os.path.dirname(__file__), "deps")
self.check_requirements_installation(abs_filepath, deps_dir) #see below
subprocess.run(["pip", "-V", "", "", ""], check=True)
subprocess.check_output(['pip', 'freeze'], stderr=subprocess.STDOUT)
self.process = QProcess()
self.process.readyReadStandardOutput.connect(self.handle_output)
self.process.readyReadStandardError.connect(self.handle_error)
if self.process.state() == QProcess.NotRunning:
self.process.start('python', [abs_filepath] + args) #args = [[sth, sth, sth], [..], ..]
if not self.process.waitForFinished():
self.print_to_console.emit('error', 'Error: Process finished prematurely' + self.process.errorString())
return
if self.process.exitStatus() != QProcess.NormalExit:
self.print_to_console.emit('error', 'Error: Process exited abnormally' + self.process.errorString())
return
As you can see in the code above, I tried to compare the python versions, as well as the found side-packages. all executions of pip commands (QProcess-script, Qt terminal, admin terminal) printed out the same content (pip 23.2.1 from C:\Program Files\Python311\Lib\site-packages\pip (python 3.11)). Since I installed numpy globally, it can also be found in the same path (C:\Program Files\Python311\Lib\site-packages\numpy).
#All Python paths are in PATH.
#Tried it by setting qt´s default python (Edit>Preferences>Python>Interpreters) as suggested here: Qt ImportError when running a python script with imports
#Furthermore, requirements.txt are checked and installed automatically, so they cannot be missing before executing the process: (check packages suggested here: Atom shows ModuleNotFoundError when running python script)
def check_requirements_installation(self, main_dir, deps_dir):
requirements_path = os.path.join(main_dir, 'requirements.txt')
if os.path.exists(requirements_path):
try:
with open(requirements_path, 'rb') as file:
# Skip the BOM character if present
first_char = file.read(1)
if first_char != b'\xef\xbb\xbf':
file.seek(0)
requirements = file.read().decode('utf-16').splitlines()
installed_packages = subprocess.check_output(['pip', 'freeze'], text=True).splitlines()
missing_packages = [requirement for requirement in requirements if not any(requirement.split('==')[0] in package for package in installed_packages)]
for i in installed_packages:
print('installed', i)
if missing_packages:
self.print_to_console.emit('info', 'Some required packages are missing. Installing...')
for package in missing_packages:
print(package)
subprocess.run(["pip", "install", "-r", "requirements.txt", f"--target={deps_dir}"], check=True)
self.print_to_console.emit('info', 'All missing packages installed successfully.')
else:
self.print_to_console.emit('info', 'All required packages are already installed.')
except Exception as e:
self.print_to_console.emit('error', str(e))
else:
self.print_to_console.emit('warning', 'Please create a requirements.txt by opening your script in your ide, directing to its path inside the terminal and by executing "pip freeze requirements.txt" inside this terminal.')
self.update_status_signal.emit('error', 'Error: The requirements.txt is missing next to your main script. Please add it to the same folder path.')
return```
*# Additionally, I created a new venv for the script:
*```
def get_venv(self, abs_filepath):
venv_dir = os.path.join(os.path.dirname(__file__), "venv")
if not os.path.exists(venv_dir):
subprocess.run(["python", "-m", "venv", venv_dir], check=True)
activate_script = os.path.join(venv_dir, "Scripts", "activate.bat")
subprocess.run([activate_script], shell=True, check=True)
deps_dir = os.path.join(os.path.dirname(__file__), "deps")
self.check_requirements_installation(main_dir, deps_dir)
env = QProcessEnvironment.systemEnvironment();
env.insert("LD_LIBRARY_PATH", deps_dir)
self.check_requirements_installation(main_dir, dir)
return venv_dir
def start_process(self, abs_filepath, args):
#....
venv = self.get_venv(abs_filepath)
self.process = QProcess()
self.process.setEnvironment(venv_dir)
Also, the process was executed using python3 and python
(1) subprocess.run(["python", "-m", "venv", venv_dir], check=True)
(2) subprocess.run(["python3", "-m", "venv", venv_dir], check=True)
But executing it with python3 lead to a "Python could not be found error" (also inside the terminal), altrough "where python3" prints out the correct file path to the user-specific python3 installation. The execution with the abs. path to python3 lead to a No access rights error.
Edit: Adding access rights to Qt for the whole PC did not make the issue go away. Does anyone have an idea what might cause the NoModuleFoundError when including side-packages in scripts which are run by QProcess?