[PyQt] New exception in Python 3.7.4 when bad code tries to PyQt5.uic.loadUi()
Phil Thompson
phil at riverbankcomputing.com
Wed Aug 7 17:50:59 BST 2019
On 07/08/2019 16:54, Kyle Altendorf wrote:
> On 2019-08-07 07:13, Phil Thompson wrote:
>> On 05/08/2019 18:25, Kyle Altendorf wrote:
>>> On 2019-08-03 14:38, Kyle Altendorf wrote:
>>>> I have many custom widgets with pyqtProperty's and GUI elements
>>>> loaded
>>>> from .ui files. In various ways, my existing code tries to access
>>>> not-yet-present attributes in pyqtProperty's while the .ui is being
>>>> loaded. This is obviously bad and I plan to fix my code. I share
>>>> this example because I already finished it and because this is an
>>>> odd
>>>> change of behavior from a micro version bump of Python. Also, it is
>>>> odd that each first time my code raises an exception there is not
>>>> necessarily a Qt failure. For example, WidgetB must be constructed
>>>> twice to get the traceback. I understand that this may well not get
>>>> 'fixed' since it probably never should have worked to begin with.
>>>>
>>>> Code and output from 3.7.3/3.7.4 on Linux/Windows are attached and
>>>> also available at:
>>>>
>>>> https://gist.github.com/altendky/f15f8d180269a4080c25dec83cf556a0
>>>>
>>>> Here is the basic traceback:
>>>>
>>>> AttributeError: __getattribute__
>>>>
>>>> The above exception was the direct cause of the following
>>>> exception:
>>>>
>>>> Traceback (most recent call last):
>>>> File "bad.py", line 146, in main
>>>> widgets.append(WidgetA(broken=True))
>>>> File "bad.py", line 53, in __init__
>>>> PyQt5.uic.loadUi(io.StringIO(ui_text), self)
>>>> File
>>>> "C:\epc\bug\venv3.7-32\lib\site-packages\PyQt5\uic\__init__.py",
>>>> line
>>>> 227, in loadUi
>>>> return DynamicUILoader(package).loadUi(uifile, baseinstance,
>>>> resource_suffix)
>>>> File
>>>> "C:\epc\bug\venv3.7-32\lib\site-packages\PyQt5\uic\Loader\loader.py",
>>>> line 72, in loadUi
>>>> return self.parse(filename, resource_suffix, basedir)
>>>> File
>>>> "C:\epc\bug\venv3.7-32\lib\site-packages\PyQt5\uic\uiparser.py",
>>>> line
>>>> 1030, in parse
>>>> actor(elem)
>>>> File
>>>> "C:\epc\bug\venv3.7-32\lib\site-packages\PyQt5\uic\uiparser.py",
>>>> line
>>>> 942, in createConnections
>>>> QtCore.QMetaObject.connectSlotsByName(self.toplevelWidget)
>>>> SystemError: <built-in function connectSlotsByName> returned a
>>>> result with an error set
>>>
>>> I read briefly about this SystemError and it seems that while yes, my
>>> code was raising an exception and shouldn't really have worked
>>> ever...
>>> this error indicates that connectSlotsByName() isn't properly
>>> propagating the exception and is instead returning a value as if no
>>> exception occurred. As such it seems that there is an error in the
>>> PyQt connectSlotsByName() wrapper in addition to my code. Though I
>>> admittedly don't know my way around SIP nor the C-API much.
>>
>> It could also be that an exception is being correctly ignored, but not
>> cleared with PyErr_Clear().
>
> Why would it be correct to ignore my code raising an exception? It
> seems bad that my code has been seemingly silently raising these
> exceptions for a few years and I was unaware of it. I guess it could
> be argued that it would be handy for PyQt to add an exception ignoring
> feature and let connectSlotsByName() continue with it's work despite
> Python code failing. But this isn't the direction I would personally
> default. Mostly unhandled exceptions should be seen I would think.
I wasn't referring to your code but to the implementation of
connectSlotsByName().
Phil
More information about the PyQt
mailing list