Когда я компилирую код Python, я получаю: RecursionError: максимальная глубина рекурсии превышена при вызове объекта Python - PullRequest
0 голосов
/ 29 мая 2018

edit: пробовал эквивалентный код с pyqt5, скомпилированным с cython.Это работает плавно, так что это похоже на ошибку pyside2.

Последняя версия Cython.Мое приложение работает нормально, когда я запускаю его с python, но когда я превращаю его в модуль и импортирую модуль из простого скрипта запуска, оно внезапно не видит никаких данных из Интернета, и оно также дает мне следующее: RecursionError: MaximumГлубина рекурсии превышена при вызове объекта Python.

Nuitka имеет ту же проблему, но не дает мне этих рекурсивных ошибок.

Понятия не имею, уместно ли это, но при компиляции программы (создании объектного кода) с помощью gcc я также получаю следующее сообщение об ошибке / предупреждение / примечание (единственное):

$ 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) {
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ТакжеНе уверен, если это уместно, но у меня есть куча классов (потоков), которая вызывает следующий класс, когда один завершает создание цикла.Может быть, это nono, даже если он отлично работает в python?

Я использую pyside2, запросы, delorean и humanize.Я даже не уверен, как начать отладку, это программа из 4000 строк.

edit: Хорошо, так что мне удалось воспроизвести точную проблему в минимальном примере.Этот код будет отлично работать до того, как вы скомпилируете его с помощью cython или nuitka.Если вы скомпилируете его с помощью Cython, он выдаст:

('thread1:', <Response [200]>)
RecursionError: maximum recursion depth exceeded while calling a Python object

и зависнет, но он покажет содержимое окна.При использовании nuitka содержимое окна никогда не будет отображаться, но потоки будут работать так, как ожидается.Если кто-нибудь может объяснить, почему это происходит и как я могу это исправить, это было бы здорово:

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 Ответ

0 голосов
/ 29 мая 2018

Возможно, что существуют разные настройки предела рекурсии в каждой среде.Попробуйте настроить предел рекурсии

import sys
sys.setrecursionlimit(3000)

(3000 - только предположение).Вы можете увидеть ограничение, используя

import sys
sys.getrecursionlimit()

Это только взлом, а не рекомендуемый способ.Вы должны подумать о рефакторинге кода с использованием итерации вместо рекурсии или сделать рекурсию лучше.Трудно сказать больше с предоставленной информацией.

Я видел, как другие устанавливали также глубину рекурсии следующим образом: Установка размера стека в скрипте Python .Возможно, стоит попробовать.

ОБНОВЛЕНИЕ: После того, как вы обновили свой вопрос, я увидел, что у вас также есть проблемы с переменным размером отслеживания.Вы также можете попробовать это: Настроить длину назначения отслеживания переменных

...