[PyQt] New exception in Python 3.7.4 when bad code tries to PyQt5.uic.loadUi()

Kyle Altendorf sda at fstab.net
Wed Aug 7 16:54:15 BST 2019



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.

> However I can't reproduce the problem - I don't get a traceback,
> although I'm not using exactly the same versions of Python.

Yes, this showed up with Python 3.7.4.  Since that's the latest version 
it is the only one that this can be replicated on afaik.  Well, only 
released version.  3.8 betas may do the same thing, I haven't checked.  
Python 3.7.3 (and whatever various versions I've run this with for the 
past few years) did not raise exceptions.

Cheers,
-kyle


More information about the PyQt mailing list