Python 3.11 and mixing of enum.IntFlag

Florian Bruhin me at the-compiler.org
Wed May 25 15:25:31 BST 2022


Hey,

I'm trying to run my project (qutebrowser) with Python 3.11 now that the
Beta 1 was released and no new features are expected.

Unfortunately, it looks like the behavior of ORing IntFlags to produce
unknown members has been changed in Python 3.11. They now *don't*
produce a pseudo-member by default anymore, but decompose to an int
instead:

    $ python3.10 -c 'import enum; A = enum.IntFlag("A", {"x": 1}); B = enum.IntFlag("B", {"y": 2}); val = A.x | B.y; print(val, type(val))'
    A.B.y|x <enum 'A'>

    $ python3.11 -c '...'
    3 <class 'int'>

This breaks e.g. mixing of QUrl flags yet again:

    $ python3.10 -c 'from PyQt6.QtCore import QUrl; flags = QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded; print(QUrl("https://example.org").toString(flags))'
    https://example.org

    $ python3.11 -c '...'
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    TypeError: arguments did not match any overloaded call:
      toString(self, options: QUrl.UrlFormattingOption = QUrl.FormattingOptions(QUrl.PrettyDecoded)): argument 1 has unexpected type 'int'
      toString(self, QUrl.ComponentFormattingOption): argument 1 has unexpected type 'int'
    
The change happened with this cpython commit:
https://github.com/python/cpython/commit/7aaeb2a3d682ecba125c33511e4b4796021d2f82

It was originally intended to land in Python 3.10, but then was reverted
and rescheduled for 3.11 due to other issues with enum changes:
https://github.com/python/cpython/issues/88725

A possible fix seems to be to set boundary=enum.KEEP for flags which are
intended to be combined with other flags, but should retain their
(pseudo-)membership:
https://docs.python.org/3.11/library/enum.html#enum.FlagBoundary

That can even be monkey-patched at runtime, this makes things work:

    QUrl.UrlFormattingOption._boundary_ = enum.FlagBoundary.KEEP

Attached is a complete reproducer. Note that the Beta 1 has another
issue with creating certain Flag instances causing an IndexError:
https://github.com/python/cpython/pull/93197

Thanks, and sorry for even more enum-related trouble :)

Floriann

-- 
            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/20220525/4b0d6ce1/attachment.sig>


More information about the PyQt mailing list