2

The following very simple code runs well: python tmpmain.py would give you a window with a Help menu, and Help->About would give you a message. But once I cythonized the tmp.py into an extension, and rename tmp.py to tmp.py.bak to make sure tmpmain.py calls the compiled extension, python tmpmain.py will cause the RecursionError: maximum recursion depth exceeded while calling a Python object. I have simplified the code as much as I can, hoping it may help debug. Any suggestion?

#tmpmain.py
from tmp import main
if __name__ == '__main__':
    main() 

and,

#tmp.py
from PySide2.QtWidgets import (QApplication,  QMainWindow, QMenu, QMessageBox)
 from PySide2.QtCore import Slot

class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        super().__init__()
        self.setupHelpMenu()        


    def setupHelpMenu(self):
        helpMenu = QMenu("&Help", self)
        self.menuBar().addMenu(helpMenu)
        helpMenu.addAction("&About", self.about)

    @Slot()
    def about(self):
        QMessageBox.about(self, "About", "This is a demo")

import sys

def main():

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

The command to compile tmp.py is:

cythonize -X language_level=3 -i tmp.py
user3015347
  • 503
  • 3
  • 12
  • In Linux (Arch Linux) with Python 3.7.4, Cython 0.29.13 and PySide2 5.13 works correctly. Does even the simplified code generate the same problem for you? – eyllanesc Sep 02 '19 at 00:20
  • I am on Windows 10: Python 3.7.3, Cython 0.29.13, PySide2 5.12.4, and the compiler is: Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.22.27905, I could correctly compile and run non-PySide2 test cases. – user3015347 Sep 02 '19 at 00:55
  • Try updating the PySide2 version to 5.13 – eyllanesc Sep 02 '19 at 01:12
  • Miniconda 3 only has 5.12.4, let me see what I can do. Thanks! – user3015347 Sep 02 '19 at 01:21
  • I pip installed pyside2 5.13, and the python code still runs, but the compiled version still has the recursion error. – user3015347 Sep 02 '19 at 01:34
  • I also update Python to 3.7.4, but the recursion error remains. – user3015347 Sep 02 '19 at 01:45
  • So it is probably a bug, with what compiler was PySide2 compiled? Maybe the cython compiler is not the same as the one used to generate PySide2 – eyllanesc Sep 02 '19 at 01:51
  • `super` seems like a likely candidate to be going wrong. Maybe try replacing it with a direct call to the base class constructor? – DavidW Sep 02 '19 at 06:07
  • Though it didn't get rid of the recursion error, I simplified the init(). Since eyllanesc said it works on Linux, it seems it is the different compiler that causes the issue. Right now, I am using Miniconda 3 on Windows 10. But pip installed PySide2 5.13. Maybe the mix use of Miniconda3 and pip complicates? Maybe the next step should be compiling python/cython/pyside2 from source using one compiler on windows 10. – user3015347 Sep 02 '19 at 10:50
  • eyllanesc, on your linux box, how did you install python/pyside2/cython? Prepackaged Miniconda or everything compiled from source? – user3015347 Sep 02 '19 at 10:51
  • @user3015347 What is the point of compiling this with cython? I very much doubt that pyside explicitly supports that, so it will always be a gamble as to whether it "works". If you just want to create an exe, use one of the tools that are designed for the job (I don't have any recommendations). – ekhumoro Sep 02 '19 at 10:51
  • Related: https://stackoverflow.com/q/46602015/984421. And also see the comments to this pyside bug: [PYSIDE-674](https://bugreports.qt.io/browse/PYSIDE-674). – ekhumoro Sep 02 '19 at 10:57
  • yes, I also read a few other posts sharing experience that PyQT works, but not PySide2. It is a surprise since PySide2 is developed by Qt team, right? Other posts might involve complicated thread stuff, but mine involve just one window and one menu, so I am also suspecting that there is a nasty bug with PySide2 Signal/Slot implementation. – user3015347 Sep 02 '19 at 11:04
  • @user3015347 PySide2 is a work in progress. There are still a lot of bugs and unsupported features - and when Qt6 comes along, [there will be many more changes](https://blog.qt.io/blog/2019/08/19/technical-vision-qt-python/). I am not an insider, but I doubt whether supporting other compilers is going to be a priority, since so much more work is required to align PySide with Qt development. In fact, I think it's more likely that an in-house solution ( (i.e. like [pyqtdeploy](https://riverbankcomputing.com/software/pyqtdeploy/intro)) would be preferred over supporting third-party tools. – ekhumoro Sep 02 '19 at 11:34
  • @eyllanesc, I managed to reach a Linux machine, compiled the code under the same setting, but the recursion error remains. It seems to be a bug on PySide2. – user3015347 Sep 02 '19 at 15:46
  • @user3015347 To clarify: (using PySide 5.13.0, Cython 0.29.13) I see the recursion error on Linux when I do "help->about". Is this what you're reporting? If so you should make it clear in the question what you have to do to get the error. – DavidW Sep 02 '19 at 16:20
  • @user3015347 try add `from PySide2.QtCore import Slot` ... `@Slot()` `def about(self):` – eyllanesc Sep 02 '19 at 16:43
  • @DavidW, I wrapped all slots with lambda, and all functionalities essentially works now, though in the terminal I still see the recursion error msg. Especailly for the QTextEdit, every click incurs an error msg in the background terminal, but the QTextEdit is responsive so far, not sure whether it will collapse if used for long hours. – user3015347 Sep 02 '19 at 18:00
  • @user3015347 Could you explain to me what you mean with *But the Help-> About() popped out before the main window; after main window shows up, Help-> About is not responsive.*? – eyllanesc Sep 02 '19 at 18:02
  • @eyllanesc, I deleted my comment before I saw your new comment. My previous comment was wrong. I deleted lambda but didn't delete the () after the about, so the function is called at initialization. Now I deleted the lambda and () after the about. But the error remains. I updated the tmp.py above. – user3015347 Sep 02 '19 at 18:19
  • @eyllanesc, it is interesting that the revised code with Slot works with pyinstaller, no error at all. (I cythonized the tmp.py, renamed it, then pyinstaller tmpmain.py, and ./dist/tmpmain/tmpmain shows the main window correctly, and the Help->About also works without error. However, recursion error shows if I cythonized the tmp.py, renamed it, then python tmpmain.py) – user3015347 Sep 02 '19 at 18:42
  • Out of curiosity, what happens if you set the "binding" cython compiler directive to True? I remember this helped (albeit for a different issue) with decorated functions from python's contextlib library? Like @eyllanesc, the code works for me on Linuxmint using a pip-installed pyside2 package, so I cannot really test this out. – CodeSurgeon Sep 07 '19 at 07:19
  • Thanks, @CodeSurgeon, I tried the suggestion and the recursion error remains. – user3015347 Sep 08 '19 at 20:50

1 Answers1

2

This is more of an unsatisfactory workaround than an answer:

I have actually seen this problem before and posted the same unsatisfactory workaround as a comment. You need to wrap your function calls in a lambda function by changing the line:

helpMenu.addAction("&About", self.about)

to

helpMenu.addAction("&About", lambda: self.about())

I'm unclear why exactly this helps, but I'm posting the answer so for both the workaround and in the hope that this gives someone a clue where to start a proper diagnosis of the fault.

DavidW
  • 29,336
  • 6
  • 55
  • 86
  • The suggested method works. Though I were expecting a formal way, but we need to keep the ball rolling. Thanks for your magic suggestion! – user3015347 Sep 08 '19 at 20:52
  • Checked this method, I had the same issue while trying to compile with Cython a module that contained PySide2 windows and widgets in it for Maya 2022 (Python 3). In my case `partial` solved it, I had issues with `.connect()` functions. – Nix Apr 16 '21 at 21:24
  • I'm having the same problem with PySide2 in Maya2022, partial solves my issue as well. Does anyone know if there's an official Autodesk ticket or solution? – Fernando Ortega Sep 08 '22 at 20:41
  • I suspect Autodesk may not be very interested - it's likely either a PySide2 or Cython issue so they probably aren't in a position to fix it. – DavidW Sep 08 '22 at 21:14