Re: New exception in Python 3.7.4 when bad code tries to PyQt5.uic.loadUi()

Phil Thompson <[email protected]>
Newsgroups gmane.comp.python.pyqt-pykde
Message-ID <[email protected]>
On 07/08/2019 18:06, Kyle Altendorf wrote:
> On 2019-08-07 12:50, Phil Thompson wrote:
>> 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().
> 
> That's what I was responding to.  It doesn't seem like
> connectSlotsByName() should be silencing exceptions raised by my code
> that it calls.  Or maybe something else is calling my code and this is
> just a delayed error.  Regardless, I would think that if my code
> raises an exception the default behavior ought to be to fail and show
> that error, not continue silently.  I know my code is bad in this
> regard and neither before nor at Python 3.7.4 is there a message about
> the exception my code raises.

As I said, I wasn’t referring to exceptions raised by your code.

> Anyways, I think we may have agreed that something somewhere, other
> than my code raising an exception, isn't quite right?

Yes (although I don’t get a traceback with v3.8).

Phil

_______________________________________________
PyQt mailing list    [email protected]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.