When i compile my python code i get: RecursionError: maximum recursion depth exceeded while calling a Python object

时光怂恿深爱的人放手 提交于 2019-12-25 18:43:11

问题


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_())

回答1:


It is possible that there are different settings of recursion limit in each environment. Try to adjust the recursion limit

import sys
sys.setrecursionlimit(3000)

(3000 is just a guess). You can see the limit by using

import sys
sys.getrecursionlimit()

This is only a hack, not a recommended way. You should think to refactor code using iteration instead of recursion or make the recursion work better. It's hard to tell more with provided information.

I've seen others setting also recursion depths like this: Setting stacksize in a python script . Maybe it's worth a try, too.

UPDATE: After you have updated your question, I've seen that you also have problems with variable tracking size. You can also try that: Adjust Variable Tracking Assignment Length



来源:https://stackoverflow.com/questions/50582560/when-i-compile-my-python-code-i-get-recursionerror-maximum-recursion-depth-exc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!