edit: Tried the equivalent code with pyqt5 compiled with cython. It works swimmingly so this seems to be a pyside2 bug.
Latest version of cython. My app works fine when i run it with python but when i make it into a module and import the module from a simple launcher script suddenly it doesn't seem to see any data from the internet and it also gives me these: RecursionError: maximum recursion depth exceeded while calling a Python object.
Nuitka has the same problem but doesn't give me these recursionerrors.
I have no idea if it's relevant but when compiling the program(making object code) with gcc i also get this error/warning/note(the only one):
$ python setup.py build_ext --inplace
Compiling prog.py because it changed.
[1/1] Cythonizing prog.py
running build_ext
building 'prog' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3
-Wall -Wstrict-prototypes -march=x86-64 -mtune=generic -O2 -pipe -
fstack-protector-strong -fno-plt -march=x86-64 -mtune=generic -O2 -
pipe -fstack-protector-strong -fno-plt -march=x86-64 -mtune=generic -
O2 -pipe -fstack-protector-strong -fno-plt -fPIC -
I/usr/include/python3.6m -c prog.c -o build/temp.linux-x86_64-
3.6/prog.o
prog.c: In function ‘__pyx_pf_4prog_13Ui_MainWindow_setupUi.isra.76’:
prog.c:41235:18: note: variable tracking size limit exceeded with -
fvar-tracking-assignments, retrying without
static PyObject *__pyx_pf_4prog_13Ui_MainWindow_setupUi(CYTHON_UNUSED
PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_MainWindow) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Also not sure if relevant but i have a bunch of classes(threads) that calls the next class when one is finished making a loop. Maybe this is a nono even if it works fine in python?
I'm using pyside2, requests, delorean and humanize. Im not even sure how to start debugging this, it's a 4000 line program.
edit: Ok so i managed to reproduce the exact problem in a minimal example. This code will work perfectly before you compile it with cython or nuitka. If you compile it with cython it will output:
('thread1:', <Response [200]>)
RecursionError: maximum recursion depth exceeded while calling a Python object
and hang but it will show the window contents. With nuitka it will never show the contents of the window but the threads will run as expected. If anyone can explain why it happens and how i can fix it that would be great:
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Slot, Signal, QThread
import sys
import requests
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(240, 100, 97, 34))
self.pushButton.setObjectName("pushButton")
self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
self.plainTextEdit.setGeometry(QtCore.QRect(200, 160, 451, 271))
self.plainTextEdit.setPlainText("")
self.plainTextEdit.setObjectName("plainTextEdit")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 30))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "OK"))
class MainUIClass(QtWidgets.QMainWindow, Ui_MainWindow):
def closeEvent(self, evnt):
print("CLOSED")
self.thread1.quit()
self.thread2.quit()
self.thread3.quit()
self.thread1.wait()
self.thread2.wait()
self.thread3.wait()
print("thread1 is running?:", self.thread1.isRunning())
print("thread2 is running?:", self.thread2.isRunning())
print("thread3 is running?:", self.thread3.isRunning())
sys.exit()
def __init__(self, parent=None):
super().__init__()
self.setupUi(self)
self.thread1 = QThread()
self.thread2 = QThread()
self.thread3 = QThread()
self.Class1 = Class1()
self.Class2 = Class2()
self.Class3 = Class3()
self.Class1.moveToThread(self.thread1)
self.Class2.moveToThread(self.thread2)
self.Class3.moveToThread(self.thread3)
self.thread1.started.connect(lambda: self.Class1.startThread())
self.Class1.startThread2.connect(self.Class2.startThread)
self.Class2.startThread3.connect(self.Class3.startThread)
self.Class3.startThread1.connect(self.Class1.startThread)
self.thread1.start()
self.thread2.start()
self.thread3.start()
class Class1(QtCore.QObject):
startThread2 = Signal()
def __init__(self):
super().__init__()
def startThread(self):
data = requests.get("https://www.google.com")
print("thread1:", data)
self.startThread2.emit()
class Class2(QtCore.QObject):
startThread3 = Signal()
def __init__(self):
super().__init__()
def startThread(self):
data = requests.get("https://www.google.com")
print("thread2:", data)
self.startThread3.emit()
class Class3(QtCore.QObject):
startThread1 = Signal()
def __init__(self):
super().__init__()
def startThread(self):
data = requests.get("https://www.google.com")
print("thread3:", data)
self.startThread1.emit()
a = QtWidgets.QApplication(sys.argv)
app = MainUIClass()
a.setQuitOnLastWindowClosed(False)
app.setWindowTitle("Pyside2 thread compiled test")
app.show()
sys.exit(a.exec_())