Suprising enum difference in PyQt 6 from PyQt 5

Florian Bruhin me at the-compiler.org
Sat Apr 16 18:38:41 BST 2022


Hi,

On Tue, Apr 12, 2022 at 07:02:19PM -0700, Greg Couch wrote:
> So I have a QTreeWidgetItem, and in PyQt 5, I was able to use:
> 
> > if item.checkState(0):
> to check if the item was checked or not.  The return value is a
> QtCore.Qt.CheckState enum.   That fails in PyQt 6 because
> QtCore.Qt.CheckState.Unchecked evaluates as True.  If QtCore.Qt.CheckState
> were changed to subclass from enum.IntEnum, instead of enum.Enum, this would
> not be a porting problem.

I see similar issues in other boolean-but-not-quite enums.

With PyQt 5:

    >>> full_match = QKeySequence.fromString("a, b").matches(QKeySequence.fromString("a, b"))
    >>> partial_match = QKeySequence.fromString("a").matches(QKeySequence.fromString("a, b"))
    >>> no_match = QKeySequence.fromString("x").matches(QKeySequence.fromString("a, b"))
    >>> full_match, partial_match, no_match
    (2, 1, 0)
    >>> bool(full_match), bool(partial_match), bool(no_match)
    (True, True, False)

but PyQt 6:

    >>> full_match, partial_match, no_match
    (<SequenceMatch.ExactMatch: 2>, <SequenceMatch.PartialMatch: 1>, <SequenceMatch.NoMatch: 0>)
    >>> bool(full_match), bool(partial_match), bool(no_match)
    (True, True, True)

so a "if seq.matches(other):" now silently is true even for
QKeySequence.SequenceMatch.PartialMatch.

I'm not sure if "just make it an IntEnum" is a suitable fix. I like the
idea of having a strict separation between ints and enums, and a match
(or a check state) clearly isn't a number (that's just an implementation
detail of old-style C++ enums essentially).

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?

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?

Florian

-- 
            me at the-compiler.org | https://www.qutebrowser.org 
       https://bruhin.software/ | https://github.com/sponsors/The-Compiler/
       GPG: 916E B0C8 FD55 A072 | https://the-compiler.org/pubkey.asc
             I love long mails! | https://email.is-not-s.ms/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20220416/b651312a/attachment.sig>


More information about the PyQt mailing list