Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-2335

Exceptions in __cause__ turn into str when raised inside virtual methods

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Not Evaluated
    • 6.5.2, 6.6.0
    • 6.5.0
    • PySide
    • None
    • Python 3.8 and Python 3.10, example above tested on Windows 10, however our CI shows the same problem in MacOS and Ubuntu.
    • Linux/X11, macOS, Windows
    • baedbe835 (dev), 28ddc0e50 (6.5)

    Description

      Hi,

      Chained exceptions raised inside virtual methods seem to have their {}{}clause__ attribute replaced by a str instance.

      Consider this example:

      import sys
      
      from PySide6.QtCore import QObject, QEvent
      from PySide6.QtWidgets import QApplication
      
      
      class Receiver(QObject):
      
          def event(self, ev):
              try:
                  try:
                      raise RuntimeError('original error')
                  except RuntimeError:
                      raise ValueError('mistakes were made')
              except:
                  print(repr(sys.exc_info()[1].__context__))
                  raise
      
      
      app = QApplication([])
      
      v = Receiver()
      app.sendEvent(v, QEvent(QEvent.Type.User))
      app.sendEvent(v, QEvent(QEvent.Type.User))
      app.processEvents()
      

      This gives this output:

      λ python tests\foo.py
      RuntimeError('original error')
      TypeError: print_exception(): Exception expected for value, str found
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "e:\projects\pytest-qt\tests\foo.py", line 23, in <module>
          app.sendEvent(v, QEvent(QEvent.Type.User))
        File "e:\projects\pytest-qt\tests\foo.py", line 14, in event
          raise ValueError('mistakes were made')
      ValueError: mistakes were made
      

      So the first print {{RuntimeError('original error') tells us that the _context  is correctly set when the exception occurs (as it should), but some time later the __context_ attribute is changed to `"Delayed ValueError exception:"` (`a str`), which breaks traceback formatting functions.}}

      As far as I can tell this behavior is independent of the Python version used, in this case I tested with Python 3.8 and Python 3.10.

      The same example using `PyQt6` gives the expected results (we just need to replace `PySide6` by `PyQt6` in the previous example):

      λ python tests\foo.py
      RuntimeError('original error')
      Traceback (most recent call last):
      File "e:\projects\pytest-qt\tests\foo.py", line 12, in event
      raise RuntimeError('original error')
      RuntimeError: original error
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
      File "e:\projects\pytest-qt\tests\foo.py", line 14, in event
      raise ValueError('mistakes were made')
      ValueError: mistakes were made 
      

      So I think the problem is in `PySide6` and how it is handling chained exceptions that originated from a C++ virtual method call.

      ------

      This was detected in pytest-dev/pytest-qt#488.

      Here's a link to our CI: https://github.com/pytest-dev/pytest-qt/actions/runs/4928752628/jobs/8807510393 

       

      Attachments

        1. pyside2335.py
          0.8 kB
          Friedemann Kleint

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              ctismer Christian Tismer
              nicoddemus Bruno Oliveira
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes