[PyQt] Python property in QObject masks AttributeErrors

Phil Thompson phil at riverbankcomputing.com
Tue Apr 19 08:08:38 BST 2011


On Tue, 19 Apr 2011 08:46:13 +0200, Benjamin Kloster
<benjamin.kloster at videlco.eu> wrote:
> On Mon, 2011-04-18 at 22:18 +0100, Phil Thompson wrote:
>> On Mon, 18 Apr 2011 14:07:13 +0200, Benjamin Kloster
>> <benjamin.kloster at videlco.eu> wrote:
>> > Hi everyone,
>> > twice now I've stumbled over a subtle bug when subclassing QObject.
>> > When
>> > the getter of a python property raises an AttributeError for any
>> > attribute or object, PyQt seems to reraise this error improperly,
>> > clearing the traceback and often reporting a false object type and
>> > attribute name. See the attached script for a minimal example.
>> > 
>> > Regards,
>> > Ben
>> 
>> It's working as it should.
>> 
>> If the getter raises an AttributeError Python then calls any
__getattr__
>> method. If there is no method then the exception raised by the getter
is
>> propagated. If there is a __getattr__ then the getter exception is
>> discarded and the exception raised by __getattr__ is propagated.
>> 
>> QObject implements __getattr__ so the exception raised by the failure
of
>> QtCore.iDontExist is discarded. The exception that QObject.__getattr__
>> raises is what you are seeing.
>> 
>> Phil
>> 
> 
> The normal behavior of a Python object is to report the first
> AttributeError ("'module' object has no attribute 'iDontExist'). At
> least in Python 2.6, 2.7 and 3.2 it is. Just replace "QtCore.QObject"
> with "object" in the example to reproduce this.
> 
> Especially if a getter is rather involved and maybe even calls third
> party libraries that produce the original AttributeError, debugging
> becomes confusing at best with PyQt's behavior.
> 
> If it's not feasible to implement the correct (i.e. standard Python)
> error reporting, I can live with that. However, I couldn't find any note
> of this caveat in PyQt's documentation. So if it's really not there, it
> should probably be added.

The behaviour *is* the standard Python behaviour - it's not a PyQt thing.

Change "QtCore.QObject" with "object" and add a __getattr__ method that
raises an exception and you'll see.

Phil


More information about the PyQt mailing list