Suprising enum difference in PyQt 6 from PyQt 5

Greg Couch gregc at cgl.ucsf.edu
Mon Apr 18 07:13:36 BST 2022


If PyQt 6 is going to keep mapping C++ enums to Python enum.Enum, then 
being a little more sophisticated and using Florian's suggestion of 
making them not convertible to a boolean value would be very helpful in 
preventing coding errors.   Many of the Qt examples are in C++ and the 
straightforward translation to PyQt no longer works in PyQt 6.  First, 
there's the scope of the enum constants where you need to lookup what 
enum the constant belongs to (which is a real PITA and makes the code 
less readable), then there's this issue of the enum constants not 
behaving the same way in a boolean context.  And there are probably 
cases where the C++ enums should be enum.Flag's instead of enum.Enum's.  
I'm really glad that Phil is maintaining PyQt and not me.

So while I appreciate the desire to make PyQt be a more Pythonic 
interface, PyQt 5 treatment of Qt's C++ enums is much better.  I think 
it falls in the Python Zen's "Although practicality beats purity" clause.

     -- Greg

On 4/17/2022 12:26 PM, Florian Bruhin wrote:
> Hey,
>
> On Sun, Apr 17, 2022 at 01:01:25PM +0100, Phil Thompson wrote:
>>> I also think it would be good to be explicit about this matching in
>>> code: Should a PartialMatch be true or false?. Or in your case, should
>>> partially checked really count as checked?
>> Agreed. I tend to use 'is' when testing the value of enums rather than '=='.
>> Also 'in' a tuple of multiple values.
> Both are fine I suppose, and equivalent - but just an "if" without
> either is problematic.
>
>>> However, this is tricky, as it's a slient breakage, and those are rather
>>> hard to spot... Maybe those kind of enums shuold instead have some
>>> annotation in the .sip file which overrides their __bool__ to raise a
>>> TypeError instead?
>> Wouldn't it apply to all enums that sub-class Enum (rather than IntEnum)? It
>> surprises me that this isn't the default behaviour.
> Looks like enum.Enum just doesn't implement __bool__ at all, and thus
> all enum values are truthy:
> https://docs.python.org/3/reference/datamodel.html#object.__bool__
>
> There's a bit of information about it here:
> https://docs.python.org/3/library/enum.html#boolean-value-of-enum-classes-and-members
>
>> I'm happy to consider adding such a __bool__ method, however doing so
>> departs from standard Python behaviour and the main motivation for moving to
>> using Python enums in PyQt6 was to make it more Pythonic.
> Right. It's arguably questionable whether Python should really default
> __bool__ to return True even for things where it makes no sense for them
> to be truthy or falsey.
>
> Raising TypeError in __bool__ seems rather untypical, but also not
> totally unheard of:
>
>      >>> bool(pandas.NA)
>      Traceback (most recent call last):
>        File "<stdin>", line 1, in <module>
>        File "pandas/_libs/missing.pyx", line 382, in pandas._libs.missing.NAType.__bool__
>      TypeError: boolean value of NA is ambiguous
>
> Some discussion: https://github.com/pandas-dev/pandas/issues/38224
>
> This definitely would be useful now that I'm porting things from PyQt5
> to PyQt6 (to turn those into loud failures), but I'm not sure if it's a
> good thing to have in general, as you say...
>
> Florian
>


More information about the PyQt mailing list