diff --git a/CHANGELOG.md b/CHANGELOG.md index bae5b1bf..55615608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * [#175](https://github.com/python-qt-tools/PyQt5-stubs/pull/175) catch up PyQtNetworkAuth with the 5.15.4 release * [#149](https://github.com/python-qt-tools/PyQt5-stubs/pull/149) update to PyQt5 5.15.4 * [#138](https://github.com/python-qt-tools/PyQt5-stubs/pull/138) update to PyQt5 5.15.3 +* [#145](https://github.com/python-qt-tools/PyQt5-stubs/pull/145) Support all implemented arithmetic operations between Qt.WindowType and Qt.WindowFlags and int * [#144](https://github.com/python-qt-tools/PyQt5-stubs/pull/144) add `QTreeWidgetItem.__lt__()` to allow sorting of items in a QTreeWidget * [#143](https://github.com/python-qt-tools/PyQt5-stubs/pull/143) make `bytes(QByteArray())` valid by incorrectly adding `.__bytes__()` until a proper solution is developed upstream * [#152](https://github.com/python-qt-tools/PyQt5-stubs/pull/152) add `.__or__()` for `QDialogButtonBox.StandardButton` and `QDialogButtonBox.StandardButtons` * [#156](https://github.com/python-qt-tools/PyQt5-stubs/pull/156) add operators to `QSize` and `QSizeF` +* [#153](https://github.com/python-qt-tools/PyQt5-stubs/pull/153) Support all implemented arithmetic operations for QFlags + based classes in modules QtCore, QtWidgets, QtGui, QtNetwork, QtDBus, QtOpenGL, QtPrintsupport, QtSql, QtTest, QtXml ## 5.15.2.0 diff --git a/PyQt5-stubs/QtCore.pyi b/PyQt5-stubs/QtCore.pyi index a3b30d69..23a4bf73 100644 --- a/PyQt5-stubs/QtCore.pyi +++ b/PyQt5-stubs/QtCore.pyi @@ -179,6 +179,9 @@ class Qt(sip.simplewrapper): TabFocusAllControls = ... # type: Qt.TabFocusBehavior class MouseEventFlag(int): + def __or__ (self, other: 'Qt.MouseEventFlag') -> 'Qt.MouseEventFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.MouseEventFlags': ... # type: ignore[override, misc] + MouseEventCreatedDoubleClick = ... # type: Qt.MouseEventFlag MouseEventCreatedDoubleClick = ... # type: Qt.MouseEventFlag @@ -225,6 +228,9 @@ class Qt(sip.simplewrapper): SwipeNativeGesture = ... # type: Qt.NativeGestureType class Edge(int): + def __or__ (self, other: 'Qt.Edge') -> 'Qt.Edges': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.Edges': ... # type: ignore[override, misc] + TopEdge = ... # type: Qt.Edge LeftEdge = ... # type: Qt.Edge RightEdge = ... # type: Qt.Edge @@ -272,6 +278,9 @@ class Qt(sip.simplewrapper): FindChildrenRecursively = ... # type: Qt.FindChildOption class ScreenOrientation(int): + def __or__ (self, other: 'Qt.ScreenOrientation') -> 'Qt.ScreenOrientations': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.ScreenOrientations': ... # type: ignore[override, misc] + PrimaryOrientation = ... # type: Qt.ScreenOrientation PortraitOrientation = ... # type: Qt.ScreenOrientation LandscapeOrientation = ... # type: Qt.ScreenOrientation @@ -305,6 +314,9 @@ class Qt(sip.simplewrapper): NavigationModeCursorForceVisible = ... # type: Qt.NavigationMode class GestureFlag(int): + def __or__ (self, other: 'Qt.GestureFlag') -> 'Qt.GestureFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.GestureFlags': ... # type: ignore[override, misc] + DontStartGestureOnChildren = ... # type: Qt.GestureFlag ReceivePartialGestures = ... # type: Qt.GestureFlag IgnoredGesturesPropagateToParent = ... # type: Qt.GestureFlag @@ -340,6 +352,9 @@ class Qt(sip.simplewrapper): GestureCanceled = ... # type: Qt.GestureState class TouchPointState(int): + def __or__ (self, other: 'Qt.TouchPointState') -> 'Qt.TouchPointStates': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.TouchPointStates': ... # type: ignore[override, misc] + TouchPointPressed = ... # type: Qt.TouchPointState TouchPointMoved = ... # type: Qt.TouchPointState TouchPointStationary = ... # type: Qt.TouchPointState @@ -373,6 +388,9 @@ class Qt(sip.simplewrapper): AnchorBottom = ... # type: Qt.AnchorPoint class InputMethodHint(int): + def __or__ (self, other: 'Qt.InputMethodHint') -> 'Qt.InputMethodHints': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.InputMethodHints': ... # type: ignore[override, misc] + ImhNone = ... # type: Qt.InputMethodHint ImhHiddenText = ... # type: Qt.InputMethodHint ImhNoAutoUppercase = ... # type: Qt.InputMethodHint @@ -497,6 +515,9 @@ class Qt(sip.simplewrapper): MaskOutColor = ... # type: Qt.MaskMode class TextInteractionFlag(int): + def __or__ (self, other: 'Qt.TextInteractionFlag') -> 'Qt.TextInteractionFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.TextInteractionFlags': ... # type: ignore[override, misc] + NoTextInteraction = ... # type: Qt.TextInteractionFlag TextSelectableByMouse = ... # type: Qt.TextInteractionFlag TextSelectableByKeyboard = ... # type: Qt.TextInteractionFlag @@ -605,6 +626,9 @@ class Qt(sip.simplewrapper): ApplicationModal = ... # type: Qt.WindowModality class MatchFlag(int): + def __or__ (self, other: 'Qt.MatchFlag') -> 'Qt.MatchFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.MatchFlags': ... # type: ignore[override, misc] + MatchExactly = ... # type: Qt.MatchFlag MatchFixedString = ... # type: Qt.MatchFlag MatchContains = ... # type: Qt.MatchFlag @@ -630,6 +654,9 @@ class Qt(sip.simplewrapper): MatchRegularExpression = ... # type: Qt.MatchFlag class ItemFlag(int): + def __or__ (self, other: 'Qt.ItemFlag') -> 'Qt.ItemFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.ItemFlags': ... # type: ignore[override, misc] + NoItemFlags = ... # type: Qt.ItemFlag ItemIsSelectable = ... # type: Qt.ItemFlag ItemIsEditable = ... # type: Qt.ItemFlag @@ -703,6 +730,9 @@ class Qt(sip.simplewrapper): Checked = ... # type: Qt.CheckState class DropAction(int): + def __or__ (self, other: 'Qt.DropAction') -> 'Qt.DropActions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.DropActions': ... # type: ignore[override, misc] + CopyAction = ... # type: Qt.DropAction MoveAction = ... # type: Qt.DropAction LinkAction = ... # type: Qt.DropAction @@ -740,6 +770,10 @@ class Qt(sip.simplewrapper): ToolButtonFollowStyle = ... # type: Qt.ToolButtonStyle class InputMethodQuery(int): + def __or__ (self, other: 'Qt.InputMethodQuery') -> 'Qt.InputMethodQueries': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.InputMethodQueries': ... # type: ignore[override, misc] + + ImMicroFocus = ... # type: Qt.InputMethodQuery ImFont = ... # type: Qt.InputMethodQuery ImCursorPosition = ... # type: Qt.InputMethodQuery @@ -944,6 +978,9 @@ class Qt(sip.simplewrapper): RFC2822Date = ... # type: Qt.DateFormat class ToolBarArea(int): + def __or__ (self, other: 'Qt.ToolBarArea') -> 'Qt.ToolBarAreas': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.ToolBarAreas': ... # type: ignore[override, misc] + LeftToolBarArea = ... # type: Qt.ToolBarArea RightToolBarArea = ... # type: Qt.ToolBarArea TopToolBarArea = ... # type: Qt.ToolBarArea @@ -970,6 +1007,9 @@ class Qt(sip.simplewrapper): VeryCoarseTimer = ... # type: Qt.TimerType class DockWidgetArea(int): + def __or__ (self, other: 'Qt.DockWidgetArea') -> 'Qt.DockWidgetAreas': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.DockWidgetAreas': ... # type: ignore[override, misc] + LeftDockWidgetArea = ... # type: Qt.DockWidgetArea RightDockWidgetArea = ... # type: Qt.DockWidgetArea TopDockWidgetArea = ... # type: Qt.DockWidgetArea @@ -2122,6 +2162,9 @@ class Qt(sip.simplewrapper): OpaqueMode = ... # type: Qt.BGMode class ImageConversionFlag(int): + def __or__ (self, other: 'Qt.ImageConversionFlag') -> 'Qt.ImageConversionFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.ImageConversionFlags': ... # type: ignore[override, misc] + AutoColor = ... # type: Qt.ImageConversionFlag ColorOnly = ... # type: Qt.ImageConversionFlag MonoOnly = ... # type: Qt.ImageConversionFlag @@ -2364,6 +2407,9 @@ class Qt(sip.simplewrapper): WA_StyleSheetTarget = ... # type: Qt.WidgetAttribute class WindowState(int): + def __or__ (self, other: 'Qt.WindowState') -> 'Qt.WindowStates': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.WindowStates': ... # type: ignore[override, misc] + WindowNoState = ... # type: Qt.WindowState WindowMinimized = ... # type: Qt.WindowState WindowMaximized = ... # type: Qt.WindowState @@ -2377,6 +2423,9 @@ class Qt(sip.simplewrapper): WindowActive = ... # type: Qt.WindowState class WindowType(int): + def __or__ (self, other: 'Qt.WindowType') -> 'Qt.WindowFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.WindowFlags': ... # type: ignore[override, misc] + Widget = ... # type: Qt.WindowType Window = ... # type: Qt.WindowType Dialog = ... # type: Qt.WindowType @@ -2490,6 +2539,10 @@ class Qt(sip.simplewrapper): TextJustificationForced = ... # type: Qt.TextFlag class AlignmentFlag(int): + def __or__ (self, other: 'Qt.AlignmentFlag') -> 'Qt.Alignment': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.Alignment': ... # type: ignore[override, misc] + + AlignLeft = ... # type: Qt.AlignmentFlag AlignLeading = ... # type: Qt.AlignmentFlag AlignRight = ... # type: Qt.AlignmentFlag @@ -2541,6 +2594,9 @@ class Qt(sip.simplewrapper): WheelFocus = ... # type: Qt.FocusPolicy class Orientation(int): + def __or__ (self, other: 'Qt.Orientation') -> 'Qt.Orientations': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.Orientations': ... # type: ignore[override, misc] + Horizontal = ... # type: Qt.Orientation Vertical = ... # type: Qt.Orientation @@ -2548,6 +2604,9 @@ class Qt(sip.simplewrapper): Vertical = ... # type: Qt.Orientation class MouseButton(int): + def __or__ (self, other: 'Qt.MouseButton') -> 'Qt.MouseButtons': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.MouseButtons': ... # type: ignore[override, misc] + NoButton = ... # type: Qt.MouseButton AllButtons = ... # type: Qt.MouseButton LeftButton = ... # type: Qt.MouseButton @@ -2636,6 +2695,9 @@ class Qt(sip.simplewrapper): UNICODE_ACCEL = ... # type: Qt.Modifier class KeyboardModifier(int): + def __or__ (self, other: 'Qt.KeyboardModifier') -> 'Qt.KeyboardModifiers': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'Qt.KeyboardModifiers': ... # type: ignore[override, misc] + NoModifier = ... # type: Qt.KeyboardModifier ShiftModifier = ... # type: Qt.KeyboardModifier ControlModifier = ... # type: Qt.KeyboardModifier @@ -2705,12 +2767,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.KeyboardModifiers') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.KeyboardModifiers': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier', int]) -> 'Qt.KeyboardModifiers': ... + def __and__(self, other: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier', int]) -> 'Qt.KeyboardModifiers': ... + def __xor__(self, other: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier', int]) -> 'Qt.KeyboardModifiers': ... + def __ror__ (self, other: 'Qt.KeyboardModifier') -> 'Qt.KeyboardModifiers': ... + def __rand__(self, other: 'Qt.KeyboardModifier') -> 'Qt.KeyboardModifiers': ... + def __rxor__(self, other: 'Qt.KeyboardModifier') -> 'Qt.KeyboardModifiers': ... class MouseButtons(sip.simplewrapper): @@ -2720,12 +2790,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.MouseButtons', 'Qt.MouseButton']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.MouseButtons') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.MouseButtons': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.MouseButtons', 'Qt.MouseButton', int]) -> 'Qt.MouseButtons': ... + def __and__(self, other: typing.Union['Qt.MouseButtons', 'Qt.MouseButton', int]) -> 'Qt.MouseButtons': ... + def __xor__(self, other: typing.Union['Qt.MouseButtons', 'Qt.MouseButton', int]) -> 'Qt.MouseButtons': ... + def __ror__ (self, other: 'Qt.MouseButton') -> 'Qt.MouseButtons': ... + def __rand__(self, other: 'Qt.MouseButton') -> 'Qt.MouseButtons': ... + def __rxor__(self, other: 'Qt.MouseButton') -> 'Qt.MouseButtons': ... class Orientations(sip.simplewrapper): @@ -2735,19 +2813,27 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.Orientations', 'Qt.Orientation']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.Orientations') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.Orientations': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.Orientations', 'Qt.Orientation', int]) -> 'Qt.Orientations': ... + def __and__(self, other: typing.Union['Qt.Orientations', 'Qt.Orientation', int]) -> 'Qt.Orientations': ... + def __xor__(self, other: typing.Union['Qt.Orientations', 'Qt.Orientation', int]) -> 'Qt.Orientations': ... + def __ror__ (self, other: 'Qt.Orientation') -> 'Qt.Orientations': ... + def __rand__(self, other: 'Qt.Orientation') -> 'Qt.Orientations': ... + def __rxor__(self, other: 'Qt.Orientation') -> 'Qt.Orientations': ... class Alignment(sip.simplewrapper): @typing.overload def __init__(self) -> None: ... @typing.overload - def __init__(self, f: typing.Union['Qt.Alignment', 'Qt.AlignmentFlag']) -> None: ... + def __init__(self, f: typing.Union['Qt.Alignment', 'Qt.AlignmentFlag', int]) -> None: ... @typing.overload def __init__(self, a0: 'Qt.Alignment') -> None: ... @@ -2756,13 +2842,19 @@ class Qt(sip.simplewrapper): def __invert__(self) -> 'Qt.Alignment': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.Alignment', 'Qt.AlignmentFlag', int]) -> 'Qt.Alignment': ... + def __and__(self, other: typing.Union['Qt.Alignment', 'Qt.AlignmentFlag', int]) -> 'Qt.Alignment': ... + def __xor__(self, other: typing.Union['Qt.Alignment', 'Qt.AlignmentFlag', int]) -> 'Qt.Alignment': ... + def __ror__ (self, other: 'Qt.AlignmentFlag') -> 'Qt.Alignment': ... + def __rand__(self, other: 'Qt.AlignmentFlag') -> 'Qt.Alignment': ... + def __rxor__(self, other: 'Qt.AlignmentFlag') -> 'Qt.Alignment': ... class WindowFlags(sip.simplewrapper): @typing.overload def __init__(self) -> None: ... @typing.overload - def __init__(self, f: typing.Union['Qt.WindowFlags', 'Qt.WindowType']) -> None: ... + def __init__(self, f: typing.Union['Qt.WindowFlags', 'Qt.WindowType', int]) -> None: ... @typing.overload def __init__(self, a0: 'Qt.WindowFlags') -> None: ... @@ -2771,6 +2863,12 @@ class Qt(sip.simplewrapper): def __invert__(self) -> 'Qt.WindowFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.WindowFlags', 'Qt.WindowType', int]) -> 'Qt.WindowFlags': ... + def __and__(self, other: typing.Union['Qt.WindowFlags', 'Qt.WindowType', int]) -> 'Qt.WindowFlags': ... + def __xor__(self, other: typing.Union['Qt.WindowFlags', 'Qt.WindowType', int]) -> 'Qt.WindowFlags': ... + def __ror__ (self, other: 'Qt.WindowType') -> 'Qt.WindowFlags': ... + def __rand__(self, other: 'Qt.WindowType') -> 'Qt.WindowFlags': ... + def __rxor__(self, other: 'Qt.WindowType') -> 'Qt.WindowFlags': ... class WindowStates(sip.simplewrapper): @@ -2780,12 +2878,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.WindowStates', 'Qt.WindowState']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.WindowStates') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.WindowStates': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.WindowStates', 'Qt.WindowState', int]) -> 'Qt.WindowStates': ... + def __and__(self, other: typing.Union['Qt.WindowStates', 'Qt.WindowState', int]) -> 'Qt.WindowStates': ... + def __xor__(self, other: typing.Union['Qt.WindowStates', 'Qt.WindowState', int]) -> 'Qt.WindowStates': ... + def __ror__ (self, other: 'Qt.WindowState') -> 'Qt.WindowStates': ... + def __rand__(self, other: 'Qt.WindowState') -> 'Qt.WindowStates': ... + def __rxor__(self, other: 'Qt.WindowState') -> 'Qt.WindowStates': ... class ImageConversionFlags(sip.simplewrapper): @@ -2795,12 +2901,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.ImageConversionFlags', 'Qt.ImageConversionFlag']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.ImageConversionFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.ImageConversionFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.ImageConversionFlags', 'Qt.ImageConversionFlag', int]) -> 'Qt.ImageConversionFlags': ... + def __and__(self, other: typing.Union['Qt.ImageConversionFlags', 'Qt.ImageConversionFlag', int]) -> 'Qt.ImageConversionFlags': ... + def __xor__(self, other: typing.Union['Qt.ImageConversionFlags', 'Qt.ImageConversionFlag', int]) -> 'Qt.ImageConversionFlags': ... + def __ror__ (self, other: 'Qt.ImageConversionFlag') -> 'Qt.ImageConversionFlags': ... + def __rand__(self, other: 'Qt.ImageConversionFlag') -> 'Qt.ImageConversionFlags': ... + def __rxor__(self, other: 'Qt.ImageConversionFlag') -> 'Qt.ImageConversionFlags': ... class DockWidgetAreas(sip.simplewrapper): @@ -2810,12 +2924,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.DockWidgetAreas', 'Qt.DockWidgetArea']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.DockWidgetAreas') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.DockWidgetAreas': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.DockWidgetAreas', 'Qt.DockWidgetArea', int]) -> 'Qt.DockWidgetAreas': ... + def __and__(self, other: typing.Union['Qt.DockWidgetAreas', 'Qt.DockWidgetArea', int]) -> 'Qt.DockWidgetAreas': ... + def __xor__(self, other: typing.Union['Qt.DockWidgetAreas', 'Qt.DockWidgetArea', int]) -> 'Qt.DockWidgetAreas': ... + def __ror__ (self, other: 'Qt.DockWidgetArea') -> 'Qt.DockWidgetAreas': ... + def __rand__(self, other: 'Qt.DockWidgetArea') -> 'Qt.DockWidgetAreas': ... + def __rxor__(self, other: 'Qt.DockWidgetArea') -> 'Qt.DockWidgetAreas': ... class ToolBarAreas(sip.simplewrapper): @@ -2825,12 +2947,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.ToolBarAreas', 'Qt.ToolBarArea']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.ToolBarAreas') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.ToolBarAreas': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.ToolBarAreas', 'Qt.ToolBarArea', int]) -> 'Qt.ToolBarAreas': ... + def __and__(self, other: typing.Union['Qt.ToolBarAreas', 'Qt.ToolBarArea', int]) -> 'Qt.ToolBarAreas': ... + def __xor__(self, other: typing.Union['Qt.ToolBarAreas', 'Qt.ToolBarArea', int]) -> 'Qt.ToolBarAreas': ... + def __ror__ (self, other: 'Qt.ToolBarArea') -> 'Qt.ToolBarAreas': ... + def __rand__(self, other: 'Qt.ToolBarArea') -> 'Qt.ToolBarAreas': ... + def __rxor__(self, other: 'Qt.ToolBarArea') -> 'Qt.ToolBarAreas': ... class InputMethodQueries(sip.simplewrapper): @@ -2840,12 +2970,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.InputMethodQueries', 'Qt.InputMethodQuery']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.InputMethodQueries') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.InputMethodQueries': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.InputMethodQueries', 'Qt.InputMethodQuery', int]) -> 'Qt.InputMethodQueries': ... + def __and__(self, other: typing.Union['Qt.InputMethodQueries', 'Qt.InputMethodQuery', int]) -> 'Qt.InputMethodQueries': ... + def __xor__(self, other: typing.Union['Qt.InputMethodQueries', 'Qt.InputMethodQuery', int]) -> 'Qt.InputMethodQueries': ... + def __ror__ (self, other: 'Qt.InputMethodQuery') -> 'Qt.InputMethodQueries': ... + def __rand__(self, other: 'Qt.InputMethodQuery') -> 'Qt.InputMethodQueries': ... + def __rxor__(self, other: 'Qt.InputMethodQuery') -> 'Qt.InputMethodQueries': ... class DropActions(sip.simplewrapper): @@ -2855,12 +2993,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.DropActions', 'Qt.DropAction']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.DropActions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.DropActions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.DropActions', 'Qt.DropAction', int]) -> 'Qt.DropActions': ... + def __and__(self, other: typing.Union['Qt.DropActions', 'Qt.DropAction', int]) -> 'Qt.DropActions': ... + def __xor__(self, other: typing.Union['Qt.DropActions', 'Qt.DropAction', int]) -> 'Qt.DropActions': ... + def __ror__ (self, other: 'Qt.DropAction') -> 'Qt.DropActions': ... + def __rand__(self, other: 'Qt.DropAction') -> 'Qt.DropActions': ... + def __rxor__(self, other: 'Qt.DropAction') -> 'Qt.DropActions': ... class ItemFlags(sip.simplewrapper): @@ -2870,12 +3016,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.ItemFlags', 'Qt.ItemFlag']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.ItemFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.ItemFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.ItemFlags', 'Qt.ItemFlag', int]) -> 'Qt.ItemFlags': ... + def __and__(self, other: typing.Union['Qt.ItemFlags', 'Qt.ItemFlag', int]) -> 'Qt.ItemFlags': ... + def __xor__(self, other: typing.Union['Qt.ItemFlags', 'Qt.ItemFlag', int]) -> 'Qt.ItemFlags': ... + def __ror__ (self, other: 'Qt.ItemFlag') -> 'Qt.ItemFlags': ... + def __rand__(self, other: 'Qt.ItemFlag') -> 'Qt.ItemFlags': ... + def __rxor__(self, other: 'Qt.ItemFlag') -> 'Qt.ItemFlags': ... class MatchFlags(sip.simplewrapper): @@ -2885,12 +3039,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.MatchFlags', 'Qt.MatchFlag']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.MatchFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.MatchFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.MatchFlags', 'Qt.MatchFlag', int]) -> 'Qt.MatchFlags': ... + def __and__(self, other: typing.Union['Qt.MatchFlags', 'Qt.MatchFlag', int]) -> 'Qt.MatchFlags': ... + def __xor__(self, other: typing.Union['Qt.MatchFlags', 'Qt.MatchFlag', int]) -> 'Qt.MatchFlags': ... + def __ror__ (self, other: 'Qt.MatchFlag') -> 'Qt.MatchFlags': ... + def __rand__(self, other: 'Qt.MatchFlag') -> 'Qt.MatchFlags': ... + def __rxor__(self, other: 'Qt.MatchFlag') -> 'Qt.MatchFlags': ... class TextInteractionFlags(sip.simplewrapper): @@ -2900,12 +3062,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.TextInteractionFlags', 'Qt.TextInteractionFlag']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.TextInteractionFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.TextInteractionFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.TextInteractionFlags', 'Qt.TextInteractionFlag', int]) -> 'Qt.TextInteractionFlags': ... + def __and__(self, other: typing.Union['Qt.TextInteractionFlags', 'Qt.TextInteractionFlag', int]) -> 'Qt.TextInteractionFlags': ... + def __xor__(self, other: typing.Union['Qt.TextInteractionFlags', 'Qt.TextInteractionFlag', int]) -> 'Qt.TextInteractionFlags': ... + def __ror__ (self, other: 'Qt.TextInteractionFlag') -> 'Qt.TextInteractionFlags': ... + def __rand__(self, other: 'Qt.TextInteractionFlag') -> 'Qt.TextInteractionFlags': ... + def __rxor__(self, other: 'Qt.TextInteractionFlag') -> 'Qt.TextInteractionFlags': ... class InputMethodHints(sip.simplewrapper): @@ -2915,12 +3085,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.InputMethodHints', 'Qt.InputMethodHint']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.InputMethodHints') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.InputMethodHints': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.InputMethodHints', 'Qt.InputMethodHint', int]) -> 'Qt.InputMethodHints': ... + def __and__(self, other: typing.Union['Qt.InputMethodHints', 'Qt.InputMethodHint', int]) -> 'Qt.InputMethodHints': ... + def __xor__(self, other: typing.Union['Qt.InputMethodHints', 'Qt.InputMethodHint', int]) -> 'Qt.InputMethodHints': ... + def __ror__ (self, other: 'Qt.InputMethodHint') -> 'Qt.InputMethodHints': ... + def __rand__(self, other: 'Qt.InputMethodHint') -> 'Qt.InputMethodHints': ... + def __rxor__(self, other: 'Qt.InputMethodHint') -> 'Qt.InputMethodHints': ... class TouchPointStates(sip.simplewrapper): @@ -2930,12 +3108,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.TouchPointStates', 'Qt.TouchPointState']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.TouchPointStates') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.TouchPointStates': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.TouchPointStates', 'Qt.TouchPointState', int]) -> 'Qt.TouchPointStates': ... + def __and__(self, other: typing.Union['Qt.TouchPointStates', 'Qt.TouchPointState', int]) -> 'Qt.TouchPointStates': ... + def __xor__(self, other: typing.Union['Qt.TouchPointStates', 'Qt.TouchPointState', int]) -> 'Qt.TouchPointStates': ... + def __ror__ (self, other: 'Qt.TouchPointState') -> 'Qt.TouchPointStates': ... + def __rand__(self, other: 'Qt.TouchPointState') -> 'Qt.TouchPointStates': ... + def __rxor__(self, other: 'Qt.TouchPointState') -> 'Qt.TouchPointStates': ... class GestureFlags(sip.simplewrapper): @@ -2945,12 +3131,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.GestureFlags', 'Qt.GestureFlag']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.GestureFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.GestureFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.GestureFlags', 'Qt.GestureFlag', int]) -> 'Qt.GestureFlags': ... + def __and__(self, other: typing.Union['Qt.GestureFlags', 'Qt.GestureFlag', int]) -> 'Qt.GestureFlags': ... + def __xor__(self, other: typing.Union['Qt.GestureFlags', 'Qt.GestureFlag', int]) -> 'Qt.GestureFlags': ... + def __ror__ (self, other: 'Qt.GestureFlag') -> 'Qt.GestureFlags': ... + def __rand__(self, other: 'Qt.GestureFlag') -> 'Qt.GestureFlags': ... + def __rxor__(self, other: 'Qt.GestureFlag') -> 'Qt.GestureFlags': ... class ScreenOrientations(sip.simplewrapper): @@ -2960,12 +3154,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.ScreenOrientations', 'Qt.ScreenOrientation']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.ScreenOrientations') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.ScreenOrientations': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.ScreenOrientations', 'Qt.ScreenOrientation', int]) -> 'Qt.ScreenOrientations': ... + def __and__(self, other: typing.Union['Qt.ScreenOrientations', 'Qt.ScreenOrientation', int]) -> 'Qt.ScreenOrientations': ... + def __xor__(self, other: typing.Union['Qt.ScreenOrientations', 'Qt.ScreenOrientation', int]) -> 'Qt.ScreenOrientations': ... + def __ror__ (self, other: 'Qt.ScreenOrientation') -> 'Qt.ScreenOrientations': ... + def __rand__(self, other: 'Qt.ScreenOrientation') -> 'Qt.ScreenOrientations': ... + def __rxor__(self, other: 'Qt.ScreenOrientation') -> 'Qt.ScreenOrientations': ... class FindChildOptions(sip.simplewrapper): @@ -2975,12 +3177,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.FindChildOptions', 'Qt.FindChildOption']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.FindChildOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.FindChildOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.FindChildOptions', 'Qt.FindChildOption', int]) -> 'Qt.FindChildOptions': ... + def __and__(self, other: typing.Union['Qt.FindChildOptions', 'Qt.FindChildOption', int]) -> 'Qt.FindChildOptions': ... + def __xor__(self, other: typing.Union['Qt.FindChildOptions', 'Qt.FindChildOption', int]) -> 'Qt.FindChildOptions': ... + def __ror__ (self, other: 'Qt.FindChildOption') -> 'Qt.FindChildOptions': ... + def __rand__(self, other: 'Qt.FindChildOption') -> 'Qt.FindChildOptions': ... + def __rxor__(self, other: 'Qt.FindChildOption') -> 'Qt.FindChildOptions': ... class ApplicationStates(sip.simplewrapper): @@ -2990,12 +3200,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.ApplicationStates', 'Qt.ApplicationState']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.ApplicationStates') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.ApplicationStates': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.ApplicationStates', 'Qt.ApplicationState', int]) -> 'Qt.ApplicationStates': ... + def __and__(self, other: typing.Union['Qt.ApplicationStates', 'Qt.ApplicationState', int]) -> 'Qt.ApplicationStates': ... + def __xor__(self, other: typing.Union['Qt.ApplicationStates', 'Qt.ApplicationState', int]) -> 'Qt.ApplicationStates': ... + def __ror__ (self, other: 'Qt.ApplicationState') -> 'Qt.ApplicationStates': ... + def __rand__(self, other: 'Qt.ApplicationState') -> 'Qt.ApplicationStates': ... + def __rxor__(self, other: 'Qt.ApplicationState') -> 'Qt.ApplicationStates': ... class Edges(sip.simplewrapper): @@ -3005,12 +3223,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.Edges', 'Qt.Edge']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.Edges') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.Edges': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.Edges', 'Qt.Edge', int]) -> 'Qt.Edges': ... + def __and__(self, other: typing.Union['Qt.Edges', 'Qt.Edge', int]) -> 'Qt.Edges': ... + def __xor__(self, other: typing.Union['Qt.Edges', 'Qt.Edge', int]) -> 'Qt.Edges': ... + def __ror__ (self, other: 'Qt.Edge') -> 'Qt.Edges': ... + def __rand__(self, other: 'Qt.Edge') -> 'Qt.Edges': ... + def __rxor__(self, other: 'Qt.Edge') -> 'Qt.Edges': ... class MouseEventFlags(sip.simplewrapper): @@ -3020,12 +3246,20 @@ class Qt(sip.simplewrapper): def __init__(self, f: typing.Union['Qt.MouseEventFlags', 'Qt.MouseEventFlag']) -> None: ... @typing.overload def __init__(self, a0: 'Qt.MouseEventFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'Qt.MouseEventFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['Qt.MouseEventFlags', 'Qt.MouseEventFlag', int]) -> 'Qt.MouseEventFlags': ... + def __and__(self, other: typing.Union['Qt.MouseEventFlags', 'Qt.MouseEventFlag', int]) -> 'Qt.MouseEventFlags': ... + def __xor__(self, other: typing.Union['Qt.MouseEventFlags', 'Qt.MouseEventFlag', int]) -> 'Qt.MouseEventFlags': ... + def __ror__ (self, other: 'Qt.MouseEventFlag') -> 'Qt.MouseEventFlags': ... + def __rand__(self, other: 'Qt.MouseEventFlag') -> 'Qt.MouseEventFlags': ... + def __rxor__(self, other: 'Qt.MouseEventFlag') -> 'Qt.MouseEventFlags': ... def convertFromPlainText(self, plain: str, mode: QtCore.Qt.WhiteSpaceMode = ...) -> str: ... def mightBeRichText(self, a0: str) -> bool: ... @@ -3243,6 +3477,9 @@ class QPersistentModelIndex(sip.simplewrapper): class QAbstractItemModel(QObject): class CheckIndexOption(int): + def __or__ (self, other: 'QAbstractItemModel.CheckIndexOption') -> int: ... # type: ignore[override] + def __ror__ (self, other: int) -> int: ... + NoOption = ... # type: QAbstractItemModel.CheckIndexOption IndexIsValid = ... # type: QAbstractItemModel.CheckIndexOption DoNotUseParent = ... # type: QAbstractItemModel.CheckIndexOption @@ -3270,12 +3507,20 @@ class QAbstractItemModel(QObject): def __init__(self, f: typing.Union['QAbstractItemModel.CheckIndexOptions', 'QAbstractItemModel.CheckIndexOption']) -> None: ... @typing.overload def __init__(self, a0: 'QAbstractItemModel.CheckIndexOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QAbstractItemModel.CheckIndexOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QAbstractItemModel.CheckIndexOptions', 'QAbstractItemModel.CheckIndexOption', int]) -> 'QAbstractItemModel.CheckIndexOptions': ... + def __and__(self, other: typing.Union['QAbstractItemModel.CheckIndexOptions', 'QAbstractItemModel.CheckIndexOption', int]) -> 'QAbstractItemModel.CheckIndexOptions': ... + def __xor__(self, other: typing.Union['QAbstractItemModel.CheckIndexOptions', 'QAbstractItemModel.CheckIndexOption', int]) -> 'QAbstractItemModel.CheckIndexOptions': ... + def __ror__ (self, other: 'QAbstractItemModel.CheckIndexOption') -> 'QAbstractItemModel.CheckIndexOptions': ... + def __rand__(self, other: 'QAbstractItemModel.CheckIndexOption') -> 'QAbstractItemModel.CheckIndexOptions': ... + def __rxor__(self, other: 'QAbstractItemModel.CheckIndexOption') -> 'QAbstractItemModel.CheckIndexOptions': ... def __init__(self, parent: typing.Optional[QObject] = ...) -> None: ... @@ -3553,6 +3798,9 @@ class QBitArray(sip.simplewrapper): class QIODevice(QObject): class OpenModeFlag(int): + def __or__ (self, other: 'QIODevice.OpenModeFlag') -> 'QIODevice.OpenMode': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QIODevice.OpenMode': ... # type: ignore[override, misc] + NotOpen = ... # type: QIODevice.OpenModeFlag ReadOnly = ... # type: QIODevice.OpenModeFlag WriteOnly = ... # type: QIODevice.OpenModeFlag @@ -3564,8 +3812,6 @@ class QIODevice(QObject): NewOnly = ... # type: QIODevice.OpenModeFlag ExistingOnly = ... # type: QIODevice.OpenModeFlag - def __or__(self, other: typing.Union['QIODevice.OpenModeFlag', 'QIODevice.OpenMode']) -> 'QIODevice.OpenModeFlag': ... #type: ignore[override] - NotOpen = ... # type: QIODevice.OpenModeFlag ReadOnly = ... # type: QIODevice.OpenModeFlag WriteOnly = ... # type: QIODevice.OpenModeFlag @@ -3584,19 +3830,19 @@ class QIODevice(QObject): @typing.overload def __init__(self, f: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag']) -> None: ... @typing.overload - def __init__(self, a0: 'QIODevice.OpenMode') -> None: ... + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QIODevice.OpenMode': ... def __index__(self) -> int: ... def __int__(self) -> int: ... - def __and__(self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag']) -> 'QIODevice.OpenMode': ... - def __iand__(self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag']) -> 'QIODevice.OpenMode': ... - def __or__(self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag']) -> 'QIODevice.OpenMode': ... - def __ior__(self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag']) -> 'QIODevice.OpenMode': ... - def __xor__(self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag']) -> 'QIODevice.OpenMode': ... - def __ixor__(self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag']) -> 'QIODevice.OpenMode': ... + def __or__ (self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag', int]) -> 'QIODevice.OpenMode': ... + def __and__(self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag', int]) -> 'QIODevice.OpenMode': ... + def __xor__(self, other: typing.Union['QIODevice.OpenMode', 'QIODevice.OpenModeFlag', int]) -> 'QIODevice.OpenMode': ... + def __ror__ (self, other: 'QIODevice.OpenModeFlag') -> 'QIODevice.OpenMode': ... + def __rand__(self, other: 'QIODevice.OpenModeFlag') -> 'QIODevice.OpenMode': ... + def __rxor__(self, other: 'QIODevice.OpenModeFlag') -> 'QIODevice.OpenMode': ... @typing.overload def __init__(self) -> None: ... @@ -3696,6 +3942,9 @@ class QByteArray(sip.simplewrapper): IllegalPadding = ... # type: QByteArray.Base64DecodingStatus class Base64Option(int): + def __or__ (self, other: 'QByteArray.Base64Option') -> 'QByteArray.Base64Options': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QByteArray.Base64Options': ... # type: ignore[override, misc] + Base64Encoding = ... # type: QByteArray.Base64Option Base64UrlEncoding = ... # type: QByteArray.Base64Option KeepTrailingEquals = ... # type: QByteArray.Base64Option @@ -3718,12 +3967,20 @@ class QByteArray(sip.simplewrapper): def __init__(self, f: typing.Union['QByteArray.Base64Options', 'QByteArray.Base64Option']) -> None: ... @typing.overload def __init__(self, a0: 'QByteArray.Base64Options') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QByteArray.Base64Options': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QByteArray.Base64Options', 'QByteArray.Base64Option', int]) -> 'QByteArray.Base64Options': ... + def __and__(self, other: typing.Union['QByteArray.Base64Options', 'QByteArray.Base64Option', int]) -> 'QByteArray.Base64Options': ... + def __xor__(self, other: typing.Union['QByteArray.Base64Options', 'QByteArray.Base64Option', int]) -> 'QByteArray.Base64Options': ... + def __ror__ (self, other: 'QByteArray.Base64Option') -> 'QByteArray.Base64Options': ... + def __rand__(self, other: 'QByteArray.Base64Option') -> 'QByteArray.Base64Options': ... + def __rxor__(self, other: 'QByteArray.Base64Option') -> 'QByteArray.Base64Options': ... class FromBase64Result(sip.simplewrapper): @@ -4177,6 +4434,9 @@ class QCollator(sip.simplewrapper): class QCommandLineOption(sip.simplewrapper): class Flag(int): + def __or__ (self, other: 'QCommandLineOption.Flag') -> 'QCommandLineOption.Flags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QCommandLineOption.Flags': ... # type: ignore[override, misc] + HiddenFromHelp = ... # type: QCommandLineOption.Flag ShortOptionStyle = ... # type: QCommandLineOption.Flag @@ -4191,12 +4451,20 @@ class QCommandLineOption(sip.simplewrapper): def __init__(self, f: typing.Union['QCommandLineOption.Flags', 'QCommandLineOption.Flag']) -> None: ... @typing.overload def __init__(self, a0: 'QCommandLineOption.Flags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QCommandLineOption.Flags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QCommandLineOption.Flags', 'QCommandLineOption.Flag', int]) -> 'QCommandLineOption.Flags': ... + def __and__(self, other: typing.Union['QCommandLineOption.Flags', 'QCommandLineOption.Flag', int]) -> 'QCommandLineOption.Flags': ... + def __xor__(self, other: typing.Union['QCommandLineOption.Flags', 'QCommandLineOption.Flag', int]) -> 'QCommandLineOption.Flags': ... + def __ror__ (self, other: 'QCommandLineOption.Flag') -> 'QCommandLineOption.Flags': ... + def __rand__(self, other: 'QCommandLineOption.Flag') -> 'QCommandLineOption.Flags': ... + def __rxor__(self, other: 'QCommandLineOption.Flag') -> 'QCommandLineOption.Flags': ... @typing.overload def __init__(self, name: str) -> None: ... @@ -5282,6 +5550,9 @@ class QDeadlineTimer(sip.simplewrapper): class QDir(sip.simplewrapper): class SortFlag(int): + def __or__ (self, other: 'QDir.SortFlag') -> 'QDir.SortFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDir.SortFlags': ... # type: ignore[override, misc] + Name = ... # type: QDir.SortFlag Time = ... # type: QDir.SortFlag Size = ... # type: QDir.SortFlag @@ -5309,6 +5580,9 @@ class QDir(sip.simplewrapper): NoSort = ... # type: QDir.SortFlag class Filter(int): + def __or__ (self, other: 'QDir.Filter') -> 'QDir.Filters': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDir.Filters': ... # type: ignore[override, misc] + Dirs = ... # type: QDir.Filter Files = ... # type: QDir.Filter Drives = ... # type: QDir.Filter @@ -5359,12 +5633,20 @@ class QDir(sip.simplewrapper): def __init__(self, f: typing.Union['QDir.Filters', 'QDir.Filter']) -> None: ... @typing.overload def __init__(self, a0: 'QDir.Filters') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDir.Filters': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QDir.Filters', 'QDir.Filter', int]) -> 'QDir.Filters': ... + def __and__(self, other: typing.Union['QDir.Filters', 'QDir.Filter', int]) -> 'QDir.Filters': ... + def __xor__(self, other: typing.Union['QDir.Filters', 'QDir.Filter', int]) -> 'QDir.Filters': ... + def __ror__ (self, other: 'QDir.Filter') -> 'QDir.Filters': ... + def __rand__(self, other: 'QDir.Filter') -> 'QDir.Filters': ... + def __rxor__(self, other: 'QDir.Filter') -> 'QDir.Filters': ... class SortFlags(sip.simplewrapper): @@ -5374,12 +5656,20 @@ class QDir(sip.simplewrapper): def __init__(self, f: typing.Union['QDir.SortFlags', 'QDir.SortFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QDir.SortFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDir.SortFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QDir.SortFlags', 'QDir.SortFlag', int]) -> 'QDir.SortFlags': ... + def __and__(self, other: typing.Union['QDir.SortFlags', 'QDir.SortFlag', int]) -> 'QDir.SortFlags': ... + def __xor__(self, other: typing.Union['QDir.SortFlags', 'QDir.SortFlag', int]) -> 'QDir.SortFlags': ... + def __ror__ (self, other: 'QDir.SortFlag') -> 'QDir.SortFlags': ... + def __rand__(self, other: 'QDir.SortFlag') -> 'QDir.SortFlags': ... + def __rxor__(self, other: 'QDir.SortFlag') -> 'QDir.SortFlags': ... @typing.overload def __init__(self, a0: 'QDir') -> None: ... @@ -5491,6 +5781,9 @@ class QDir(sip.simplewrapper): class QDirIterator(sip.simplewrapper): class IteratorFlag(int): + def __or__ (self, other: 'QDirIterator.IteratorFlag') -> 'QDirIterator.IteratorFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDirIterator.IteratorFlags': ... # type: ignore[override, misc] + NoIteratorFlags = ... # type: QDirIterator.IteratorFlag FollowSymlinks = ... # type: QDirIterator.IteratorFlag Subdirectories = ... # type: QDirIterator.IteratorFlag @@ -5507,12 +5800,20 @@ class QDirIterator(sip.simplewrapper): def __init__(self, f: typing.Union['QDirIterator.IteratorFlags', 'QDirIterator.IteratorFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QDirIterator.IteratorFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDirIterator.IteratorFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QDirIterator.IteratorFlags', 'QDirIterator.IteratorFlag', int]) -> 'QDirIterator.IteratorFlags': ... + def __and__(self, other: typing.Union['QDirIterator.IteratorFlags', 'QDirIterator.IteratorFlag', int]) -> 'QDirIterator.IteratorFlags': ... + def __xor__(self, other: typing.Union['QDirIterator.IteratorFlags', 'QDirIterator.IteratorFlag', int]) -> 'QDirIterator.IteratorFlags': ... + def __ror__ (self, other: 'QDirIterator.IteratorFlag') -> 'QDirIterator.IteratorFlags': ... + def __rand__(self, other: 'QDirIterator.IteratorFlag') -> 'QDirIterator.IteratorFlags': ... + def __rxor__(self, other: 'QDirIterator.IteratorFlag') -> 'QDirIterator.IteratorFlags': ... @typing.overload def __init__(self, dir: QDir, flags: 'QDirIterator.IteratorFlags' = ...) -> None: ... @@ -5693,6 +5994,9 @@ class QElapsedTimer(sip.simplewrapper): class QEventLoop(QObject): class ProcessEventsFlag(int): + def __or__ (self, other: 'QEventLoop.ProcessEventsFlag') -> 'QEventLoop.ProcessEventsFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QEventLoop.ProcessEventsFlags': ... # type: ignore[override, misc] + AllEvents = ... # type: QEventLoop.ProcessEventsFlag ExcludeUserInputEvents = ... # type: QEventLoop.ProcessEventsFlag ExcludeSocketNotifiers = ... # type: QEventLoop.ProcessEventsFlag @@ -5713,12 +6017,20 @@ class QEventLoop(QObject): def __init__(self, f: typing.Union['QEventLoop.ProcessEventsFlags', 'QEventLoop.ProcessEventsFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QEventLoop.ProcessEventsFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QEventLoop.ProcessEventsFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QEventLoop.ProcessEventsFlags', 'QEventLoop.ProcessEventsFlag', int]) -> 'QEventLoop.ProcessEventsFlags': ... + def __and__(self, other: typing.Union['QEventLoop.ProcessEventsFlags', 'QEventLoop.ProcessEventsFlag', int]) -> 'QEventLoop.ProcessEventsFlags': ... + def __xor__(self, other: typing.Union['QEventLoop.ProcessEventsFlags', 'QEventLoop.ProcessEventsFlag', int]) -> 'QEventLoop.ProcessEventsFlags': ... + def __ror__ (self, other: 'QEventLoop.ProcessEventsFlag') -> 'QEventLoop.ProcessEventsFlags': ... + def __rand__(self, other: 'QEventLoop.ProcessEventsFlag') -> 'QEventLoop.ProcessEventsFlags': ... + def __rxor__(self, other: 'QEventLoop.ProcessEventsFlag') -> 'QEventLoop.ProcessEventsFlags': ... def __init__(self, parent: typing.Optional[QObject] = ...) -> None: ... @@ -5789,6 +6101,9 @@ class QFileDevice(QIODevice): DontCloseHandle = ... # type: QFileDevice.FileHandleFlag class Permission(int): + def __or__ (self, other: 'QFileDevice.Permission') -> 'QFileDevice.Permissions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QFileDevice.Permissions': ... # type: ignore[override, misc] + ReadOwner = ... # type: QFileDevice.Permission WriteOwner = ... # type: QFileDevice.Permission ExeOwner = ... # type: QFileDevice.Permission @@ -5856,12 +6171,20 @@ class QFileDevice(QIODevice): def __init__(self, f: typing.Union['QFileDevice.Permissions', 'QFileDevice.Permission']) -> None: ... @typing.overload def __init__(self, a0: 'QFileDevice.Permissions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QFileDevice.Permissions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QFileDevice.Permissions', 'QFileDevice.Permission', int]) -> 'QFileDevice.Permissions': ... + def __and__(self, other: typing.Union['QFileDevice.Permissions', 'QFileDevice.Permission', int]) -> 'QFileDevice.Permissions': ... + def __xor__(self, other: typing.Union['QFileDevice.Permissions', 'QFileDevice.Permission', int]) -> 'QFileDevice.Permissions': ... + def __ror__ (self, other: 'QFileDevice.Permission') -> 'QFileDevice.Permissions': ... + def __rand__(self, other: 'QFileDevice.Permission') -> 'QFileDevice.Permissions': ... + def __rxor__(self, other: 'QFileDevice.Permission') -> 'QFileDevice.Permissions': ... class FileHandleFlags(sip.simplewrapper): @@ -5871,12 +6194,20 @@ class QFileDevice(QIODevice): def __init__(self, f: typing.Union['QFileDevice.FileHandleFlags', 'QFileDevice.FileHandleFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QFileDevice.FileHandleFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QFileDevice.FileHandleFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QFileDevice.FileHandleFlags', 'QFileDevice.FileHandleFlag', int]) -> 'QFileDevice.FileHandleFlags': ... + def __and__(self, other: typing.Union['QFileDevice.FileHandleFlags', 'QFileDevice.FileHandleFlag', int]) -> 'QFileDevice.FileHandleFlags': ... + def __xor__(self, other: typing.Union['QFileDevice.FileHandleFlags', 'QFileDevice.FileHandleFlag', int]) -> 'QFileDevice.FileHandleFlags': ... + def __ror__ (self, other: 'QFileDevice.FileHandleFlag') -> 'QFileDevice.FileHandleFlags': ... + def __rand__(self, other: 'QFileDevice.FileHandleFlag') -> 'QFileDevice.FileHandleFlags': ... + def __rxor__(self, other: 'QFileDevice.FileHandleFlag') -> 'QFileDevice.FileHandleFlags': ... def setFileTime(self, newDate: typing.Union[QDateTime, datetime.datetime], fileTime: 'QFileDevice.FileTime') -> bool: ... def fileTime(self, time: 'QFileDevice.FileTime') -> QDateTime: ... @@ -6183,6 +6514,9 @@ class QItemSelectionRange(sip.simplewrapper): class QItemSelectionModel(QObject): class SelectionFlag(int): + def __or__ (self, other: 'QItemSelectionModel.SelectionFlag') -> 'QItemSelectionModel.SelectionFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QItemSelectionModel.SelectionFlags': ... # type: ignore[override, misc] + NoUpdate = ... # type: QItemSelectionModel.SelectionFlag Clear = ... # type: QItemSelectionModel.SelectionFlag Select = ... # type: QItemSelectionModel.SelectionFlag @@ -6215,12 +6549,20 @@ class QItemSelectionModel(QObject): def __init__(self, f: typing.Union['QItemSelectionModel.SelectionFlags', 'QItemSelectionModel.SelectionFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QItemSelectionModel.SelectionFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QItemSelectionModel.SelectionFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QItemSelectionModel.SelectionFlags', 'QItemSelectionModel.SelectionFlag', int]) -> 'QItemSelectionModel.SelectionFlags': ... + def __and__(self, other: typing.Union['QItemSelectionModel.SelectionFlags', 'QItemSelectionModel.SelectionFlag', int]) -> 'QItemSelectionModel.SelectionFlags': ... + def __xor__(self, other: typing.Union['QItemSelectionModel.SelectionFlags', 'QItemSelectionModel.SelectionFlag', int]) -> 'QItemSelectionModel.SelectionFlags': ... + def __ror__ (self, other: 'QItemSelectionModel.SelectionFlag') -> 'QItemSelectionModel.SelectionFlags': ... + def __rand__(self, other: 'QItemSelectionModel.SelectionFlag') -> 'QItemSelectionModel.SelectionFlags': ... + def __rxor__(self, other: 'QItemSelectionModel.SelectionFlag') -> 'QItemSelectionModel.SelectionFlags': ... @typing.overload def __init__(self, model: typing.Optional[QAbstractItemModel] = ...) -> None: ... @@ -6471,6 +6813,9 @@ class QJsonValue(sip.simplewrapper): class QLibrary(QObject): class LoadHint(int): + def __or__ (self, other: 'QLibrary.LoadHint') -> 'QLibrary.LoadHints': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QLibrary.LoadHints': ... # type: ignore[override, misc] + ResolveAllSymbolsHint = ... # type: QLibrary.LoadHint ExportExternalSymbolsHint = ... # type: QLibrary.LoadHint LoadArchiveMemberHint = ... # type: QLibrary.LoadHint @@ -6491,12 +6836,20 @@ class QLibrary(QObject): def __init__(self, f: typing.Union['QLibrary.LoadHints', 'QLibrary.LoadHint']) -> None: ... @typing.overload def __init__(self, a0: 'QLibrary.LoadHints') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QLibrary.LoadHints': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QLibrary.LoadHints', 'QLibrary.LoadHint', int]) -> 'QLibrary.LoadHints': ... + def __and__(self, other: typing.Union['QLibrary.LoadHints', 'QLibrary.LoadHint', int]) -> 'QLibrary.LoadHints': ... + def __xor__(self, other: typing.Union['QLibrary.LoadHints', 'QLibrary.LoadHint', int]) -> 'QLibrary.LoadHints': ... + def __ror__ (self, other: 'QLibrary.LoadHint') -> 'QLibrary.LoadHints': ... + def __rand__(self, other: 'QLibrary.LoadHint') -> 'QLibrary.LoadHints': ... + def __rxor__(self, other: 'QLibrary.LoadHint') -> 'QLibrary.LoadHints': ... @typing.overload def __init__(self, parent: typing.Optional[QObject] = ...) -> None: ... @@ -7027,6 +7380,9 @@ class QLocale(sip.simplewrapper): NarrowFormat = ... # type: QLocale.FormatType class NumberOption(int): + def __or__ (self, other: 'QLocale.NumberOption') -> 'QLocale.NumberOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QLocale.NumberOptions': ... # type: ignore[override, misc] + OmitGroupSeparator = ... # type: QLocale.NumberOption RejectGroupSeparator = ... # type: QLocale.NumberOption DefaultNumberOptions = ... # type: QLocale.NumberOption @@ -8371,12 +8727,20 @@ class QLocale(sip.simplewrapper): def __init__(self, f: typing.Union['QLocale.NumberOptions', 'QLocale.NumberOption']) -> None: ... @typing.overload def __init__(self, a0: 'QLocale.NumberOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QLocale.NumberOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QLocale.NumberOptions', 'QLocale.NumberOption', int]) -> 'QLocale.NumberOptions': ... + def __and__(self, other: typing.Union['QLocale.NumberOptions', 'QLocale.NumberOption', int]) -> 'QLocale.NumberOptions': ... + def __xor__(self, other: typing.Union['QLocale.NumberOptions', 'QLocale.NumberOption', int]) -> 'QLocale.NumberOptions': ... + def __ror__ (self, other: 'QLocale.NumberOption') -> 'QLocale.NumberOptions': ... + def __rand__(self, other: 'QLocale.NumberOption') -> 'QLocale.NumberOptions': ... + def __rxor__(self, other: 'QLocale.NumberOption') -> 'QLocale.NumberOptions': ... class DataSizeFormats(sip.simplewrapper): @@ -8386,12 +8750,20 @@ class QLocale(sip.simplewrapper): def __init__(self, f: typing.Union['QLocale.DataSizeFormats', 'QLocale.DataSizeFormat']) -> None: ... @typing.overload def __init__(self, a0: 'QLocale.DataSizeFormats') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QLocale.DataSizeFormats': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QLocale.DataSizeFormats', 'QLocale.DataSizeFormat', int]) -> 'QLocale.DataSizeFormats': ... + def __and__(self, other: typing.Union['QLocale.DataSizeFormats', 'QLocale.DataSizeFormat', int]) -> 'QLocale.DataSizeFormats': ... + def __xor__(self, other: typing.Union['QLocale.DataSizeFormats', 'QLocale.DataSizeFormat', int]) -> 'QLocale.DataSizeFormats': ... + def __ror__ (self, other: 'QLocale.DataSizeFormat') -> 'QLocale.DataSizeFormats': ... + def __rand__(self, other: 'QLocale.DataSizeFormat') -> 'QLocale.DataSizeFormats': ... + def __rxor__(self, other: 'QLocale.DataSizeFormat') -> 'QLocale.DataSizeFormats': ... @typing.overload def __init__(self) -> None: ... @@ -8780,6 +9152,9 @@ class QMetaClassInfo(sip.simplewrapper): class QMetaType(sip.simplewrapper): class TypeFlag(int): + def __or__ (self, other: 'QMetaType.TypeFlag') -> 'QMetaType.TypeFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QMetaType.TypeFlags': ... # type: ignore[override, misc] + NeedsConstruction = ... # type: QMetaType.TypeFlag NeedsDestruction = ... # type: QMetaType.TypeFlag MovableType = ... # type: QMetaType.TypeFlag @@ -8969,12 +9344,20 @@ class QMetaType(sip.simplewrapper): def __init__(self, f: typing.Union['QMetaType.TypeFlags', 'QMetaType.TypeFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QMetaType.TypeFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QMetaType.TypeFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QMetaType.TypeFlags', 'QMetaType.TypeFlag', int]) -> 'QMetaType.TypeFlags': ... + def __and__(self, other: typing.Union['QMetaType.TypeFlags', 'QMetaType.TypeFlag', int]) -> 'QMetaType.TypeFlags': ... + def __xor__(self, other: typing.Union['QMetaType.TypeFlags', 'QMetaType.TypeFlag', int]) -> 'QMetaType.TypeFlags': ... + def __ror__ (self, other: 'QMetaType.TypeFlag') -> 'QMetaType.TypeFlags': ... + def __rand__(self, other: 'QMetaType.TypeFlag') -> 'QMetaType.TypeFlags': ... + def __rxor__(self, other: 'QMetaType.TypeFlag') -> 'QMetaType.TypeFlags': ... def __init__(self, type: int = ...) -> None: ... @@ -9908,6 +10291,9 @@ class QRegExp(sip.simplewrapper): class QRegularExpression(sip.simplewrapper): class MatchOption(int): + def __or__ (self, other: 'QRegularExpression.MatchOption') -> 'QRegularExpression.MatchOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QRegularExpression.MatchOptions': ... # type: ignore[override, misc] + NoMatchOption = ... # type: QRegularExpression.MatchOption AnchoredMatchOption = ... # type: QRegularExpression.MatchOption DontCheckSubjectStringMatchOption = ... # type: QRegularExpression.MatchOption @@ -9928,6 +10314,9 @@ class QRegularExpression(sip.simplewrapper): NoMatch = ... # type: QRegularExpression.MatchType class PatternOption(int): + def __or__ (self, other: 'QRegularExpression.PatternOption') -> 'QRegularExpression.PatternOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QRegularExpression.PatternOptions': ... # type: ignore[override, misc] + NoPatternOption = ... # type: QRegularExpression.PatternOption CaseInsensitiveOption = ... # type: QRegularExpression.PatternOption DotMatchesEverythingOption = ... # type: QRegularExpression.PatternOption @@ -9958,12 +10347,20 @@ class QRegularExpression(sip.simplewrapper): def __init__(self, f: typing.Union['QRegularExpression.PatternOptions', 'QRegularExpression.PatternOption']) -> None: ... @typing.overload def __init__(self, a0: 'QRegularExpression.PatternOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QRegularExpression.PatternOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QRegularExpression.PatternOptions', 'QRegularExpression.PatternOption', int]) -> 'QRegularExpression.PatternOptions': ... + def __and__(self, other: typing.Union['QRegularExpression.PatternOptions', 'QRegularExpression.PatternOption', int]) -> 'QRegularExpression.PatternOptions': ... + def __xor__(self, other: typing.Union['QRegularExpression.PatternOptions', 'QRegularExpression.PatternOption', int]) -> 'QRegularExpression.PatternOptions': ... + def __ror__ (self, other: 'QRegularExpression.PatternOption') -> 'QRegularExpression.PatternOptions': ... + def __rand__(self, other: 'QRegularExpression.PatternOption') -> 'QRegularExpression.PatternOptions': ... + def __rxor__(self, other: 'QRegularExpression.PatternOption') -> 'QRegularExpression.PatternOptions': ... class MatchOptions(sip.simplewrapper): @@ -9973,12 +10370,20 @@ class QRegularExpression(sip.simplewrapper): def __init__(self, f: typing.Union['QRegularExpression.MatchOptions', 'QRegularExpression.MatchOption']) -> None: ... @typing.overload def __init__(self, a0: 'QRegularExpression.MatchOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QRegularExpression.MatchOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QRegularExpression.MatchOptions', 'QRegularExpression.MatchOption', int]) -> 'QRegularExpression.MatchOptions': ... + def __and__(self, other: typing.Union['QRegularExpression.MatchOptions', 'QRegularExpression.MatchOption', int]) -> 'QRegularExpression.MatchOptions': ... + def __xor__(self, other: typing.Union['QRegularExpression.MatchOptions', 'QRegularExpression.MatchOption', int]) -> 'QRegularExpression.MatchOptions': ... + def __ror__ (self, other: 'QRegularExpression.MatchOption') -> 'QRegularExpression.MatchOptions': ... + def __rand__(self, other: 'QRegularExpression.MatchOption') -> 'QRegularExpression.MatchOptions': ... + def __rxor__(self, other: 'QRegularExpression.MatchOption') -> 'QRegularExpression.MatchOptions': ... @typing.overload def __init__(self) -> None: ... @@ -10550,6 +10955,9 @@ class QSortFilterProxyModel(QAbstractProxyModel): class QStandardPaths(sip.simplewrapper): class LocateOption(int): + def __or__ (self, other: 'QStandardPaths.LocateOption') -> 'QStandardPaths.LocateOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStandardPaths.LocateOptions': ... # type: ignore[override, misc] + LocateFile = ... # type: QStandardPaths.LocateOption LocateDirectory = ... # type: QStandardPaths.LocateOption @@ -10607,12 +11015,20 @@ class QStandardPaths(sip.simplewrapper): def __init__(self, f: typing.Union['QStandardPaths.LocateOptions', 'QStandardPaths.LocateOption']) -> None: ... @typing.overload def __init__(self, a0: 'QStandardPaths.LocateOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStandardPaths.LocateOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStandardPaths.LocateOptions', 'QStandardPaths.LocateOption', int]) -> 'QStandardPaths.LocateOptions': ... + def __and__(self, other: typing.Union['QStandardPaths.LocateOptions', 'QStandardPaths.LocateOption', int]) -> 'QStandardPaths.LocateOptions': ... + def __xor__(self, other: typing.Union['QStandardPaths.LocateOptions', 'QStandardPaths.LocateOption', int]) -> 'QStandardPaths.LocateOptions': ... + def __ror__ (self, other: 'QStandardPaths.LocateOption') -> 'QStandardPaths.LocateOptions': ... + def __rand__(self, other: 'QStandardPaths.LocateOption') -> 'QStandardPaths.LocateOptions': ... + def __rxor__(self, other: 'QStandardPaths.LocateOption') -> 'QStandardPaths.LocateOptions': ... def __init__(self, a0: 'QStandardPaths') -> None: ... @@ -10899,6 +11315,9 @@ class QTextBoundaryFinder(sip.simplewrapper): Sentence = ... # type: QTextBoundaryFinder.BoundaryType class BoundaryReason(int): + def __or__ (self, other: 'QTextBoundaryFinder.BoundaryReason') -> 'QTextBoundaryFinder.BoundaryReasons': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTextBoundaryFinder.BoundaryReasons': ... # type: ignore[override, misc] + NotAtBoundary = ... # type: QTextBoundaryFinder.BoundaryReason SoftHyphen = ... # type: QTextBoundaryFinder.BoundaryReason BreakOpportunity = ... # type: QTextBoundaryFinder.BoundaryReason @@ -10921,12 +11340,20 @@ class QTextBoundaryFinder(sip.simplewrapper): def __init__(self, f: typing.Union['QTextBoundaryFinder.BoundaryReasons', 'QTextBoundaryFinder.BoundaryReason']) -> None: ... @typing.overload def __init__(self, a0: 'QTextBoundaryFinder.BoundaryReasons') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextBoundaryFinder.BoundaryReasons': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextBoundaryFinder.BoundaryReasons', 'QTextBoundaryFinder.BoundaryReason', int]) -> 'QTextBoundaryFinder.BoundaryReasons': ... + def __and__(self, other: typing.Union['QTextBoundaryFinder.BoundaryReasons', 'QTextBoundaryFinder.BoundaryReason', int]) -> 'QTextBoundaryFinder.BoundaryReasons': ... + def __xor__(self, other: typing.Union['QTextBoundaryFinder.BoundaryReasons', 'QTextBoundaryFinder.BoundaryReason', int]) -> 'QTextBoundaryFinder.BoundaryReasons': ... + def __ror__ (self, other: 'QTextBoundaryFinder.BoundaryReason') -> 'QTextBoundaryFinder.BoundaryReasons': ... + def __rand__(self, other: 'QTextBoundaryFinder.BoundaryReason') -> 'QTextBoundaryFinder.BoundaryReasons': ... + def __rxor__(self, other: 'QTextBoundaryFinder.BoundaryReason') -> 'QTextBoundaryFinder.BoundaryReasons': ... @typing.overload def __init__(self) -> None: ... @@ -10951,6 +11378,9 @@ class QTextBoundaryFinder(sip.simplewrapper): class QTextCodec(sip.wrapper): class ConversionFlag(int): + def __or__ (self, other: 'QTextCodec.ConversionFlag') -> 'QTextCodec.ConversionFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTextCodec.ConversionFlags': ... # type: ignore[override, misc] + DefaultConversion = ... # type: QTextCodec.ConversionFlag ConvertInvalidToNull = ... # type: QTextCodec.ConversionFlag IgnoreHeader = ... # type: QTextCodec.ConversionFlag @@ -10967,12 +11397,20 @@ class QTextCodec(sip.wrapper): def __init__(self, f: typing.Union['QTextCodec.ConversionFlags', 'QTextCodec.ConversionFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTextCodec.ConversionFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextCodec.ConversionFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextCodec.ConversionFlags', 'QTextCodec.ConversionFlag', int]) -> 'QTextCodec.ConversionFlags': ... + def __and__(self, other: typing.Union['QTextCodec.ConversionFlags', 'QTextCodec.ConversionFlag', int]) -> 'QTextCodec.ConversionFlags': ... + def __xor__(self, other: typing.Union['QTextCodec.ConversionFlags', 'QTextCodec.ConversionFlag', int]) -> 'QTextCodec.ConversionFlags': ... + def __ror__ (self, other: 'QTextCodec.ConversionFlag') -> 'QTextCodec.ConversionFlags': ... + def __rand__(self, other: 'QTextCodec.ConversionFlag') -> 'QTextCodec.ConversionFlags': ... + def __rxor__(self, other: 'QTextCodec.ConversionFlag') -> 'QTextCodec.ConversionFlags': ... class ConverterState(sip.simplewrapper): @@ -11060,6 +11498,9 @@ class QTextStream(sip.simplewrapper): WriteFailed = ... # type: QTextStream.Status class NumberFlag(int): + def __or__ (self, other: 'QTextStream.NumberFlag') -> 'QTextStream.NumberFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTextStream.NumberFlags': ... # type: ignore[override, misc] + ShowBase = ... # type: QTextStream.NumberFlag ForcePoint = ... # type: QTextStream.NumberFlag ForceSign = ... # type: QTextStream.NumberFlag @@ -11100,12 +11541,20 @@ class QTextStream(sip.simplewrapper): def __init__(self, f: typing.Union['QTextStream.NumberFlags', 'QTextStream.NumberFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTextStream.NumberFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextStream.NumberFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextStream.NumberFlags', 'QTextStream.NumberFlag', int]) -> 'QTextStream.NumberFlags': ... + def __and__(self, other: typing.Union['QTextStream.NumberFlags', 'QTextStream.NumberFlag', int]) -> 'QTextStream.NumberFlags': ... + def __xor__(self, other: typing.Union['QTextStream.NumberFlags', 'QTextStream.NumberFlag', int]) -> 'QTextStream.NumberFlags': ... + def __ror__ (self, other: 'QTextStream.NumberFlag') -> 'QTextStream.NumberFlags': ... + def __rand__(self, other: 'QTextStream.NumberFlag') -> 'QTextStream.NumberFlags': ... + def __rxor__(self, other: 'QTextStream.NumberFlag') -> 'QTextStream.NumberFlags': ... @typing.overload def __init__(self) -> None: ... @@ -11501,6 +11950,9 @@ class QUrl(sip.simplewrapper): AssumeLocalFile = ... # type: QUrl.UserInputResolutionOption class ComponentFormattingOption(int): + def __or__ (self, other: 'QUrl.ComponentFormattingOption') -> 'QUrl.ComponentFormattingOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QUrl.ComponentFormattingOptions': ... # type: ignore[override, misc] + PrettyDecoded = ... # type: QUrl.ComponentFormattingOption EncodeSpaces = ... # type: QUrl.ComponentFormattingOption EncodeUnicode = ... # type: QUrl.ComponentFormattingOption @@ -11520,6 +11972,9 @@ class QUrl(sip.simplewrapper): FullyDecoded = ... # type: QUrl.ComponentFormattingOption class UrlFormattingOption(int): + def __or__(self, other: 'QUrl.UrlFormattingOption') -> 'QUrl.FormattingOptions': ... # type: ignore[override] + def __ror__(self, other: int) -> 'QUrl.FormattingOptions': ... # type: ignore[override, misc] + None_ = ... # type: QUrl.UrlFormattingOption RemoveScheme = ... # type: QUrl.UrlFormattingOption RemovePassword = ... # type: QUrl.UrlFormattingOption @@ -11570,12 +12025,20 @@ class QUrl(sip.simplewrapper): def __init__(self, f: typing.Union['QUrl.ComponentFormattingOptions', 'QUrl.ComponentFormattingOption']) -> None: ... @typing.overload def __init__(self, a0: 'QUrl.ComponentFormattingOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QUrl.ComponentFormattingOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QUrl.ComponentFormattingOptions', 'QUrl.ComponentFormattingOption', int]) -> 'QUrl.ComponentFormattingOptions': ... + def __and__(self, other: typing.Union['QUrl.ComponentFormattingOptions', 'QUrl.ComponentFormattingOption', int]) -> 'QUrl.ComponentFormattingOptions': ... + def __xor__(self, other: typing.Union['QUrl.ComponentFormattingOptions', 'QUrl.ComponentFormattingOption', int]) -> 'QUrl.ComponentFormattingOptions': ... + def __ror__ (self, other: 'QUrl.ComponentFormattingOption') -> 'QUrl.ComponentFormattingOptions': ... + def __rand__(self, other: 'QUrl.ComponentFormattingOption') -> 'QUrl.ComponentFormattingOptions': ... + def __rxor__(self, other: 'QUrl.ComponentFormattingOption') -> 'QUrl.ComponentFormattingOptions': ... class UserInputResolutionOptions(sip.simplewrapper): @@ -11585,12 +12048,20 @@ class QUrl(sip.simplewrapper): def __init__(self, f: typing.Union['QUrl.UserInputResolutionOptions', 'QUrl.UserInputResolutionOption']) -> None: ... @typing.overload def __init__(self, a0: 'QUrl.UserInputResolutionOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QUrl.UserInputResolutionOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QUrl.UserInputResolutionOptions', 'QUrl.UserInputResolutionOption', int]) -> 'QUrl.UserInputResolutionOptions': ... + def __and__(self, other: typing.Union['QUrl.UserInputResolutionOptions', 'QUrl.UserInputResolutionOption', int]) -> 'QUrl.UserInputResolutionOptions': ... + def __xor__(self, other: typing.Union['QUrl.UserInputResolutionOptions', 'QUrl.UserInputResolutionOption', int]) -> 'QUrl.UserInputResolutionOptions': ... + def __ror__ (self, other: 'QUrl.UserInputResolutionOption') -> 'QUrl.UserInputResolutionOptions': ... + def __rand__(self, other: 'QUrl.UserInputResolutionOption') -> 'QUrl.UserInputResolutionOptions': ... + def __rxor__(self, other: 'QUrl.UserInputResolutionOption') -> 'QUrl.UserInputResolutionOptions': ... @typing.overload def __init__(self) -> None: ... diff --git a/PyQt5-stubs/QtDBus.pyi b/PyQt5-stubs/QtDBus.pyi index b9770de6..38e019df 100644 --- a/PyQt5-stubs/QtDBus.pyi +++ b/PyQt5-stubs/QtDBus.pyi @@ -106,6 +106,9 @@ class QDBus(sip.simplewrapper): class QDBusConnection(sip.simplewrapper): class ConnectionCapability(int): + def __or__ (self, other: 'QDBusConnection.ConnectionCapability') -> 'QDBusConnection.ConnectionCapabilities': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDBusConnection.ConnectionCapabilities': ... # type: ignore[override, misc] + UnixFileDescriptorPassing = ... # type: QDBusConnection.ConnectionCapability UnixFileDescriptorPassing = ... # type: QDBusConnection.ConnectionCapability @@ -118,6 +121,9 @@ class QDBusConnection(sip.simplewrapper): UnregisterTree = ... # type: QDBusConnection.UnregisterMode class RegisterOption(int): + def __or__ (self, other: typing.Union[int, 'QDBusConnection.RegisterOption']) -> 'QDBusConnection.RegisterOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDBusConnection.RegisterOptions': ... # type: ignore[override, misc] + ExportAdaptors = ... # type: QDBusConnection.RegisterOption ExportScriptableSlots = ... # type: QDBusConnection.RegisterOption ExportScriptableSignals = ... # type: QDBusConnection.RegisterOption @@ -173,12 +179,20 @@ class QDBusConnection(sip.simplewrapper): def __init__(self, f: typing.Union['QDBusConnection.RegisterOptions', 'QDBusConnection.RegisterOption']) -> None: ... @typing.overload def __init__(self, a0: 'QDBusConnection.RegisterOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDBusConnection.RegisterOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QDBusConnection.RegisterOptions', 'QDBusConnection.RegisterOption', int]) -> 'QDBusConnection.RegisterOptions': ... + def __and__(self, other: typing.Union['QDBusConnection.RegisterOptions', 'QDBusConnection.RegisterOption', int]) -> 'QDBusConnection.RegisterOptions': ... + def __xor__(self, other: typing.Union['QDBusConnection.RegisterOptions', 'QDBusConnection.RegisterOption', int]) -> 'QDBusConnection.RegisterOptions': ... + def __ror__ (self, other: 'QDBusConnection.RegisterOption') -> 'QDBusConnection.RegisterOptions': ... + def __rand__(self, other: 'QDBusConnection.RegisterOption') -> 'QDBusConnection.RegisterOptions': ... + def __rxor__(self, other: 'QDBusConnection.RegisterOption') -> 'QDBusConnection.RegisterOptions': ... class ConnectionCapabilities(sip.simplewrapper): @@ -188,12 +202,20 @@ class QDBusConnection(sip.simplewrapper): def __init__(self, f: typing.Union['QDBusConnection.ConnectionCapabilities', 'QDBusConnection.ConnectionCapability']) -> None: ... @typing.overload def __init__(self, a0: 'QDBusConnection.ConnectionCapabilities') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDBusConnection.ConnectionCapabilities': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QDBusConnection.ConnectionCapabilities', 'QDBusConnection.ConnectionCapability', int]) -> 'QDBusConnection.ConnectionCapabilities': ... + def __and__(self, other: typing.Union['QDBusConnection.ConnectionCapabilities', 'QDBusConnection.ConnectionCapability', int]) -> 'QDBusConnection.ConnectionCapabilities': ... + def __xor__(self, other: typing.Union['QDBusConnection.ConnectionCapabilities', 'QDBusConnection.ConnectionCapability', int]) -> 'QDBusConnection.ConnectionCapabilities': ... + def __ror__ (self, other: 'QDBusConnection.ConnectionCapability') -> 'QDBusConnection.ConnectionCapabilities': ... + def __rand__(self, other: 'QDBusConnection.ConnectionCapability') -> 'QDBusConnection.ConnectionCapabilities': ... + def __rxor__(self, other: 'QDBusConnection.ConnectionCapability') -> 'QDBusConnection.ConnectionCapabilities': ... @typing.overload def __init__(self, name: str) -> None: ... @@ -506,6 +528,9 @@ class QDBusPendingCallWatcher(QtCore.QObject, QDBusPendingCall): class QDBusServiceWatcher(QtCore.QObject): class WatchModeFlag(int): + def __or__ (self, other: typing.Union[int, 'QDBusServiceWatcher.WatchModeFlag']) -> 'QDBusServiceWatcher.WatchMode': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDBusServiceWatcher.WatchMode': ... # type: ignore[override, misc] + WatchForRegistration = ... # type: QDBusServiceWatcher.WatchModeFlag WatchForUnregistration = ... # type: QDBusServiceWatcher.WatchModeFlag WatchForOwnerChange = ... # type: QDBusServiceWatcher.WatchModeFlag @@ -522,12 +547,20 @@ class QDBusServiceWatcher(QtCore.QObject): def __init__(self, f: typing.Union['QDBusServiceWatcher.WatchMode', 'QDBusServiceWatcher.WatchModeFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QDBusServiceWatcher.WatchMode') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDBusServiceWatcher.WatchMode': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QDBusServiceWatcher.WatchMode', 'QDBusServiceWatcher.WatchModeFlag', int]) -> 'QDBusServiceWatcher.WatchMode': ... + def __and__(self, other: typing.Union['QDBusServiceWatcher.WatchMode', 'QDBusServiceWatcher.WatchModeFlag', int]) -> 'QDBusServiceWatcher.WatchMode': ... + def __xor__(self, other: typing.Union['QDBusServiceWatcher.WatchMode', 'QDBusServiceWatcher.WatchModeFlag', int]) -> 'QDBusServiceWatcher.WatchMode': ... + def __ror__ (self, other: 'QDBusServiceWatcher.WatchModeFlag') -> 'QDBusServiceWatcher.WatchMode': ... + def __rand__(self, other: 'QDBusServiceWatcher.WatchModeFlag') -> 'QDBusServiceWatcher.WatchMode': ... + def __rxor__(self, other: 'QDBusServiceWatcher.WatchModeFlag') -> 'QDBusServiceWatcher.WatchMode': ... @typing.overload def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... diff --git a/PyQt5-stubs/QtGui.pyi b/PyQt5-stubs/QtGui.pyi index f7ee5581..954971b8 100644 --- a/PyQt5-stubs/QtGui.pyi +++ b/PyQt5-stubs/QtGui.pyi @@ -1768,6 +1768,9 @@ class QTouchEvent(QInputEvent): class TouchPoint(sip.simplewrapper): class InfoFlag(int): + def __or__ (self, other: typing.Union[int, 'QTouchEvent.TouchPoint.InfoFlag']) -> 'QTouchEvent.TouchPoint.InfoFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTouchEvent.TouchPoint.InfoFlags': ... # type: ignore[override, misc] + Pen = ... # type: QTouchEvent.TouchPoint.InfoFlag Token = ... # type: QTouchEvent.TouchPoint.InfoFlag @@ -1782,12 +1785,20 @@ class QTouchEvent(QInputEvent): def __init__(self, f: typing.Union['QTouchEvent.TouchPoint.InfoFlags', 'QTouchEvent.TouchPoint.InfoFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTouchEvent.TouchPoint.InfoFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTouchEvent.TouchPoint.InfoFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTouchEvent.TouchPoint.InfoFlags', 'QTouchEvent.TouchPoint.InfoFlag', int]) -> 'QTouchEvent.TouchPoint.InfoFlags': ... + def __and__(self, other: typing.Union['QTouchEvent.TouchPoint.InfoFlags', 'QTouchEvent.TouchPoint.InfoFlag', int]) -> 'QTouchEvent.TouchPoint.InfoFlags': ... + def __xor__(self, other: typing.Union['QTouchEvent.TouchPoint.InfoFlags', 'QTouchEvent.TouchPoint.InfoFlag', int]) -> 'QTouchEvent.TouchPoint.InfoFlags': ... + def __ror__ (self, other: 'QTouchEvent.TouchPoint.InfoFlag') -> 'QTouchEvent.TouchPoint.InfoFlags': ... + def __rand__(self, other: 'QTouchEvent.TouchPoint.InfoFlag') -> 'QTouchEvent.TouchPoint.InfoFlags': ... + def __rxor__(self, other: 'QTouchEvent.TouchPoint.InfoFlag') -> 'QTouchEvent.TouchPoint.InfoFlags': ... def ellipseDiameters(self) -> QtCore.QSizeF: ... def rotation(self) -> float: ... @@ -2609,12 +2620,20 @@ class QGlyphRun(sip.simplewrapper): def __init__(self, f: typing.Union['QGlyphRun.GlyphRunFlags', 'QGlyphRun.GlyphRunFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QGlyphRun.GlyphRunFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGlyphRun.GlyphRunFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGlyphRun.GlyphRunFlags', 'QGlyphRun.GlyphRunFlag', int]) -> 'QGlyphRun.GlyphRunFlags': ... + def __and__(self, other: typing.Union['QGlyphRun.GlyphRunFlags', 'QGlyphRun.GlyphRunFlag', int]) -> 'QGlyphRun.GlyphRunFlags': ... + def __xor__(self, other: typing.Union['QGlyphRun.GlyphRunFlags', 'QGlyphRun.GlyphRunFlag', int]) -> 'QGlyphRun.GlyphRunFlags': ... + def __ror__ (self, other: 'QGlyphRun.GlyphRunFlag') -> 'QGlyphRun.GlyphRunFlags': ... + def __rand__(self, other: 'QGlyphRun.GlyphRunFlag') -> 'QGlyphRun.GlyphRunFlags': ... + def __rxor__(self, other: 'QGlyphRun.GlyphRunFlag') -> 'QGlyphRun.GlyphRunFlags': ... @typing.overload def __init__(self) -> None: ... @@ -3200,12 +3219,20 @@ class QImageIOHandler(sip.simplewrapper): def __init__(self, f: typing.Union['QImageIOHandler.Transformations', 'QImageIOHandler.Transformation']) -> None: ... @typing.overload def __init__(self, a0: 'QImageIOHandler.Transformations') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QImageIOHandler.Transformations': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QImageIOHandler.Transformations', 'QImageIOHandler.Transformation', int]) -> 'QImageIOHandler.Transformations': ... + def __and__(self, other: typing.Union['QImageIOHandler.Transformations', 'QImageIOHandler.Transformation', int]) -> 'QImageIOHandler.Transformations': ... + def __xor__(self, other: typing.Union['QImageIOHandler.Transformations', 'QImageIOHandler.Transformation', int]) -> 'QImageIOHandler.Transformations': ... + def __ror__ (self, other: 'QImageIOHandler.Transformation') -> 'QImageIOHandler.Transformations': ... + def __rand__(self, other: 'QImageIOHandler.Transformation') -> 'QImageIOHandler.Transformations': ... + def __rxor__(self, other: 'QImageIOHandler.Transformation') -> 'QImageIOHandler.Transformations': ... def __init__(self) -> None: ... @@ -3813,6 +3840,9 @@ class QOffscreenSurface(QtCore.QObject, QSurface): class QOpenGLBuffer(sip.simplewrapper): class RangeAccessFlag(int): + def __or__ (self, other: 'QOpenGLBuffer.RangeAccessFlag') -> 'QOpenGLBuffer.RangeAccessFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QOpenGLBuffer.RangeAccessFlags': ... # type: ignore[override, misc] + RangeRead = ... # type: QOpenGLBuffer.RangeAccessFlag RangeWrite = ... # type: QOpenGLBuffer.RangeAccessFlag RangeInvalidate = ... # type: QOpenGLBuffer.RangeAccessFlag @@ -3876,12 +3906,20 @@ class QOpenGLBuffer(sip.simplewrapper): def __init__(self, f: typing.Union['QOpenGLBuffer.RangeAccessFlags', 'QOpenGLBuffer.RangeAccessFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QOpenGLBuffer.RangeAccessFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QOpenGLBuffer.RangeAccessFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QOpenGLBuffer.RangeAccessFlags', 'QOpenGLBuffer.RangeAccessFlag', int]) -> 'QOpenGLBuffer.RangeAccessFlags': ... + def __and__(self, other: typing.Union['QOpenGLBuffer.RangeAccessFlags', 'QOpenGLBuffer.RangeAccessFlag', int]) -> 'QOpenGLBuffer.RangeAccessFlags': ... + def __xor__(self, other: typing.Union['QOpenGLBuffer.RangeAccessFlags', 'QOpenGLBuffer.RangeAccessFlag', int]) -> 'QOpenGLBuffer.RangeAccessFlags': ... + def __ror__ (self, other: 'QOpenGLBuffer.RangeAccessFlag') -> 'QOpenGLBuffer.RangeAccessFlags': ... + def __rand__(self, other: 'QOpenGLBuffer.RangeAccessFlag') -> 'QOpenGLBuffer.RangeAccessFlags': ... + def __rxor__(self, other: 'QOpenGLBuffer.RangeAccessFlag') -> 'QOpenGLBuffer.RangeAccessFlags': ... @typing.overload def __init__(self) -> None: ... @@ -3991,6 +4029,9 @@ class QOpenGLVersionProfile(sip.simplewrapper): class QOpenGLDebugMessage(sip.simplewrapper): class Severity(int): + def __or__ (self, other: 'QOpenGLDebugMessage.Severity') -> 'QOpenGLDebugMessage.Severities': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QOpenGLDebugMessage.Severities': ... # type: ignore[override, misc] + InvalidSeverity = ... # type: QOpenGLDebugMessage.Severity HighSeverity = ... # type: QOpenGLDebugMessage.Severity MediumSeverity = ... # type: QOpenGLDebugMessage.Severity @@ -4006,6 +4047,9 @@ class QOpenGLDebugMessage(sip.simplewrapper): AnySeverity = ... # type: QOpenGLDebugMessage.Severity class Type(int): + def __or__ (self, other: 'QOpenGLDebugMessage.Type') -> 'QOpenGLDebugMessage.Types': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QOpenGLDebugMessage.Types': ... # type: ignore[override, misc] + InvalidType = ... # type: QOpenGLDebugMessage.Type ErrorType = ... # type: QOpenGLDebugMessage.Type DeprecatedBehaviorType = ... # type: QOpenGLDebugMessage.Type @@ -4031,6 +4075,9 @@ class QOpenGLDebugMessage(sip.simplewrapper): AnyType = ... # type: QOpenGLDebugMessage.Type class Source(int): + def __or__ (self, other: 'QOpenGLDebugMessage.Source') -> 'QOpenGLDebugMessage.Sources': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QOpenGLDebugMessage.Sources': ... # type: ignore[override, misc] + InvalidSource = ... # type: QOpenGLDebugMessage.Source APISource = ... # type: QOpenGLDebugMessage.Source WindowSystemSource = ... # type: QOpenGLDebugMessage.Source @@ -4057,12 +4104,20 @@ class QOpenGLDebugMessage(sip.simplewrapper): def __init__(self, f: typing.Union['QOpenGLDebugMessage.Sources', 'QOpenGLDebugMessage.Source']) -> None: ... @typing.overload def __init__(self, a0: 'QOpenGLDebugMessage.Sources') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QOpenGLDebugMessage.Sources': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QOpenGLDebugMessage.Sources', 'QOpenGLDebugMessage.Source', int]) -> 'QOpenGLDebugMessage.Sources': ... + def __and__(self, other: typing.Union['QOpenGLDebugMessage.Sources', 'QOpenGLDebugMessage.Source', int]) -> 'QOpenGLDebugMessage.Sources': ... + def __xor__(self, other: typing.Union['QOpenGLDebugMessage.Sources', 'QOpenGLDebugMessage.Source', int]) -> 'QOpenGLDebugMessage.Sources': ... + def __ror__ (self, other: 'QOpenGLDebugMessage.Source') -> 'QOpenGLDebugMessage.Sources': ... + def __rand__(self, other: 'QOpenGLDebugMessage.Source') -> 'QOpenGLDebugMessage.Sources': ... + def __rxor__(self, other: 'QOpenGLDebugMessage.Source') -> 'QOpenGLDebugMessage.Sources': ... class Types(sip.simplewrapper): @@ -4072,12 +4127,20 @@ class QOpenGLDebugMessage(sip.simplewrapper): def __init__(self, f: typing.Union['QOpenGLDebugMessage.Types', 'QOpenGLDebugMessage.Type']) -> None: ... @typing.overload def __init__(self, a0: 'QOpenGLDebugMessage.Types') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QOpenGLDebugMessage.Types': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QOpenGLDebugMessage.Types', 'QOpenGLDebugMessage.Type', int]) -> 'QOpenGLDebugMessage.Types': ... + def __and__(self, other: typing.Union['QOpenGLDebugMessage.Types', 'QOpenGLDebugMessage.Type', int]) -> 'QOpenGLDebugMessage.Types': ... + def __xor__(self, other: typing.Union['QOpenGLDebugMessage.Types', 'QOpenGLDebugMessage.Type', int]) -> 'QOpenGLDebugMessage.Types': ... + def __ror__ (self, other: 'QOpenGLDebugMessage.Type') -> 'QOpenGLDebugMessage.Types': ... + def __rand__(self, other: 'QOpenGLDebugMessage.Type') -> 'QOpenGLDebugMessage.Types': ... + def __rxor__(self, other: 'QOpenGLDebugMessage.Type') -> 'QOpenGLDebugMessage.Types': ... class Severities(sip.simplewrapper): @@ -4087,12 +4150,20 @@ class QOpenGLDebugMessage(sip.simplewrapper): def __init__(self, f: typing.Union['QOpenGLDebugMessage.Severities', 'QOpenGLDebugMessage.Severity']) -> None: ... @typing.overload def __init__(self, a0: 'QOpenGLDebugMessage.Severities') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QOpenGLDebugMessage.Severities': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QOpenGLDebugMessage.Severities', 'QOpenGLDebugMessage.Severity', int]) -> 'QOpenGLDebugMessage.Severities': ... + def __and__(self, other: typing.Union['QOpenGLDebugMessage.Severities', 'QOpenGLDebugMessage.Severity', int]) -> 'QOpenGLDebugMessage.Severities': ... + def __xor__(self, other: typing.Union['QOpenGLDebugMessage.Severities', 'QOpenGLDebugMessage.Severity', int]) -> 'QOpenGLDebugMessage.Severities': ... + def __ror__ (self, other: 'QOpenGLDebugMessage.Severity') -> 'QOpenGLDebugMessage.Severities': ... + def __rand__(self, other: 'QOpenGLDebugMessage.Severity') -> 'QOpenGLDebugMessage.Severities': ... + def __rxor__(self, other: 'QOpenGLDebugMessage.Severity') -> 'QOpenGLDebugMessage.Severities': ... @typing.overload def __init__(self) -> None: ... @@ -4296,6 +4367,9 @@ class QOpenGLPixelTransferOptions(sip.simplewrapper): class QOpenGLShader(QtCore.QObject): class ShaderTypeBit(int): + def __or__ (self, other: 'QOpenGLShader.ShaderTypeBit') -> 'QOpenGLShader.ShaderType': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QOpenGLShader.ShaderType': ... # type: ignore[override, misc] + Vertex = ... # type: QOpenGLShader.ShaderTypeBit Fragment = ... # type: QOpenGLShader.ShaderTypeBit Geometry = ... # type: QOpenGLShader.ShaderTypeBit @@ -4318,12 +4392,20 @@ class QOpenGLShader(QtCore.QObject): def __init__(self, f: typing.Union['QOpenGLShader.ShaderType', 'QOpenGLShader.ShaderTypeBit']) -> None: ... @typing.overload def __init__(self, a0: 'QOpenGLShader.ShaderType') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QOpenGLShader.ShaderType': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QOpenGLShader.ShaderType', 'QOpenGLShader.ShaderTypeBit', int]) -> 'QOpenGLShader.ShaderType': ... + def __and__(self, other: typing.Union['QOpenGLShader.ShaderType', 'QOpenGLShader.ShaderTypeBit', int]) -> 'QOpenGLShader.ShaderType': ... + def __xor__(self, other: typing.Union['QOpenGLShader.ShaderType', 'QOpenGLShader.ShaderTypeBit', int]) -> 'QOpenGLShader.ShaderType': ... + def __ror__ (self, other: 'QOpenGLShader.ShaderTypeBit') -> 'QOpenGLShader.ShaderType': ... + def __rand__(self, other: 'QOpenGLShader.ShaderTypeBit') -> 'QOpenGLShader.ShaderType': ... + def __rxor__(self, other: 'QOpenGLShader.ShaderTypeBit') -> 'QOpenGLShader.ShaderType': ... def __init__(self, type: typing.Union['QOpenGLShader.ShaderType', 'QOpenGLShader.ShaderTypeBit'], parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -4630,6 +4712,9 @@ class QOpenGLTexture(sip.simplewrapper): SwizzleAlpha = ... # type: QOpenGLTexture.SwizzleComponent class Feature(int): + def __or__ (self, other: 'QOpenGLTexture.Feature') -> 'QOpenGLTexture.Features': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QOpenGLTexture.Features': ... # type: ignore[override, misc] + ImmutableStorage = ... # type: QOpenGLTexture.Feature ImmutableMultisampleStorage = ... # type: QOpenGLTexture.Feature TextureRectangle = ... # type: QOpenGLTexture.Feature @@ -5102,12 +5187,20 @@ class QOpenGLTexture(sip.simplewrapper): def __init__(self, f: typing.Union['QOpenGLTexture.Features', 'QOpenGLTexture.Feature']) -> None: ... @typing.overload def __init__(self, a0: 'QOpenGLTexture.Features') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QOpenGLTexture.Features': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QOpenGLTexture.Features', 'QOpenGLTexture.Feature', int]) -> 'QOpenGLTexture.Features': ... + def __and__(self, other: typing.Union['QOpenGLTexture.Features', 'QOpenGLTexture.Feature', int]) -> 'QOpenGLTexture.Features': ... + def __xor__(self, other: typing.Union['QOpenGLTexture.Features', 'QOpenGLTexture.Feature', int]) -> 'QOpenGLTexture.Features': ... + def __ror__ (self, other: 'QOpenGLTexture.Feature') -> 'QOpenGLTexture.Features': ... + def __rand__(self, other: 'QOpenGLTexture.Feature') -> 'QOpenGLTexture.Features': ... + def __rxor__(self, other: 'QOpenGLTexture.Feature') -> 'QOpenGLTexture.Features': ... @typing.overload def __init__(self, target: 'QOpenGLTexture.Target') -> None: ... @@ -6375,6 +6468,9 @@ class QPainter(sip.simplewrapper): RasterOp_NotDestination = ... # type: QPainter.CompositionMode class RenderHint(int): + def __or__ (self, other: 'QPainter.RenderHint') -> 'QPainter.RenderHints': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QPainter.RenderHints': ... # type: ignore[override, misc] + Antialiasing = ... # type: QPainter.RenderHint TextAntialiasing = ... # type: QPainter.RenderHint SmoothPixmapTransform = ... # type: QPainter.RenderHint @@ -6399,12 +6495,20 @@ class QPainter(sip.simplewrapper): def __init__(self, f: typing.Union['QPainter.RenderHints', 'QPainter.RenderHint']) -> None: ... @typing.overload def __init__(self, a0: 'QPainter.RenderHints') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QPainter.RenderHints': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QPainter.RenderHints', 'QPainter.RenderHint', int]) -> 'QPainter.RenderHints': ... + def __and__(self, other: typing.Union['QPainter.RenderHints', 'QPainter.RenderHint', int]) -> 'QPainter.RenderHints': ... + def __xor__(self, other: typing.Union['QPainter.RenderHints', 'QPainter.RenderHint', int]) -> 'QPainter.RenderHints': ... + def __ror__ (self, other: 'QPainter.RenderHint') -> 'QPainter.RenderHints': ... + def __rand__(self, other: 'QPainter.RenderHint') -> 'QPainter.RenderHints': ... + def __rxor__(self, other: 'QPainter.RenderHint') -> 'QPainter.RenderHints': ... class PixmapFragment(sip.simplewrapper): @@ -6435,12 +6539,20 @@ class QPainter(sip.simplewrapper): def __init__(self, f: typing.Union['QPainter.PixmapFragmentHints', 'QPainter.PixmapFragmentHint']) -> None: ... @typing.overload def __init__(self, a0: 'QPainter.PixmapFragmentHints') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QPainter.PixmapFragmentHints': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QPainter.PixmapFragmentHints', 'QPainter.PixmapFragmentHint', int]) -> 'QPainter.PixmapFragmentHints': ... + def __and__(self, other: typing.Union['QPainter.PixmapFragmentHints', 'QPainter.PixmapFragmentHint', int]) -> 'QPainter.PixmapFragmentHints': ... + def __xor__(self, other: typing.Union['QPainter.PixmapFragmentHints', 'QPainter.PixmapFragmentHint', int]) -> 'QPainter.PixmapFragmentHints': ... + def __ror__ (self, other: 'QPainter.PixmapFragmentHint') -> 'QPainter.PixmapFragmentHints': ... + def __rand__(self, other: 'QPainter.PixmapFragmentHint') -> 'QPainter.PixmapFragmentHints': ... + def __rxor__(self, other: 'QPainter.PixmapFragmentHint') -> 'QPainter.PixmapFragmentHints': ... @typing.overload def __init__(self) -> None: ... @@ -6776,6 +6888,9 @@ class QPainter(sip.simplewrapper): class QTextItem(sip.simplewrapper): class RenderFlag(int): + def __or__ (self, other: 'QTextItem.RenderFlag') -> 'QTextItem.RenderFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTextItem.RenderFlags': ... # type: ignore[override, misc] + RightToLeft = ... # type: QTextItem.RenderFlag Overline = ... # type: QTextItem.RenderFlag Underline = ... # type: QTextItem.RenderFlag @@ -6794,12 +6909,20 @@ class QTextItem(sip.simplewrapper): def __init__(self, f: typing.Union['QTextItem.RenderFlags', 'QTextItem.RenderFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTextItem.RenderFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextItem.RenderFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextItem.RenderFlags', 'QTextItem.RenderFlag', int]) -> 'QTextItem.RenderFlags': ... + def __and__(self, other: typing.Union['QTextItem.RenderFlags', 'QTextItem.RenderFlag', int]) -> 'QTextItem.RenderFlags': ... + def __xor__(self, other: typing.Union['QTextItem.RenderFlags', 'QTextItem.RenderFlag', int]) -> 'QTextItem.RenderFlags': ... + def __ror__ (self, other: 'QTextItem.RenderFlag') -> 'QTextItem.RenderFlags': ... + def __rand__(self, other: 'QTextItem.RenderFlag') -> 'QTextItem.RenderFlags': ... + def __rxor__(self, other: 'QTextItem.RenderFlag') -> 'QTextItem.RenderFlags': ... @typing.overload def __init__(self) -> None: ... @@ -6902,6 +7025,9 @@ class QPaintEngine(sip.simplewrapper): AllDirty = ... # type: QPaintEngine.DirtyFlag class PaintEngineFeature(int): + def __or__ (self, other: 'QPaintEngine.PaintEngineFeature') -> 'QPaintEngine.PaintEngineFeatures': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QPaintEngine.PaintEngineFeatures': ... # type: ignore[override, misc] + PrimitiveTransform = ... # type: QPaintEngine.PaintEngineFeature PatternTransform = ... # type: QPaintEngine.PaintEngineFeature PixmapTransform = ... # type: QPaintEngine.PaintEngineFeature @@ -6952,12 +7078,20 @@ class QPaintEngine(sip.simplewrapper): def __init__(self, f: typing.Union['QPaintEngine.PaintEngineFeatures', 'QPaintEngine.PaintEngineFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QPaintEngine.PaintEngineFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QPaintEngine.PaintEngineFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QPaintEngine.PaintEngineFeatures', 'QPaintEngine.PaintEngineFeature', int]) -> 'QPaintEngine.PaintEngineFeatures': ... + def __and__(self, other: typing.Union['QPaintEngine.PaintEngineFeatures', 'QPaintEngine.PaintEngineFeature', int]) -> 'QPaintEngine.PaintEngineFeatures': ... + def __xor__(self, other: typing.Union['QPaintEngine.PaintEngineFeatures', 'QPaintEngine.PaintEngineFeature', int]) -> 'QPaintEngine.PaintEngineFeatures': ... + def __ror__ (self, other: 'QPaintEngine.PaintEngineFeature') -> 'QPaintEngine.PaintEngineFeatures': ... + def __rand__(self, other: 'QPaintEngine.PaintEngineFeature') -> 'QPaintEngine.PaintEngineFeatures': ... + def __rxor__(self, other: 'QPaintEngine.PaintEngineFeature') -> 'QPaintEngine.PaintEngineFeatures': ... class DirtyFlags(sip.simplewrapper): @@ -6967,12 +7101,20 @@ class QPaintEngine(sip.simplewrapper): def __init__(self, f: typing.Union['QPaintEngine.DirtyFlags', 'QPaintEngine.DirtyFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QPaintEngine.DirtyFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QPaintEngine.DirtyFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QPaintEngine.DirtyFlags', 'QPaintEngine.DirtyFlag', int]) -> 'QPaintEngine.DirtyFlags': ... + def __and__(self, other: typing.Union['QPaintEngine.DirtyFlags', 'QPaintEngine.DirtyFlag', int]) -> 'QPaintEngine.DirtyFlags': ... + def __xor__(self, other: typing.Union['QPaintEngine.DirtyFlags', 'QPaintEngine.DirtyFlag', int]) -> 'QPaintEngine.DirtyFlags': ... + def __ror__ (self, other: 'QPaintEngine.DirtyFlag') -> 'QPaintEngine.DirtyFlags': ... + def __rand__(self, other: 'QPaintEngine.DirtyFlag') -> 'QPaintEngine.DirtyFlags': ... + def __rxor__(self, other: 'QPaintEngine.DirtyFlag') -> 'QPaintEngine.DirtyFlags': ... def __init__(self, features: typing.Union['QPaintEngine.PaintEngineFeatures', 'QPaintEngine.PaintEngineFeature'] = ...) -> None: ... @@ -7904,6 +8046,9 @@ class QRasterWindow(QPaintDeviceWindow): class QRawFont(sip.simplewrapper): class LayoutFlag(int): + def __or__ (self, other: 'QRawFont.LayoutFlag') -> 'QRawFont.LayoutFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QRawFont.LayoutFlags': ... # type: ignore[override, misc] + SeparateAdvances = ... # type: QRawFont.LayoutFlag KernedAdvances = ... # type: QRawFont.LayoutFlag UseDesignMetrics = ... # type: QRawFont.LayoutFlag @@ -7927,12 +8072,20 @@ class QRawFont(sip.simplewrapper): def __init__(self, f: typing.Union['QRawFont.LayoutFlags', 'QRawFont.LayoutFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QRawFont.LayoutFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QRawFont.LayoutFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QRawFont.LayoutFlags', 'QRawFont.LayoutFlag', int]) -> 'QRawFont.LayoutFlags': ... + def __and__(self, other: typing.Union['QRawFont.LayoutFlags', 'QRawFont.LayoutFlag', int]) -> 'QRawFont.LayoutFlags': ... + def __xor__(self, other: typing.Union['QRawFont.LayoutFlags', 'QRawFont.LayoutFlag', int]) -> 'QRawFont.LayoutFlags': ... + def __ror__ (self, other: 'QRawFont.LayoutFlag') -> 'QRawFont.LayoutFlags': ... + def __rand__(self, other: 'QRawFont.LayoutFlag') -> 'QRawFont.LayoutFlags': ... + def __rxor__(self, other: 'QRawFont.LayoutFlag') -> 'QRawFont.LayoutFlags': ... @typing.overload def __init__(self) -> None: ... @@ -8472,6 +8625,9 @@ class QSurfaceFormat(sip.simplewrapper): TripleBuffer = ... # type: QSurfaceFormat.SwapBehavior class FormatOption(int): + def __or__ (self, other: 'QSurfaceFormat.FormatOption') -> 'QSurfaceFormat.FormatOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QSurfaceFormat.FormatOptions': ... # type: ignore[override, misc] + StereoBuffers = ... # type: QSurfaceFormat.FormatOption DebugContext = ... # type: QSurfaceFormat.FormatOption DeprecatedFunctions = ... # type: QSurfaceFormat.FormatOption @@ -8490,12 +8646,20 @@ class QSurfaceFormat(sip.simplewrapper): def __init__(self, f: typing.Union['QSurfaceFormat.FormatOptions', 'QSurfaceFormat.FormatOption']) -> None: ... @typing.overload def __init__(self, a0: 'QSurfaceFormat.FormatOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QSurfaceFormat.FormatOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QSurfaceFormat.FormatOptions', 'QSurfaceFormat.FormatOption', int]) -> 'QSurfaceFormat.FormatOptions': ... + def __and__(self, other: typing.Union['QSurfaceFormat.FormatOptions', 'QSurfaceFormat.FormatOption', int]) -> 'QSurfaceFormat.FormatOptions': ... + def __xor__(self, other: typing.Union['QSurfaceFormat.FormatOptions', 'QSurfaceFormat.FormatOption', int]) -> 'QSurfaceFormat.FormatOptions': ... + def __ror__ (self, other: 'QSurfaceFormat.FormatOption') -> 'QSurfaceFormat.FormatOptions': ... + def __rand__(self, other: 'QSurfaceFormat.FormatOption') -> 'QSurfaceFormat.FormatOptions': ... + def __rxor__(self, other: 'QSurfaceFormat.FormatOption') -> 'QSurfaceFormat.FormatOptions': ... @typing.overload def __init__(self) -> None: ... @@ -8784,6 +8948,9 @@ class QTextDocument(QtCore.QObject): UserResource = ... # type: QTextDocument.ResourceType class FindFlag(int): + def __or__ (self, other: 'QTextDocument.FindFlag') -> 'QTextDocument.FindFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTextDocument.FindFlags': ... # type: ignore[override, misc] + FindBackward = ... # type: QTextDocument.FindFlag FindCaseSensitively = ... # type: QTextDocument.FindFlag FindWholeWords = ... # type: QTextDocument.FindFlag @@ -8807,12 +8974,20 @@ class QTextDocument(QtCore.QObject): def __init__(self, f: typing.Union['QTextDocument.FindFlags', 'QTextDocument.FindFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTextDocument.FindFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextDocument.FindFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextDocument.FindFlags', 'QTextDocument.FindFlag', int]) -> 'QTextDocument.FindFlags': ... + def __and__(self, other: typing.Union['QTextDocument.FindFlags', 'QTextDocument.FindFlag', int]) -> 'QTextDocument.FindFlags': ... + def __xor__(self, other: typing.Union['QTextDocument.FindFlags', 'QTextDocument.FindFlag', int]) -> 'QTextDocument.FindFlags': ... + def __ror__ (self, other: 'QTextDocument.FindFlag') -> 'QTextDocument.FindFlags': ... + def __rand__(self, other: 'QTextDocument.FindFlag') -> 'QTextDocument.FindFlags': ... + def __rxor__(self, other: 'QTextDocument.FindFlag') -> 'QTextDocument.FindFlags': ... class MarkdownFeatures(sip.simplewrapper): @@ -8822,12 +8997,20 @@ class QTextDocument(QtCore.QObject): def __init__(self, f: typing.Union['QTextDocument.MarkdownFeatures', 'QTextDocument.MarkdownFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QTextDocument.MarkdownFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextDocument.MarkdownFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextDocument.MarkdownFeatures', 'QTextDocument.MarkdownFeature', int]) -> 'QTextDocument.MarkdownFeatures': ... + def __and__(self, other: typing.Union['QTextDocument.MarkdownFeatures', 'QTextDocument.MarkdownFeature', int]) -> 'QTextDocument.MarkdownFeatures': ... + def __xor__(self, other: typing.Union['QTextDocument.MarkdownFeatures', 'QTextDocument.MarkdownFeature', int]) -> 'QTextDocument.MarkdownFeatures': ... + def __ror__ (self, other: 'QTextDocument.MarkdownFeature') -> 'QTextDocument.MarkdownFeatures': ... + def __rand__(self, other: 'QTextDocument.MarkdownFeature') -> 'QTextDocument.MarkdownFeatures': ... + def __rxor__(self, other: 'QTextDocument.MarkdownFeature') -> 'QTextDocument.MarkdownFeatures': ... @typing.overload def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -9229,6 +9412,9 @@ class QTextFormat(sip.simplewrapper): UserProperty = ... # type: QTextFormat.Property class PageBreakFlag(int): + def __or__ (self, other: 'QTextFormat.PageBreakFlag') -> 'QTextFormat.PageBreakFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTextFormat.PageBreakFlags': ... # type: ignore[override, misc] + PageBreak_Auto = ... # type: QTextFormat.PageBreakFlag PageBreak_AlwaysBefore = ... # type: QTextFormat.PageBreakFlag PageBreak_AlwaysAfter = ... # type: QTextFormat.PageBreakFlag @@ -9275,12 +9461,20 @@ class QTextFormat(sip.simplewrapper): def __init__(self, f: typing.Union['QTextFormat.PageBreakFlags', 'QTextFormat.PageBreakFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTextFormat.PageBreakFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextFormat.PageBreakFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextFormat.PageBreakFlags', 'QTextFormat.PageBreakFlag', int]) -> 'QTextFormat.PageBreakFlags': ... + def __and__(self, other: typing.Union['QTextFormat.PageBreakFlags', 'QTextFormat.PageBreakFlag', int]) -> 'QTextFormat.PageBreakFlags': ... + def __xor__(self, other: typing.Union['QTextFormat.PageBreakFlags', 'QTextFormat.PageBreakFlag', int]) -> 'QTextFormat.PageBreakFlags': ... + def __ror__ (self, other: 'QTextFormat.PageBreakFlag') -> 'QTextFormat.PageBreakFlags': ... + def __rand__(self, other: 'QTextFormat.PageBreakFlag') -> 'QTextFormat.PageBreakFlags': ... + def __rxor__(self, other: 'QTextFormat.PageBreakFlag') -> 'QTextFormat.PageBreakFlags': ... @typing.overload def __init__(self) -> None: ... @@ -10022,6 +10216,9 @@ class QTextOption(sip.simplewrapper): DelimiterTab = ... # type: QTextOption.TabType class Flag(int): + def __or__ (self, other: 'QTextOption.Flag') -> 'QTextOption.Flags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTextOption.Flags': ... # type: ignore[override, misc] + IncludeTrailingSpaces = ... # type: QTextOption.Flag ShowTabsAndSpaces = ... # type: QTextOption.Flag ShowLineAndParagraphSeparators = ... # type: QTextOption.Flag @@ -10057,12 +10254,20 @@ class QTextOption(sip.simplewrapper): def __init__(self, f: typing.Union['QTextOption.Flags', 'QTextOption.Flag']) -> None: ... @typing.overload def __init__(self, a0: 'QTextOption.Flags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextOption.Flags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextOption.Flags', 'QTextOption.Flag', int]) -> 'QTextOption.Flags': ... + def __and__(self, other: typing.Union['QTextOption.Flags', 'QTextOption.Flag', int]) -> 'QTextOption.Flags': ... + def __xor__(self, other: typing.Union['QTextOption.Flags', 'QTextOption.Flag', int]) -> 'QTextOption.Flags': ... + def __ror__ (self, other: 'QTextOption.Flag') -> 'QTextOption.Flags': ... + def __rand__(self, other: 'QTextOption.Flag') -> 'QTextOption.Flags': ... + def __rxor__(self, other: 'QTextOption.Flag') -> 'QTextOption.Flags': ... class Tab(sip.simplewrapper): @@ -10156,6 +10361,9 @@ class QTextTable(QTextFrame): class QTouchDevice(sip.simplewrapper): class CapabilityFlag(int): + def __or__ (self, other: 'QTouchDevice.CapabilityFlag') -> 'QTouchDevice.Capabilities': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTouchDevice.Capabilities': ... # type: ignore[override, misc] + Position = ... # type: QTouchDevice.CapabilityFlag Area = ... # type: QTouchDevice.CapabilityFlag Pressure = ... # type: QTouchDevice.CapabilityFlag @@ -10187,12 +10395,20 @@ class QTouchDevice(sip.simplewrapper): def __init__(self, f: typing.Union['QTouchDevice.Capabilities', 'QTouchDevice.CapabilityFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTouchDevice.Capabilities') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTouchDevice.Capabilities': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTouchDevice.Capabilities', 'QTouchDevice.CapabilityFlag', int]) -> 'QTouchDevice.Capabilities': ... + def __and__(self, other: typing.Union['QTouchDevice.Capabilities', 'QTouchDevice.CapabilityFlag', int]) -> 'QTouchDevice.Capabilities': ... + def __xor__(self, other: typing.Union['QTouchDevice.Capabilities', 'QTouchDevice.CapabilityFlag', int]) -> 'QTouchDevice.Capabilities': ... + def __ror__ (self, other: 'QTouchDevice.CapabilityFlag') -> 'QTouchDevice.Capabilities': ... + def __rand__(self, other: 'QTouchDevice.CapabilityFlag') -> 'QTouchDevice.Capabilities': ... + def __rxor__(self, other: 'QTouchDevice.CapabilityFlag') -> 'QTouchDevice.Capabilities': ... @typing.overload def __init__(self) -> None: ... diff --git a/PyQt5-stubs/QtNetwork.pyi b/PyQt5-stubs/QtNetwork.pyi index 667ddfa1..5a7bc297 100644 --- a/PyQt5-stubs/QtNetwork.pyi +++ b/PyQt5-stubs/QtNetwork.pyi @@ -91,6 +91,9 @@ class QAbstractNetworkCache(QtCore.QObject): class QAbstractSocket(QtCore.QIODevice): class PauseMode(int): + def __or__ (self, other: 'QAbstractSocket.PauseMode') -> 'QAbstractSocket.PauseModes': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QAbstractSocket.PauseModes': ... # type: ignore[override, misc] + PauseNever = ... # type: QAbstractSocket.PauseMode PauseOnSslErrors = ... # type: QAbstractSocket.PauseMode @@ -98,6 +101,9 @@ class QAbstractSocket(QtCore.QIODevice): PauseOnSslErrors = ... # type: QAbstractSocket.PauseMode class BindFlag(int): + def __or__ (self, other: 'QAbstractSocket.BindFlag') -> 'QAbstractSocket.BindMode': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QAbstractSocket.BindMode': ... # type: ignore[override, misc] + DefaultForPlatform = ... # type: QAbstractSocket.BindFlag ShareAddress = ... # type: QAbstractSocket.BindFlag DontShareAddress = ... # type: QAbstractSocket.BindFlag @@ -225,12 +231,20 @@ class QAbstractSocket(QtCore.QIODevice): def __init__(self, f: typing.Union['QAbstractSocket.BindMode', 'QAbstractSocket.BindFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QAbstractSocket.BindMode') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QAbstractSocket.BindMode': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QAbstractSocket.BindMode', 'QAbstractSocket.BindFlag', int]) -> 'QAbstractSocket.BindMode': ... + def __and__(self, other: typing.Union['QAbstractSocket.BindMode', 'QAbstractSocket.BindFlag', int]) -> 'QAbstractSocket.BindMode': ... + def __xor__(self, other: typing.Union['QAbstractSocket.BindMode', 'QAbstractSocket.BindFlag', int]) -> 'QAbstractSocket.BindMode': ... + def __ror__ (self, other: 'QAbstractSocket.BindFlag') -> 'QAbstractSocket.BindMode': ... + def __rand__(self, other: 'QAbstractSocket.BindFlag') -> 'QAbstractSocket.BindMode': ... + def __rxor__(self, other: 'QAbstractSocket.BindFlag') -> 'QAbstractSocket.BindMode': ... class PauseModes(sip.simplewrapper): @@ -240,12 +254,20 @@ class QAbstractSocket(QtCore.QIODevice): def __init__(self, f: typing.Union['QAbstractSocket.PauseModes', 'QAbstractSocket.PauseMode']) -> None: ... @typing.overload def __init__(self, a0: 'QAbstractSocket.PauseModes') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QAbstractSocket.PauseModes': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QAbstractSocket.PauseModes', 'QAbstractSocket.PauseMode', int]) -> 'QAbstractSocket.PauseModes': ... + def __and__(self, other: typing.Union['QAbstractSocket.PauseModes', 'QAbstractSocket.PauseMode', int]) -> 'QAbstractSocket.PauseModes': ... + def __xor__(self, other: typing.Union['QAbstractSocket.PauseModes', 'QAbstractSocket.PauseMode', int]) -> 'QAbstractSocket.PauseModes': ... + def __ror__ (self, other: 'QAbstractSocket.PauseMode') -> 'QAbstractSocket.PauseModes': ... + def __rand__(self, other: 'QAbstractSocket.PauseMode') -> 'QAbstractSocket.PauseModes': ... + def __rxor__(self, other: 'QAbstractSocket.PauseMode') -> 'QAbstractSocket.PauseModes': ... def __init__(self, socketType: 'QAbstractSocket.SocketType', parent: QtCore.QObject) -> None: ... @@ -476,6 +498,9 @@ class QDnsLookup(QtCore.QObject): class QHostAddress(sip.simplewrapper): class ConversionModeFlag(int): + def __or__ (self, other: 'QHostAddress.ConversionModeFlag') -> 'QHostAddress.ConversionMode': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QHostAddress.ConversionMode': ... # type: ignore[override, misc] + ConvertV4MappedToIPv4 = ... # type: QHostAddress.ConversionModeFlag ConvertV4CompatToIPv4 = ... # type: QHostAddress.ConversionModeFlag ConvertUnspecifiedAddress = ... # type: QHostAddress.ConversionModeFlag @@ -515,12 +540,20 @@ class QHostAddress(sip.simplewrapper): def __init__(self, f: typing.Union['QHostAddress.ConversionMode', 'QHostAddress.ConversionModeFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QHostAddress.ConversionMode') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QHostAddress.ConversionMode': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QHostAddress.ConversionMode', 'QHostAddress.ConversionModeFlag', int]) -> 'QHostAddress.ConversionMode': ... + def __and__(self, other: typing.Union['QHostAddress.ConversionMode', 'QHostAddress.ConversionModeFlag', int]) -> 'QHostAddress.ConversionMode': ... + def __xor__(self, other: typing.Union['QHostAddress.ConversionMode', 'QHostAddress.ConversionModeFlag', int]) -> 'QHostAddress.ConversionMode': ... + def __ror__ (self, other: 'QHostAddress.ConversionModeFlag') -> 'QHostAddress.ConversionMode': ... + def __rand__(self, other: 'QHostAddress.ConversionModeFlag') -> 'QHostAddress.ConversionMode': ... + def __rxor__(self, other: 'QHostAddress.ConversionModeFlag') -> 'QHostAddress.ConversionMode': ... @typing.overload def __init__(self) -> None: ... @@ -611,6 +644,9 @@ class QHostInfo(sip.simplewrapper): class QHstsPolicy(sip.simplewrapper): class PolicyFlag(int): + def __or__ (self, other: 'QHstsPolicy.PolicyFlag') -> 'QHstsPolicy.PolicyFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QHstsPolicy.PolicyFlags': ... # type: ignore[override, misc] + IncludeSubDomains = ... # type: QHstsPolicy.PolicyFlag IncludeSubDomains = ... # type: QHstsPolicy.PolicyFlag @@ -623,12 +659,20 @@ class QHstsPolicy(sip.simplewrapper): def __init__(self, f: typing.Union['QHstsPolicy.PolicyFlags', 'QHstsPolicy.PolicyFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QHstsPolicy.PolicyFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QHstsPolicy.PolicyFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QHstsPolicy.PolicyFlags', 'QHstsPolicy.PolicyFlag', int]) -> 'QHstsPolicy.PolicyFlags': ... + def __and__(self, other: typing.Union['QHstsPolicy.PolicyFlags', 'QHstsPolicy.PolicyFlag', int]) -> 'QHstsPolicy.PolicyFlags': ... + def __xor__(self, other: typing.Union['QHstsPolicy.PolicyFlags', 'QHstsPolicy.PolicyFlag', int]) -> 'QHstsPolicy.PolicyFlags': ... + def __ror__ (self, other: 'QHstsPolicy.PolicyFlag') -> 'QHstsPolicy.PolicyFlags': ... + def __rand__(self, other: 'QHstsPolicy.PolicyFlag') -> 'QHstsPolicy.PolicyFlags': ... + def __rxor__(self, other: 'QHstsPolicy.PolicyFlag') -> 'QHstsPolicy.PolicyFlags': ... @typing.overload def __init__(self) -> None: ... @@ -708,6 +752,9 @@ class QHttpMultiPart(QtCore.QObject): class QLocalServer(QtCore.QObject): class SocketOption(int): + def __or__ (self, other: 'QLocalServer.SocketOption') -> 'QLocalServer.SocketOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QLocalServer.SocketOptions': ... # type: ignore[override, misc] + UserAccessOption = ... # type: QLocalServer.SocketOption GroupAccessOption = ... # type: QLocalServer.SocketOption OtherAccessOption = ... # type: QLocalServer.SocketOption @@ -726,12 +773,20 @@ class QLocalServer(QtCore.QObject): def __init__(self, f: typing.Union['QLocalServer.SocketOptions', 'QLocalServer.SocketOption']) -> None: ... @typing.overload def __init__(self, a0: 'QLocalServer.SocketOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QLocalServer.SocketOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QLocalServer.SocketOptions', 'QLocalServer.SocketOption', int]) -> 'QLocalServer.SocketOptions': ... + def __and__(self, other: typing.Union['QLocalServer.SocketOptions', 'QLocalServer.SocketOption', int]) -> 'QLocalServer.SocketOptions': ... + def __xor__(self, other: typing.Union['QLocalServer.SocketOptions', 'QLocalServer.SocketOption', int]) -> 'QLocalServer.SocketOptions': ... + def __ror__ (self, other: 'QLocalServer.SocketOption') -> 'QLocalServer.SocketOptions': ... + def __rand__(self, other: 'QLocalServer.SocketOption') -> 'QLocalServer.SocketOptions': ... + def __rxor__(self, other: 'QLocalServer.SocketOption') -> 'QLocalServer.SocketOptions': ... def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -933,6 +988,9 @@ class QNetworkAccessManager(QtCore.QObject): class QNetworkConfigurationManager(QtCore.QObject): class Capability(int): + def __or__ (self, other: typing.Union[int, 'QNetworkConfigurationManager.Capability']) -> 'QNetworkConfigurationManager.Capabilities': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QNetworkConfigurationManager.Capabilities': ... # type: ignore[override, misc] + CanStartAndStopInterfaces = ... # type: QNetworkConfigurationManager.Capability DirectConnectionRouting = ... # type: QNetworkConfigurationManager.Capability SystemSessionSupport = ... # type: QNetworkConfigurationManager.Capability @@ -957,12 +1015,20 @@ class QNetworkConfigurationManager(QtCore.QObject): def __init__(self, f: typing.Union['QNetworkConfigurationManager.Capabilities', 'QNetworkConfigurationManager.Capability']) -> None: ... @typing.overload def __init__(self, a0: 'QNetworkConfigurationManager.Capabilities') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QNetworkConfigurationManager.Capabilities': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QNetworkConfigurationManager.Capabilities', 'QNetworkConfigurationManager.Capability', int]) -> 'QNetworkConfigurationManager.Capabilities': ... + def __and__(self, other: typing.Union['QNetworkConfigurationManager.Capabilities', 'QNetworkConfigurationManager.Capability', int]) -> 'QNetworkConfigurationManager.Capabilities': ... + def __xor__(self, other: typing.Union['QNetworkConfigurationManager.Capabilities', 'QNetworkConfigurationManager.Capability', int]) -> 'QNetworkConfigurationManager.Capabilities': ... + def __ror__ (self, other: 'QNetworkConfigurationManager.Capability') -> 'QNetworkConfigurationManager.Capabilities': ... + def __rand__(self, other: 'QNetworkConfigurationManager.Capability') -> 'QNetworkConfigurationManager.Capabilities': ... + def __rxor__(self, other: 'QNetworkConfigurationManager.Capability') -> 'QNetworkConfigurationManager.Capabilities': ... def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -1051,12 +1117,20 @@ class QNetworkConfiguration(sip.simplewrapper): def __init__(self, f: typing.Union['QNetworkConfiguration.StateFlags', 'QNetworkConfiguration.StateFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QNetworkConfiguration.StateFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QNetworkConfiguration.StateFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QNetworkConfiguration.StateFlags', 'QNetworkConfiguration.StateFlag', int]) -> 'QNetworkConfiguration.StateFlags': ... + def __and__(self, other: typing.Union['QNetworkConfiguration.StateFlags', 'QNetworkConfiguration.StateFlag', int]) -> 'QNetworkConfiguration.StateFlags': ... + def __xor__(self, other: typing.Union['QNetworkConfiguration.StateFlags', 'QNetworkConfiguration.StateFlag', int]) -> 'QNetworkConfiguration.StateFlags': ... + def __ror__ (self, other: 'QNetworkConfiguration.StateFlag') -> 'QNetworkConfiguration.StateFlags': ... + def __rand__(self, other: 'QNetworkConfiguration.StateFlag') -> 'QNetworkConfiguration.StateFlags': ... + def __rxor__(self, other: 'QNetworkConfiguration.StateFlag') -> 'QNetworkConfiguration.StateFlags': ... @typing.overload def __init__(self) -> None: ... @@ -1250,6 +1324,9 @@ class QNetworkInterface(sip.simplewrapper): Ieee1394 = ... # type: QNetworkInterface.InterfaceType class InterfaceFlag(int): + def __or__ (self, other: 'QNetworkInterface.InterfaceFlag') -> 'QNetworkInterface.InterfaceFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QNetworkInterface.InterfaceFlags': ... # type: ignore[override, misc] + IsUp = ... # type: QNetworkInterface.InterfaceFlag IsRunning = ... # type: QNetworkInterface.InterfaceFlag CanBroadcast = ... # type: QNetworkInterface.InterfaceFlag @@ -1272,12 +1349,20 @@ class QNetworkInterface(sip.simplewrapper): def __init__(self, f: typing.Union['QNetworkInterface.InterfaceFlags', 'QNetworkInterface.InterfaceFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QNetworkInterface.InterfaceFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QNetworkInterface.InterfaceFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QNetworkInterface.InterfaceFlags', 'QNetworkInterface.InterfaceFlag', int]) -> 'QNetworkInterface.InterfaceFlags': ... + def __and__(self, other: typing.Union['QNetworkInterface.InterfaceFlags', 'QNetworkInterface.InterfaceFlag', int]) -> 'QNetworkInterface.InterfaceFlags': ... + def __xor__(self, other: typing.Union['QNetworkInterface.InterfaceFlags', 'QNetworkInterface.InterfaceFlag', int]) -> 'QNetworkInterface.InterfaceFlags': ... + def __ror__ (self, other: 'QNetworkInterface.InterfaceFlag') -> 'QNetworkInterface.InterfaceFlags': ... + def __rand__(self, other: 'QNetworkInterface.InterfaceFlag') -> 'QNetworkInterface.InterfaceFlags': ... + def __rxor__(self, other: 'QNetworkInterface.InterfaceFlag') -> 'QNetworkInterface.InterfaceFlags': ... @typing.overload def __init__(self) -> None: ... @@ -1350,12 +1435,20 @@ class QNetworkProxy(sip.simplewrapper): def __init__(self, f: typing.Union['QNetworkProxy.Capabilities', 'QNetworkProxy.Capability']) -> None: ... @typing.overload def __init__(self, a0: 'QNetworkProxy.Capabilities') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QNetworkProxy.Capabilities': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QNetworkProxy.Capabilities', 'QNetworkProxy.Capability', int]) -> 'QNetworkProxy.Capabilities': ... + def __and__(self, other: typing.Union['QNetworkProxy.Capabilities', 'QNetworkProxy.Capability', int]) -> 'QNetworkProxy.Capabilities': ... + def __xor__(self, other: typing.Union['QNetworkProxy.Capabilities', 'QNetworkProxy.Capability', int]) -> 'QNetworkProxy.Capabilities': ... + def __ror__ (self, other: 'QNetworkProxy.Capability') -> 'QNetworkProxy.Capabilities': ... + def __rand__(self, other: 'QNetworkProxy.Capability') -> 'QNetworkProxy.Capabilities': ... + def __rxor__(self, other: 'QNetworkProxy.Capability') -> 'QNetworkProxy.Capabilities': ... @typing.overload def __init__(self) -> None: ... @@ -1802,12 +1895,20 @@ class QNetworkSession(QtCore.QObject): def __init__(self, f: typing.Union['QNetworkSession.UsagePolicies', 'QNetworkSession.UsagePolicy']) -> None: ... @typing.overload def __init__(self, a0: 'QNetworkSession.UsagePolicies') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QNetworkSession.UsagePolicies': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QNetworkSession.UsagePolicies', 'QNetworkSession.UsagePolicy', int]) -> 'QNetworkSession.UsagePolicies': ... + def __and__(self, other: typing.Union['QNetworkSession.UsagePolicies', 'QNetworkSession.UsagePolicy', int]) -> 'QNetworkSession.UsagePolicies': ... + def __xor__(self, other: typing.Union['QNetworkSession.UsagePolicies', 'QNetworkSession.UsagePolicy', int]) -> 'QNetworkSession.UsagePolicies': ... + def __ror__ (self, other: 'QNetworkSession.UsagePolicy') -> 'QNetworkSession.UsagePolicies': ... + def __rand__(self, other: 'QNetworkSession.UsagePolicy') -> 'QNetworkSession.UsagePolicies': ... + def __rxor__(self, other: 'QNetworkSession.UsagePolicy') -> 'QNetworkSession.UsagePolicies': ... def __init__(self, connConfig: QNetworkConfiguration, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -1868,6 +1969,9 @@ class QPasswordDigestor(sip.simplewrapper): class QSsl(sip.simplewrapper): class SslOption(int): + def __or__ (self, other: 'QSsl.SslOption') -> 'QSsl.SslOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QSsl.SslOptions': ... # type: ignore[override, misc] + SslOptionDisableEmptyFragments = ... # type: QSsl.SslOption SslOptionDisableSessionTickets = ... # type: QSsl.SslOption SslOptionDisableCompression = ... # type: QSsl.SslOption @@ -1969,12 +2073,20 @@ class QSsl(sip.simplewrapper): def __init__(self, f: typing.Union['QSsl.SslOptions', 'QSsl.SslOption']) -> None: ... @typing.overload def __init__(self, a0: 'QSsl.SslOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QSsl.SslOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QSsl.SslOptions', 'QSsl.SslOption', int]) -> 'QSsl.SslOptions': ... + def __and__(self, other: typing.Union['QSsl.SslOptions', 'QSsl.SslOption', int]) -> 'QSsl.SslOptions': ... + def __xor__(self, other: typing.Union['QSsl.SslOptions', 'QSsl.SslOption', int]) -> 'QSsl.SslOptions': ... + def __ror__ (self, other: 'QSsl.SslOption') -> 'QSsl.SslOptions': ... + def __rand__(self, other: 'QSsl.SslOption') -> 'QSsl.SslOptions': ... + def __rxor__(self, other: 'QSsl.SslOption') -> 'QSsl.SslOptions': ... class QSslCertificate(sip.simplewrapper): diff --git a/PyQt5-stubs/QtOpenGL.pyi b/PyQt5-stubs/QtOpenGL.pyi index 474b09be..f585dfa3 100644 --- a/PyQt5-stubs/QtOpenGL.pyi +++ b/PyQt5-stubs/QtOpenGL.pyi @@ -44,6 +44,9 @@ PYQT_OPENGL_BOUND_ARRAY = typing.Union[typing.Sequence[int], class QGL(sip.simplewrapper): class FormatOption(int): + def __or__ (self, other: 'QGL.FormatOption') -> 'QGL.FormatOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGL.FormatOptions': ... # type: ignore[override, misc] + DoubleBuffer = ... # type: QGL.FormatOption DepthBuffer = ... # type: QGL.FormatOption Rgba = ... # type: QGL.FormatOption @@ -98,12 +101,20 @@ class QGL(sip.simplewrapper): def __init__(self, f: typing.Union['QGL.FormatOptions', 'QGL.FormatOption']) -> None: ... @typing.overload def __init__(self, a0: 'QGL.FormatOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGL.FormatOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGL.FormatOptions', 'QGL.FormatOption', int]) -> 'QGL.FormatOptions': ... + def __and__(self, other: typing.Union['QGL.FormatOptions', 'QGL.FormatOption', int]) -> 'QGL.FormatOptions': ... + def __xor__(self, other: typing.Union['QGL.FormatOptions', 'QGL.FormatOption', int]) -> 'QGL.FormatOptions': ... + def __ror__ (self, other: 'QGL.FormatOption') -> 'QGL.FormatOptions': ... + def __rand__(self, other: 'QGL.FormatOption') -> 'QGL.FormatOptions': ... + def __rxor__(self, other: 'QGL.FormatOption') -> 'QGL.FormatOptions': ... class QGLFormat(sip.simplewrapper): @@ -118,6 +129,9 @@ class QGLFormat(sip.simplewrapper): CompatibilityProfile = ... # type: QGLFormat.OpenGLContextProfile class OpenGLVersionFlag(int): + def __or__ (self, other: 'QGLFormat.OpenGLVersionFlag') -> 'QGLFormat.OpenGLVersionFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGLFormat.OpenGLVersionFlags': ... # type: ignore[override, misc] + OpenGL_Version_None = ... # type: QGLFormat.OpenGLVersionFlag OpenGL_Version_1_1 = ... # type: QGLFormat.OpenGLVersionFlag OpenGL_Version_1_2 = ... # type: QGLFormat.OpenGLVersionFlag @@ -170,12 +184,20 @@ class QGLFormat(sip.simplewrapper): def __init__(self, f: typing.Union['QGLFormat.OpenGLVersionFlags', 'QGLFormat.OpenGLVersionFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QGLFormat.OpenGLVersionFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGLFormat.OpenGLVersionFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGLFormat.OpenGLVersionFlags', 'QGLFormat.OpenGLVersionFlag', int]) -> 'QGLFormat.OpenGLVersionFlags': ... + def __and__(self, other: typing.Union['QGLFormat.OpenGLVersionFlags', 'QGLFormat.OpenGLVersionFlag', int]) -> 'QGLFormat.OpenGLVersionFlags': ... + def __xor__(self, other: typing.Union['QGLFormat.OpenGLVersionFlags', 'QGLFormat.OpenGLVersionFlag', int]) -> 'QGLFormat.OpenGLVersionFlags': ... + def __ror__ (self, other: 'QGLFormat.OpenGLVersionFlag') -> 'QGLFormat.OpenGLVersionFlags': ... + def __rand__(self, other: 'QGLFormat.OpenGLVersionFlag') -> 'QGLFormat.OpenGLVersionFlags': ... + def __rxor__(self, other: 'QGLFormat.OpenGLVersionFlag') -> 'QGLFormat.OpenGLVersionFlags': ... @typing.overload def __init__(self) -> None: ... @@ -250,6 +272,9 @@ class QGLFormat(sip.simplewrapper): class QGLContext(sip.wrapper): class BindOption(int): + def __or__ (self, other: 'QGLContext.BindOption') -> 'QGLContext.BindOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGLContext.BindOptions': ... # type: ignore[override, misc] + NoBindOption = ... # type: QGLContext.BindOption InvertedYBindOption = ... # type: QGLContext.BindOption MipmapBindOption = ... # type: QGLContext.BindOption @@ -272,12 +297,20 @@ class QGLContext(sip.wrapper): def __init__(self, f: typing.Union['QGLContext.BindOptions', 'QGLContext.BindOption']) -> None: ... @typing.overload def __init__(self, a0: 'QGLContext.BindOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGLContext.BindOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGLContext.BindOptions', 'QGLContext.BindOption', int]) -> 'QGLContext.BindOptions': ... + def __and__(self, other: typing.Union['QGLContext.BindOptions', 'QGLContext.BindOption', int]) -> 'QGLContext.BindOptions': ... + def __xor__(self, other: typing.Union['QGLContext.BindOptions', 'QGLContext.BindOption', int]) -> 'QGLContext.BindOptions': ... + def __ror__ (self, other: 'QGLContext.BindOption') -> 'QGLContext.BindOptions': ... + def __rand__(self, other: 'QGLContext.BindOption') -> 'QGLContext.BindOptions': ... + def __rxor__(self, other: 'QGLContext.BindOption') -> 'QGLContext.BindOptions': ... def __init__(self, format: QGLFormat) -> None: ... diff --git a/PyQt5-stubs/QtPrintSupport.pyi b/PyQt5-stubs/QtPrintSupport.pyi index 6130e270..60b792ea 100644 --- a/PyQt5-stubs/QtPrintSupport.pyi +++ b/PyQt5-stubs/QtPrintSupport.pyi @@ -44,6 +44,9 @@ PYQT_OPENGL_BOUND_ARRAY = typing.Union[typing.Sequence[int], class QAbstractPrintDialog(QtWidgets.QDialog): class PrintDialogOption(int): + def __or__ (self, other: 'QAbstractPrintDialog.PrintDialogOption') -> 'QAbstractPrintDialog.PrintDialogOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QAbstractPrintDialog.PrintDialogOptions': ... # type: ignore[override, misc] + None_ = ... # type: QAbstractPrintDialog.PrintDialogOption PrintToFile = ... # type: QAbstractPrintDialog.PrintDialogOption PrintSelection = ... # type: QAbstractPrintDialog.PrintDialogOption @@ -79,12 +82,20 @@ class QAbstractPrintDialog(QtWidgets.QDialog): def __init__(self, f: typing.Union['QAbstractPrintDialog.PrintDialogOptions', 'QAbstractPrintDialog.PrintDialogOption']) -> None: ... @typing.overload def __init__(self, a0: 'QAbstractPrintDialog.PrintDialogOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QAbstractPrintDialog.PrintDialogOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QAbstractPrintDialog.PrintDialogOptions', 'QAbstractPrintDialog.PrintDialogOption', int]) -> 'QAbstractPrintDialog.PrintDialogOptions': ... + def __and__(self, other: typing.Union['QAbstractPrintDialog.PrintDialogOptions', 'QAbstractPrintDialog.PrintDialogOption', int]) -> 'QAbstractPrintDialog.PrintDialogOptions': ... + def __xor__(self, other: typing.Union['QAbstractPrintDialog.PrintDialogOptions', 'QAbstractPrintDialog.PrintDialogOption', int]) -> 'QAbstractPrintDialog.PrintDialogOptions': ... + def __ror__ (self, other: 'QAbstractPrintDialog.PrintDialogOption') -> 'QAbstractPrintDialog.PrintDialogOptions': ... + def __rand__(self, other: 'QAbstractPrintDialog.PrintDialogOption') -> 'QAbstractPrintDialog.PrintDialogOptions': ... + def __rxor__(self, other: 'QAbstractPrintDialog.PrintDialogOption') -> 'QAbstractPrintDialog.PrintDialogOptions': ... def __init__(self, printer: 'QPrinter', parent: typing.Optional[QtWidgets.QWidget] = ...) -> None: ... diff --git a/PyQt5-stubs/QtSql.pyi b/PyQt5-stubs/QtSql.pyi index e185262e..fe52e638 100644 --- a/PyQt5-stubs/QtSql.pyi +++ b/PyQt5-stubs/QtSql.pyi @@ -715,6 +715,9 @@ class QSql(sip.simplewrapper): AllTables = ... # type: QSql.TableType class ParamTypeFlag(int): + def __or__ (self, other: 'QSql.ParamTypeFlag') -> 'QSql.ParamType': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QSql.ParamType': ... # type: ignore[override, misc] + In = ... # type: QSql.ParamTypeFlag Out = ... # type: QSql.ParamTypeFlag InOut = ... # type: QSql.ParamTypeFlag @@ -740,9 +743,17 @@ class QSql(sip.simplewrapper): def __init__(self, f: typing.Union['QSql.ParamType', 'QSql.ParamTypeFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QSql.ParamType') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QSql.ParamType': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QSql.ParamType', 'QSql.ParamTypeFlag', int]) -> 'QSql.ParamType': ... + def __and__(self, other: typing.Union['QSql.ParamType', 'QSql.ParamTypeFlag', int]) -> 'QSql.ParamType': ... + def __xor__(self, other: typing.Union['QSql.ParamType', 'QSql.ParamTypeFlag', int]) -> 'QSql.ParamType': ... + def __ror__ (self, other: 'QSql.ParamTypeFlag') -> 'QSql.ParamType': ... + def __rand__(self, other: 'QSql.ParamTypeFlag') -> 'QSql.ParamType': ... + def __rxor__(self, other: 'QSql.ParamTypeFlag') -> 'QSql.ParamType': ... diff --git a/PyQt5-stubs/QtWidgets.pyi b/PyQt5-stubs/QtWidgets.pyi index 76c1ddc9..abc5ad3a 100644 --- a/PyQt5-stubs/QtWidgets.pyi +++ b/PyQt5-stubs/QtWidgets.pyi @@ -43,6 +43,9 @@ PYQT_OPENGL_BOUND_ARRAY = typing.Union[typing.Sequence[int], class QWidget(QtCore.QObject, QtGui.QPaintDevice): class RenderFlag(int): + def __or__ (self, other: 'QWidget.RenderFlag') -> 'QWidget.RenderFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QWidget.RenderFlags': ... # type: ignore[override, misc] + DrawWindowBackground = ... # type: QWidget.RenderFlag DrawChildren = ... # type: QWidget.RenderFlag IgnoreMask = ... # type: QWidget.RenderFlag @@ -59,12 +62,20 @@ class QWidget(QtCore.QObject, QtGui.QPaintDevice): def __init__(self, f: typing.Union['QWidget.RenderFlags', 'QWidget.RenderFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QWidget.RenderFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QWidget.RenderFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QWidget.RenderFlags', 'QWidget.RenderFlag', int]) -> 'QWidget.RenderFlags': ... + def __and__(self, other: typing.Union['QWidget.RenderFlags', 'QWidget.RenderFlag', int]) -> 'QWidget.RenderFlags': ... + def __xor__(self, other: typing.Union['QWidget.RenderFlags', 'QWidget.RenderFlag', int]) -> 'QWidget.RenderFlags': ... + def __ror__ (self, other: 'QWidget.RenderFlag') -> 'QWidget.RenderFlags': ... + def __rand__(self, other: 'QWidget.RenderFlag') -> 'QWidget.RenderFlags': ... + def __rxor__(self, other: 'QWidget.RenderFlag') -> 'QWidget.RenderFlags': ... def __init__(self, parent: typing.Optional['QWidget'] = ..., flags: typing.Union[QtCore.Qt.WindowFlags, QtCore.Qt.WindowType] = ...) -> None: ... @@ -690,6 +701,9 @@ class QAbstractItemView(QAbstractScrollArea): PositionAtCenter = ... # type: QAbstractItemView.ScrollHint class EditTrigger(int): + def __or__ (self, other: 'QAbstractItemView.EditTrigger') -> 'QAbstractItemView.EditTriggers': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QAbstractItemView.EditTriggers': ... # type: ignore[override, misc] + NoEditTriggers = ... # type: QAbstractItemView.EditTrigger CurrentChanged = ... # type: QAbstractItemView.EditTrigger DoubleClicked = ... # type: QAbstractItemView.EditTrigger @@ -727,12 +741,20 @@ class QAbstractItemView(QAbstractScrollArea): def __init__(self, f: typing.Union['QAbstractItemView.EditTriggers', 'QAbstractItemView.EditTrigger']) -> None: ... @typing.overload def __init__(self, a0: 'QAbstractItemView.EditTriggers') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QAbstractItemView.EditTriggers': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QAbstractItemView.EditTriggers', 'QAbstractItemView.EditTrigger', int]) -> 'QAbstractItemView.EditTriggers': ... + def __and__(self, other: typing.Union['QAbstractItemView.EditTriggers', 'QAbstractItemView.EditTrigger', int]) -> 'QAbstractItemView.EditTriggers': ... + def __xor__(self, other: typing.Union['QAbstractItemView.EditTriggers', 'QAbstractItemView.EditTrigger', int]) -> 'QAbstractItemView.EditTriggers': ... + def __ror__ (self, other: 'QAbstractItemView.EditTrigger') -> 'QAbstractItemView.EditTriggers': ... + def __rand__(self, other: 'QAbstractItemView.EditTrigger') -> 'QAbstractItemView.EditTriggers': ... + def __rxor__(self, other: 'QAbstractItemView.EditTrigger') -> 'QAbstractItemView.EditTriggers': ... def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -974,6 +996,9 @@ class QAbstractSpinBox(QWidget): NoButtons = ... # type: QAbstractSpinBox.ButtonSymbols class StepEnabledFlag(int): + def __or__ (self, other: 'QAbstractSpinBox.StepEnabledFlag') -> 'QAbstractSpinBox.StepEnabled': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QAbstractSpinBox.StepEnabled': ... # type: ignore[override, misc] + StepNone = ... # type: QAbstractSpinBox.StepEnabledFlag StepUpEnabled = ... # type: QAbstractSpinBox.StepEnabledFlag StepDownEnabled = ... # type: QAbstractSpinBox.StepEnabledFlag @@ -990,12 +1015,20 @@ class QAbstractSpinBox(QWidget): def __init__(self, f: typing.Union['QAbstractSpinBox.StepEnabled', 'QAbstractSpinBox.StepEnabledFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QAbstractSpinBox.StepEnabled') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QAbstractSpinBox.StepEnabled': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QAbstractSpinBox.StepEnabled', 'QAbstractSpinBox.StepEnabledFlag', int]) -> 'QAbstractSpinBox.StepEnabled': ... + def __and__(self, other: typing.Union['QAbstractSpinBox.StepEnabled', 'QAbstractSpinBox.StepEnabledFlag', int]) -> 'QAbstractSpinBox.StepEnabled': ... + def __xor__(self, other: typing.Union['QAbstractSpinBox.StepEnabled', 'QAbstractSpinBox.StepEnabledFlag', int]) -> 'QAbstractSpinBox.StepEnabled': ... + def __ror__ (self, other: 'QAbstractSpinBox.StepEnabledFlag') -> 'QAbstractSpinBox.StepEnabled': ... + def __rand__(self, other: 'QAbstractSpinBox.StepEnabledFlag') -> 'QAbstractSpinBox.StepEnabled': ... + def __rxor__(self, other: 'QAbstractSpinBox.StepEnabledFlag') -> 'QAbstractSpinBox.StepEnabled': ... def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -1685,6 +1718,9 @@ class QDialog(QWidget): class QColorDialog(QDialog): class ColorDialogOption(int): + def __or__ (self, other: 'QColorDialog.ColorDialogOption') -> 'QColorDialog.ColorDialogOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QColorDialog.ColorDialogOptions': ... # type: ignore[override, misc] + ShowAlphaChannel = ... # type: QColorDialog.ColorDialogOption NoButtons = ... # type: QColorDialog.ColorDialogOption DontUseNativeDialog = ... # type: QColorDialog.ColorDialogOption @@ -1701,12 +1737,20 @@ class QColorDialog(QDialog): def __init__(self, f: typing.Union['QColorDialog.ColorDialogOptions', 'QColorDialog.ColorDialogOption']) -> None: ... @typing.overload def __init__(self, a0: 'QColorDialog.ColorDialogOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QColorDialog.ColorDialogOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QColorDialog.ColorDialogOptions', 'QColorDialog.ColorDialogOption', int]) -> 'QColorDialog.ColorDialogOptions': ... + def __and__(self, other: typing.Union['QColorDialog.ColorDialogOptions', 'QColorDialog.ColorDialogOption', int]) -> 'QColorDialog.ColorDialogOptions': ... + def __xor__(self, other: typing.Union['QColorDialog.ColorDialogOptions', 'QColorDialog.ColorDialogOption', int]) -> 'QColorDialog.ColorDialogOptions': ... + def __ror__ (self, other: 'QColorDialog.ColorDialogOption') -> 'QColorDialog.ColorDialogOptions': ... + def __rand__(self, other: 'QColorDialog.ColorDialogOption') -> 'QColorDialog.ColorDialogOptions': ... + def __rxor__(self, other: 'QColorDialog.ColorDialogOption') -> 'QColorDialog.ColorDialogOptions': ... @typing.overload def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -2621,6 +2665,9 @@ class QStyle(QtCore.QObject): PM_CustomBase = ... # type: QStyle.PixelMetric class SubControl(int): + def __or__ (self, other: 'QStyle.SubControl') -> 'QStyle.SubControls': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStyle.SubControls': ... # type: ignore[override, misc] + SC_None = ... # type: QStyle.SubControl SC_ScrollBarAddLine = ... # type: QStyle.SubControl SC_ScrollBarSubLine = ... # type: QStyle.SubControl @@ -3068,6 +3115,9 @@ class QStyle(QtCore.QObject): PE_CustomBase = ... # type: QStyle.PrimitiveElement class StateFlag(int): + def __or__ (self, other: 'QStyle.StateFlag') -> 'QStyle.State': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStyle.State': ... # type: ignore[override, misc] + State_None = ... # type: QStyle.StateFlag State_Enabled = ... # type: QStyle.StateFlag State_Raised = ... # type: QStyle.StateFlag @@ -3134,12 +3184,20 @@ class QStyle(QtCore.QObject): def __init__(self, f: typing.Union['QStyle.State', 'QStyle.StateFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QStyle.State') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyle.State': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyle.State', 'QStyle.StateFlag', int]) -> 'QStyle.State': ... + def __and__(self, other: typing.Union['QStyle.State', 'QStyle.StateFlag', int]) -> 'QStyle.State': ... + def __xor__(self, other: typing.Union['QStyle.State', 'QStyle.StateFlag', int]) -> 'QStyle.State': ... + def __ror__ (self, other: 'QStyle.StateFlag') -> 'QStyle.State': ... + def __rand__(self, other: 'QStyle.StateFlag') -> 'QStyle.State': ... + def __rxor__(self, other: 'QStyle.StateFlag') -> 'QStyle.State': ... class SubControls(sip.simplewrapper): @@ -3149,12 +3207,20 @@ class QStyle(QtCore.QObject): def __init__(self, f: typing.Union['QStyle.SubControls', 'QStyle.SubControl']) -> None: ... @typing.overload def __init__(self, a0: 'QStyle.SubControls') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyle.SubControls': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyle.SubControls', 'QStyle.SubControl', int]) -> 'QStyle.SubControls': ... + def __and__(self, other: typing.Union['QStyle.SubControls', 'QStyle.SubControl', int]) -> 'QStyle.SubControls': ... + def __xor__(self, other: typing.Union['QStyle.SubControls', 'QStyle.SubControl', int]) -> 'QStyle.SubControls': ... + def __ror__ (self, other: 'QStyle.SubControl') -> 'QStyle.SubControls': ... + def __rand__(self, other: 'QStyle.SubControl') -> 'QStyle.SubControls': ... + def __rxor__(self, other: 'QStyle.SubControl') -> 'QStyle.SubControls': ... def __init__(self) -> None: ... @@ -3342,6 +3408,9 @@ class QDataWidgetMapper(QtCore.QObject): class QDateTimeEdit(QAbstractSpinBox): class Section(int): + def __or__ (self, other: 'QDateTimeEdit.Section') -> 'QDateTimeEdit.Sections': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDateTimeEdit.Sections': ... # type: ignore[override, misc] + NoSection = ... # type: QDateTimeEdit.Section AmPmSection = ... # type: QDateTimeEdit.Section MSecSection = ... # type: QDateTimeEdit.Section @@ -3374,12 +3443,20 @@ class QDateTimeEdit(QAbstractSpinBox): def __init__(self, f: typing.Union['QDateTimeEdit.Sections', 'QDateTimeEdit.Section']) -> None: ... @typing.overload def __init__(self, a0: 'QDateTimeEdit.Sections') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDateTimeEdit.Sections': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QDateTimeEdit.Sections', 'QDateTimeEdit.Section', int]) -> 'QDateTimeEdit.Sections': ... + def __and__(self, other: typing.Union['QDateTimeEdit.Sections', 'QDateTimeEdit.Section', int]) -> 'QDateTimeEdit.Sections': ... + def __xor__(self, other: typing.Union['QDateTimeEdit.Sections', 'QDateTimeEdit.Section', int]) -> 'QDateTimeEdit.Sections': ... + def __ror__ (self, other: 'QDateTimeEdit.Section') -> 'QDateTimeEdit.Sections': ... + def __rand__(self, other: 'QDateTimeEdit.Section') -> 'QDateTimeEdit.Sections': ... + def __rxor__(self, other: 'QDateTimeEdit.Section') -> 'QDateTimeEdit.Sections': ... @typing.overload def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -3530,11 +3607,9 @@ class QDial(QAbstractSlider): class QDialogButtonBox(QWidget): class StandardButton(int): - @typing.overload # type: ignore[override] - def __or__(self, other: typing.Union['QDialogButtonBox.StandardButton', 'QDialogButtonBox.StandardButtons']) -> 'QDialogButtonBox.StandardButtons': ... # type: ignore[misc] - @typing.overload - def __or__(self, other: int) -> int: ... - + def __or__ (self, other: 'QDialogButtonBox.StandardButton') -> 'QDialogButtonBox.StandardButtons': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDialogButtonBox.StandardButtons': ... # type: ignore[override, misc] + NoButton = ... # type: QDialogButtonBox.StandardButton Ok = ... # type: QDialogButtonBox.StandardButton Save = ... # type: QDialogButtonBox.StandardButton @@ -3619,13 +3694,20 @@ class QDialogButtonBox(QWidget): def __init__(self, f: typing.Union['QDialogButtonBox.StandardButtons', 'QDialogButtonBox.StandardButton']) -> None: ... @typing.overload def __init__(self, a0: 'QDialogButtonBox.StandardButtons') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDialogButtonBox.StandardButtons': ... def __index__(self) -> int: ... def __int__(self) -> int: ... - def __or__(self, other: typing.Union[int, 'QDialogButtonBox.StandardButtons', 'QDialogButtonBox.StandardButton']) -> 'QDialogButtonBox.StandardButtons': ... + def __or__ (self, other: typing.Union['QDialogButtonBox.StandardButtons', 'QDialogButtonBox.StandardButton', int]) -> 'QDialogButtonBox.StandardButtons': ... + def __and__(self, other: typing.Union['QDialogButtonBox.StandardButtons', 'QDialogButtonBox.StandardButton', int]) -> 'QDialogButtonBox.StandardButtons': ... + def __xor__(self, other: typing.Union['QDialogButtonBox.StandardButtons', 'QDialogButtonBox.StandardButton', int]) -> 'QDialogButtonBox.StandardButtons': ... + def __ror__ (self, other: 'QDialogButtonBox.StandardButton') -> 'QDialogButtonBox.StandardButtons': ... + def __rand__(self, other: 'QDialogButtonBox.StandardButton') -> 'QDialogButtonBox.StandardButtons': ... + def __rxor__(self, other: 'QDialogButtonBox.StandardButton') -> 'QDialogButtonBox.StandardButtons': ... @typing.overload def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -3726,6 +3808,9 @@ class QDirModel(QtCore.QAbstractItemModel): class QDockWidget(QWidget): class DockWidgetFeature(int): + def __or__ (self, other: 'QDockWidget.DockWidgetFeature') -> 'QDockWidget.DockWidgetFeatures': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QDockWidget.DockWidgetFeatures': ... # type: ignore[override, misc] + DockWidgetClosable = ... # type: QDockWidget.DockWidgetFeature DockWidgetMovable = ... # type: QDockWidget.DockWidgetFeature DockWidgetFloatable = ... # type: QDockWidget.DockWidgetFeature @@ -3748,12 +3833,20 @@ class QDockWidget(QWidget): def __init__(self, f: typing.Union['QDockWidget.DockWidgetFeatures', 'QDockWidget.DockWidgetFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QDockWidget.DockWidgetFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QDockWidget.DockWidgetFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QDockWidget.DockWidgetFeatures', 'QDockWidget.DockWidgetFeature', int]) -> 'QDockWidget.DockWidgetFeatures': ... + def __and__(self, other: typing.Union['QDockWidget.DockWidgetFeatures', 'QDockWidget.DockWidgetFeature', int]) -> 'QDockWidget.DockWidgetFeatures': ... + def __xor__(self, other: typing.Union['QDockWidget.DockWidgetFeatures', 'QDockWidget.DockWidgetFeature', int]) -> 'QDockWidget.DockWidgetFeatures': ... + def __ror__ (self, other: 'QDockWidget.DockWidgetFeature') -> 'QDockWidget.DockWidgetFeatures': ... + def __rand__(self, other: 'QDockWidget.DockWidgetFeature') -> 'QDockWidget.DockWidgetFeatures': ... + def __rxor__(self, other: 'QDockWidget.DockWidgetFeature') -> 'QDockWidget.DockWidgetFeatures': ... @typing.overload def __init__(self, title: str, parent: typing.Optional[QWidget] = ..., flags: typing.Union[QtCore.Qt.WindowFlags, QtCore.Qt.WindowType] = ...) -> None: ... @@ -3801,6 +3894,9 @@ class QErrorMessage(QDialog): class QFileDialog(QDialog): class Option(int): + def __or__ (self, other: 'QFileDialog.Option') -> 'QFileDialog.Options': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QFileDialog.Options': ... # type: ignore[override, misc] + ShowDirsOnly = ... # type: QFileDialog.Option DontResolveSymlinks = ... # type: QFileDialog.Option DontConfirmOverwrite = ... # type: QFileDialog.Option @@ -3867,12 +3963,20 @@ class QFileDialog(QDialog): def __init__(self, f: typing.Union['QFileDialog.Options', 'QFileDialog.Option']) -> None: ... @typing.overload def __init__(self, a0: 'QFileDialog.Options') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QFileDialog.Options': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QFileDialog.Options', 'QFileDialog.Option', int]) -> 'QFileDialog.Options': ... + def __and__(self, other: typing.Union['QFileDialog.Options', 'QFileDialog.Option', int]) -> 'QFileDialog.Options': ... + def __xor__(self, other: typing.Union['QFileDialog.Options', 'QFileDialog.Option', int]) -> 'QFileDialog.Options': ... + def __ror__ (self, other: 'QFileDialog.Option') -> 'QFileDialog.Options': ... + def __rand__(self, other: 'QFileDialog.Option') -> 'QFileDialog.Options': ... + def __rxor__(self, other: 'QFileDialog.Option') -> 'QFileDialog.Options': ... @typing.overload def __init__(self, parent: QWidget, f: typing.Union[QtCore.Qt.WindowFlags, QtCore.Qt.WindowType]) -> None: ... @@ -3969,6 +4073,9 @@ class QFileDialog(QDialog): class QFileIconProvider(sip.simplewrapper): class Option(int): + def __or__ (self, other: 'QFileIconProvider.Option') -> 'QFileIconProvider.Options': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QFileIconProvider.Options': ... # type: ignore[override, misc] + DontUseCustomDirectoryIcons = ... # type: QFileIconProvider.Option DontUseCustomDirectoryIcons = ... # type: QFileIconProvider.Option @@ -3998,12 +4105,20 @@ class QFileIconProvider(sip.simplewrapper): def __init__(self, f: typing.Union['QFileIconProvider.Options', 'QFileIconProvider.Option']) -> None: ... @typing.overload def __init__(self, a0: 'QFileIconProvider.Options') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QFileIconProvider.Options': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QFileIconProvider.Options', 'QFileIconProvider.Option', int]) -> 'QFileIconProvider.Options': ... + def __and__(self, other: typing.Union['QFileIconProvider.Options', 'QFileIconProvider.Option', int]) -> 'QFileIconProvider.Options': ... + def __xor__(self, other: typing.Union['QFileIconProvider.Options', 'QFileIconProvider.Option', int]) -> 'QFileIconProvider.Options': ... + def __ror__ (self, other: 'QFileIconProvider.Option') -> 'QFileIconProvider.Options': ... + def __rand__(self, other: 'QFileIconProvider.Option') -> 'QFileIconProvider.Options': ... + def __rxor__(self, other: 'QFileIconProvider.Option') -> 'QFileIconProvider.Options': ... def __init__(self) -> None: ... @@ -4019,6 +4134,9 @@ class QFileIconProvider(sip.simplewrapper): class QFileSystemModel(QtCore.QAbstractItemModel): class Option(int): + def __or__ (self, other: 'QFileSystemModel.Option') -> 'QFileSystemModel.Options': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QFileSystemModel.Options': ... # type: ignore[override, misc] + DontWatchForChanges = ... # type: QFileSystemModel.Option DontResolveSymlinks = ... # type: QFileSystemModel.Option DontUseCustomDirectoryIcons = ... # type: QFileSystemModel.Option @@ -4046,12 +4164,20 @@ class QFileSystemModel(QtCore.QAbstractItemModel): def __init__(self, f: typing.Union['QFileSystemModel.Options', 'QFileSystemModel.Option']) -> None: ... @typing.overload def __init__(self, a0: 'QFileSystemModel.Options') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QFileSystemModel.Options': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QFileSystemModel.Options', 'QFileSystemModel.Option', int]) -> 'QFileSystemModel.Options': ... + def __and__(self, other: typing.Union['QFileSystemModel.Options', 'QFileSystemModel.Option', int]) -> 'QFileSystemModel.Options': ... + def __xor__(self, other: typing.Union['QFileSystemModel.Options', 'QFileSystemModel.Option', int]) -> 'QFileSystemModel.Options': ... + def __ror__ (self, other: 'QFileSystemModel.Option') -> 'QFileSystemModel.Options': ... + def __rand__(self, other: 'QFileSystemModel.Option') -> 'QFileSystemModel.Options': ... + def __rxor__(self, other: 'QFileSystemModel.Option') -> 'QFileSystemModel.Options': ... def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -4129,6 +4255,9 @@ class QFocusFrame(QWidget): class QFontComboBox(QComboBox): class FontFilter(int): + def __or__ (self, other: 'QFontComboBox.FontFilter') -> 'QFontComboBox.FontFilters': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QFontComboBox.FontFilters': ... # type: ignore[override, misc] + AllFonts = ... # type: QFontComboBox.FontFilter ScalableFonts = ... # type: QFontComboBox.FontFilter NonScalableFonts = ... # type: QFontComboBox.FontFilter @@ -4149,12 +4278,20 @@ class QFontComboBox(QComboBox): def __init__(self, f: typing.Union['QFontComboBox.FontFilters', 'QFontComboBox.FontFilter']) -> None: ... @typing.overload def __init__(self, a0: 'QFontComboBox.FontFilters') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QFontComboBox.FontFilters': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QFontComboBox.FontFilters', 'QFontComboBox.FontFilter', int]) -> 'QFontComboBox.FontFilters': ... + def __and__(self, other: typing.Union['QFontComboBox.FontFilters', 'QFontComboBox.FontFilter', int]) -> 'QFontComboBox.FontFilters': ... + def __xor__(self, other: typing.Union['QFontComboBox.FontFilters', 'QFontComboBox.FontFilter', int]) -> 'QFontComboBox.FontFilters': ... + def __ror__ (self, other: 'QFontComboBox.FontFilter') -> 'QFontComboBox.FontFilters': ... + def __rand__(self, other: 'QFontComboBox.FontFilter') -> 'QFontComboBox.FontFilters': ... + def __rxor__(self, other: 'QFontComboBox.FontFilter') -> 'QFontComboBox.FontFilters': ... def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -4172,6 +4309,9 @@ class QFontComboBox(QComboBox): class QFontDialog(QDialog): class FontDialogOption(int): + def __or__ (self, other: 'QFontDialog.FontDialogOption') -> 'QFontDialog.FontDialogOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QFontDialog.FontDialogOptions': ... # type: ignore[override, misc] + NoButtons = ... # type: QFontDialog.FontDialogOption DontUseNativeDialog = ... # type: QFontDialog.FontDialogOption ScalableFonts = ... # type: QFontDialog.FontDialogOption @@ -4194,12 +4334,20 @@ class QFontDialog(QDialog): def __init__(self, f: typing.Union['QFontDialog.FontDialogOptions', 'QFontDialog.FontDialogOption']) -> None: ... @typing.overload def __init__(self, a0: 'QFontDialog.FontDialogOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QFontDialog.FontDialogOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QFontDialog.FontDialogOptions', 'QFontDialog.FontDialogOption', int]) -> 'QFontDialog.FontDialogOptions': ... + def __and__(self, other: typing.Union['QFontDialog.FontDialogOptions', 'QFontDialog.FontDialogOption', int]) -> 'QFontDialog.FontDialogOptions': ... + def __xor__(self, other: typing.Union['QFontDialog.FontDialogOptions', 'QFontDialog.FontDialogOption', int]) -> 'QFontDialog.FontDialogOptions': ... + def __ror__ (self, other: 'QFontDialog.FontDialogOption') -> 'QFontDialog.FontDialogOptions': ... + def __rand__(self, other: 'QFontDialog.FontDialogOption') -> 'QFontDialog.FontDialogOptions': ... + def __rxor__(self, other: 'QFontDialog.FontDialogOption') -> 'QFontDialog.FontDialogOptions': ... @typing.overload def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -4402,12 +4550,20 @@ class QPinchGesture(QGesture): def __init__(self, f: typing.Union['QPinchGesture.ChangeFlags', 'QPinchGesture.ChangeFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QPinchGesture.ChangeFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QPinchGesture.ChangeFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QPinchGesture.ChangeFlags', 'QPinchGesture.ChangeFlag', int]) -> 'QPinchGesture.ChangeFlags': ... + def __and__(self, other: typing.Union['QPinchGesture.ChangeFlags', 'QPinchGesture.ChangeFlag', int]) -> 'QPinchGesture.ChangeFlags': ... + def __xor__(self, other: typing.Union['QPinchGesture.ChangeFlags', 'QPinchGesture.ChangeFlag', int]) -> 'QPinchGesture.ChangeFlags': ... + def __ror__ (self, other: 'QPinchGesture.ChangeFlag') -> 'QPinchGesture.ChangeFlags': ... + def __rand__(self, other: 'QPinchGesture.ChangeFlag') -> 'QPinchGesture.ChangeFlags': ... + def __rxor__(self, other: 'QPinchGesture.ChangeFlag') -> 'QPinchGesture.ChangeFlags': ... def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -4520,6 +4676,9 @@ class QGestureEvent(QtCore.QEvent): class QGestureRecognizer(sip.wrapper): class ResultFlag(int): + def __or__ (self, other: 'QGestureRecognizer.ResultFlag') -> 'QGestureRecognizer.Result': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGestureRecognizer.Result': ... # type: ignore[override, misc] + Ignore = ... # type: QGestureRecognizer.ResultFlag MayBeGesture = ... # type: QGestureRecognizer.ResultFlag TriggerGesture = ... # type: QGestureRecognizer.ResultFlag @@ -4542,12 +4701,20 @@ class QGestureRecognizer(sip.wrapper): def __init__(self, f: typing.Union['QGestureRecognizer.Result', 'QGestureRecognizer.ResultFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QGestureRecognizer.Result') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGestureRecognizer.Result': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGestureRecognizer.Result', 'QGestureRecognizer.ResultFlag', int]) -> 'QGestureRecognizer.Result': ... + def __and__(self, other: typing.Union['QGestureRecognizer.Result', 'QGestureRecognizer.ResultFlag', int]) -> 'QGestureRecognizer.Result': ... + def __xor__(self, other: typing.Union['QGestureRecognizer.Result', 'QGestureRecognizer.ResultFlag', int]) -> 'QGestureRecognizer.Result': ... + def __ror__ (self, other: 'QGestureRecognizer.ResultFlag') -> 'QGestureRecognizer.Result': ... + def __rand__(self, other: 'QGestureRecognizer.ResultFlag') -> 'QGestureRecognizer.Result': ... + def __rxor__(self, other: 'QGestureRecognizer.ResultFlag') -> 'QGestureRecognizer.Result': ... @typing.overload def __init__(self) -> None: ... @@ -4675,6 +4842,9 @@ class QGraphicsEffect(QtCore.QObject): PadToEffectiveBoundingRect = ... # type: QGraphicsEffect.PixmapPadMode class ChangeFlag(int): + def __or__ (self, other: 'QGraphicsEffect.ChangeFlag') -> 'QGraphicsEffect.ChangeFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGraphicsEffect.ChangeFlags': ... # type: ignore[override, misc] + SourceAttached = ... # type: QGraphicsEffect.ChangeFlag SourceDetached = ... # type: QGraphicsEffect.ChangeFlag SourceBoundingRectChanged = ... # type: QGraphicsEffect.ChangeFlag @@ -4693,12 +4863,20 @@ class QGraphicsEffect(QtCore.QObject): def __init__(self, f: typing.Union['QGraphicsEffect.ChangeFlags', 'QGraphicsEffect.ChangeFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QGraphicsEffect.ChangeFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGraphicsEffect.ChangeFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGraphicsEffect.ChangeFlags', 'QGraphicsEffect.ChangeFlag', int]) -> 'QGraphicsEffect.ChangeFlags': ... + def __and__(self, other: typing.Union['QGraphicsEffect.ChangeFlags', 'QGraphicsEffect.ChangeFlag', int]) -> 'QGraphicsEffect.ChangeFlags': ... + def __xor__(self, other: typing.Union['QGraphicsEffect.ChangeFlags', 'QGraphicsEffect.ChangeFlag', int]) -> 'QGraphicsEffect.ChangeFlags': ... + def __ror__ (self, other: 'QGraphicsEffect.ChangeFlag') -> 'QGraphicsEffect.ChangeFlags': ... + def __rand__(self, other: 'QGraphicsEffect.ChangeFlag') -> 'QGraphicsEffect.ChangeFlags': ... + def __rxor__(self, other: 'QGraphicsEffect.ChangeFlag') -> 'QGraphicsEffect.ChangeFlags': ... def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -4733,6 +4911,9 @@ class QGraphicsColorizeEffect(QGraphicsEffect): class QGraphicsBlurEffect(QGraphicsEffect): class BlurHint(int): + def __or__ (self, other: 'QGraphicsBlurEffect.BlurHint') -> 'QGraphicsBlurEffect.BlurHints': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGraphicsBlurEffect.BlurHints': ... # type: ignore[override, misc] + PerformanceHint = ... # type: QGraphicsBlurEffect.BlurHint QualityHint = ... # type: QGraphicsBlurEffect.BlurHint AnimationHint = ... # type: QGraphicsBlurEffect.BlurHint @@ -4749,12 +4930,20 @@ class QGraphicsBlurEffect(QGraphicsEffect): def __init__(self, f: typing.Union['QGraphicsBlurEffect.BlurHints', 'QGraphicsBlurEffect.BlurHint']) -> None: ... @typing.overload def __init__(self, a0: 'QGraphicsBlurEffect.BlurHints') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGraphicsBlurEffect.BlurHints': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGraphicsBlurEffect.BlurHints', 'QGraphicsBlurEffect.BlurHint', int]) -> 'QGraphicsBlurEffect.BlurHints': ... + def __and__(self, other: typing.Union['QGraphicsBlurEffect.BlurHints', 'QGraphicsBlurEffect.BlurHint', int]) -> 'QGraphicsBlurEffect.BlurHints': ... + def __xor__(self, other: typing.Union['QGraphicsBlurEffect.BlurHints', 'QGraphicsBlurEffect.BlurHint', int]) -> 'QGraphicsBlurEffect.BlurHints': ... + def __ror__ (self, other: 'QGraphicsBlurEffect.BlurHint') -> 'QGraphicsBlurEffect.BlurHints': ... + def __rand__(self, other: 'QGraphicsBlurEffect.BlurHint') -> 'QGraphicsBlurEffect.BlurHints': ... + def __rxor__(self, other: 'QGraphicsBlurEffect.BlurHint') -> 'QGraphicsBlurEffect.BlurHints': ... def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -4874,6 +5063,9 @@ class QGraphicsItem(sip.wrapper): SceneModal = ... # type: QGraphicsItem.PanelModality class GraphicsItemFlag(int): + def __or__ (self, other: 'QGraphicsItem.GraphicsItemFlag') -> 'QGraphicsItem.GraphicsItemFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGraphicsItem.GraphicsItemFlags': ... # type: ignore[override, misc] + ItemIsMovable = ... # type: QGraphicsItem.GraphicsItemFlag ItemIsSelectable = ... # type: QGraphicsItem.GraphicsItemFlag ItemIsFocusable = ... # type: QGraphicsItem.GraphicsItemFlag @@ -4998,12 +5190,20 @@ class QGraphicsItem(sip.wrapper): def __init__(self, f: typing.Union['QGraphicsItem.GraphicsItemFlags', 'QGraphicsItem.GraphicsItemFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QGraphicsItem.GraphicsItemFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGraphicsItem.GraphicsItemFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGraphicsItem.GraphicsItemFlags', 'QGraphicsItem.GraphicsItemFlag', int]) -> 'QGraphicsItem.GraphicsItemFlags': ... + def __and__(self, other: typing.Union['QGraphicsItem.GraphicsItemFlags', 'QGraphicsItem.GraphicsItemFlag', int]) -> 'QGraphicsItem.GraphicsItemFlags': ... + def __xor__(self, other: typing.Union['QGraphicsItem.GraphicsItemFlags', 'QGraphicsItem.GraphicsItemFlag', int]) -> 'QGraphicsItem.GraphicsItemFlags': ... + def __ror__ (self, other: 'QGraphicsItem.GraphicsItemFlag') -> 'QGraphicsItem.GraphicsItemFlags': ... + def __rand__(self, other: 'QGraphicsItem.GraphicsItemFlag') -> 'QGraphicsItem.GraphicsItemFlags': ... + def __rxor__(self, other: 'QGraphicsItem.GraphicsItemFlag') -> 'QGraphicsItem.GraphicsItemFlags': ... Type = ... # type: int UserType = ... # type: int @@ -5713,6 +5913,9 @@ class QGraphicsProxyWidget(QGraphicsWidget): class QGraphicsScene(QtCore.QObject): class SceneLayer(int): + def __or__ (self, other: 'QGraphicsScene.SceneLayer') -> 'QGraphicsScene.SceneLayers': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGraphicsScene.SceneLayers': ... # type: ignore[override, misc] + ItemLayer = ... # type: QGraphicsScene.SceneLayer BackgroundLayer = ... # type: QGraphicsScene.SceneLayer ForegroundLayer = ... # type: QGraphicsScene.SceneLayer @@ -5738,12 +5941,20 @@ class QGraphicsScene(QtCore.QObject): def __init__(self, f: typing.Union['QGraphicsScene.SceneLayers', 'QGraphicsScene.SceneLayer']) -> None: ... @typing.overload def __init__(self, a0: 'QGraphicsScene.SceneLayers') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGraphicsScene.SceneLayers': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGraphicsScene.SceneLayers', 'QGraphicsScene.SceneLayer', int]) -> 'QGraphicsScene.SceneLayers': ... + def __and__(self, other: typing.Union['QGraphicsScene.SceneLayers', 'QGraphicsScene.SceneLayer', int]) -> 'QGraphicsScene.SceneLayers': ... + def __xor__(self, other: typing.Union['QGraphicsScene.SceneLayers', 'QGraphicsScene.SceneLayer', int]) -> 'QGraphicsScene.SceneLayers': ... + def __ror__ (self, other: 'QGraphicsScene.SceneLayer') -> 'QGraphicsScene.SceneLayers': ... + def __rand__(self, other: 'QGraphicsScene.SceneLayer') -> 'QGraphicsScene.SceneLayers': ... + def __rxor__(self, other: 'QGraphicsScene.SceneLayer') -> 'QGraphicsScene.SceneLayers': ... @typing.overload def __init__(self, parent: typing.Optional[QtCore.QObject] = ...) -> None: ... @@ -6031,6 +6242,9 @@ class QGraphicsRotation(QGraphicsTransform): class QGraphicsView(QAbstractScrollArea): class OptimizationFlag(int): + def __or__ (self, other: 'QGraphicsView.OptimizationFlag') -> 'QGraphicsView.OptimizationFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGraphicsView.OptimizationFlags': ... # type: ignore[override, misc] + DontClipPainter = ... # type: QGraphicsView.OptimizationFlag DontSavePainterState = ... # type: QGraphicsView.OptimizationFlag DontAdjustForAntialiasing = ... # type: QGraphicsView.OptimizationFlag @@ -6071,6 +6285,9 @@ class QGraphicsView(QAbstractScrollArea): RubberBandDrag = ... # type: QGraphicsView.DragMode class CacheModeFlag(int): + def __or__ (self, other: 'QGraphicsView.CacheModeFlag') -> 'QGraphicsView.CacheMode': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QGraphicsView.CacheMode': ... # type: ignore[override, misc] + CacheNone = ... # type: QGraphicsView.CacheModeFlag CacheBackground = ... # type: QGraphicsView.CacheModeFlag @@ -6085,12 +6302,20 @@ class QGraphicsView(QAbstractScrollArea): def __init__(self, f: typing.Union['QGraphicsView.CacheMode', 'QGraphicsView.CacheModeFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QGraphicsView.CacheMode') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGraphicsView.CacheMode': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGraphicsView.CacheMode', 'QGraphicsView.CacheModeFlag', int]) -> 'QGraphicsView.CacheMode': ... + def __and__(self, other: typing.Union['QGraphicsView.CacheMode', 'QGraphicsView.CacheModeFlag', int]) -> 'QGraphicsView.CacheMode': ... + def __xor__(self, other: typing.Union['QGraphicsView.CacheMode', 'QGraphicsView.CacheModeFlag', int]) -> 'QGraphicsView.CacheMode': ... + def __ror__ (self, other: 'QGraphicsView.CacheModeFlag') -> 'QGraphicsView.CacheMode': ... + def __rand__(self, other: 'QGraphicsView.CacheModeFlag') -> 'QGraphicsView.CacheMode': ... + def __rxor__(self, other: 'QGraphicsView.CacheModeFlag') -> 'QGraphicsView.CacheMode': ... class OptimizationFlags(sip.simplewrapper): @@ -6100,12 +6325,20 @@ class QGraphicsView(QAbstractScrollArea): def __init__(self, f: typing.Union['QGraphicsView.OptimizationFlags', 'QGraphicsView.OptimizationFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QGraphicsView.OptimizationFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QGraphicsView.OptimizationFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QGraphicsView.OptimizationFlags', 'QGraphicsView.OptimizationFlag', int]) -> 'QGraphicsView.OptimizationFlags': ... + def __and__(self, other: typing.Union['QGraphicsView.OptimizationFlags', 'QGraphicsView.OptimizationFlag', int]) -> 'QGraphicsView.OptimizationFlags': ... + def __xor__(self, other: typing.Union['QGraphicsView.OptimizationFlags', 'QGraphicsView.OptimizationFlag', int]) -> 'QGraphicsView.OptimizationFlags': ... + def __ror__ (self, other: 'QGraphicsView.OptimizationFlag') -> 'QGraphicsView.OptimizationFlags': ... + def __rand__(self, other: 'QGraphicsView.OptimizationFlag') -> 'QGraphicsView.OptimizationFlags': ... + def __rxor__(self, other: 'QGraphicsView.OptimizationFlag') -> 'QGraphicsView.OptimizationFlags': ... @typing.overload def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -6488,6 +6721,9 @@ class QInputDialog(QDialog): DoubleInput = ... # type: QInputDialog.InputMode class InputDialogOption(int): + def __or__ (self, other: 'QInputDialog.InputDialogOption') -> 'QInputDialog.InputDialogOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QInputDialog.InputDialogOptions': ... # type: ignore[override, misc] + NoButtons = ... # type: QInputDialog.InputDialogOption UseListViewForComboBoxItems = ... # type: QInputDialog.InputDialogOption UsePlainTextEditForTextInput = ... # type: QInputDialog.InputDialogOption @@ -6504,12 +6740,20 @@ class QInputDialog(QDialog): def __init__(self, f: typing.Union['QInputDialog.InputDialogOptions', 'QInputDialog.InputDialogOption']) -> None: ... @typing.overload def __init__(self, a0: 'QInputDialog.InputDialogOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QInputDialog.InputDialogOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QInputDialog.InputDialogOptions', 'QInputDialog.InputDialogOption', int]) -> 'QInputDialog.InputDialogOptions': ... + def __and__(self, other: typing.Union['QInputDialog.InputDialogOptions', 'QInputDialog.InputDialogOption', int]) -> 'QInputDialog.InputDialogOptions': ... + def __xor__(self, other: typing.Union['QInputDialog.InputDialogOptions', 'QInputDialog.InputDialogOption', int]) -> 'QInputDialog.InputDialogOptions': ... + def __ror__ (self, other: 'QInputDialog.InputDialogOption') -> 'QInputDialog.InputDialogOptions': ... + def __rand__(self, other: 'QInputDialog.InputDialogOption') -> 'QInputDialog.InputDialogOptions': ... + def __rxor__(self, other: 'QInputDialog.InputDialogOption') -> 'QInputDialog.InputDialogOptions': ... def __init__(self, parent: typing.Optional[QWidget] = ..., flags: typing.Union[QtCore.Qt.WindowFlags, QtCore.Qt.WindowType] = ...) -> None: ... @@ -7186,6 +7430,9 @@ class QListWidget(QListView): class QMainWindow(QWidget): class DockOption(int): + def __or__ (self, other: 'QMainWindow.DockOption') -> 'QMainWindow.DockOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QMainWindow.DockOptions': ... # type: ignore[override, misc] + AnimatedDocks = ... # type: QMainWindow.DockOption AllowNestedDocks = ... # type: QMainWindow.DockOption AllowTabbedDocks = ... # type: QMainWindow.DockOption @@ -7208,12 +7455,20 @@ class QMainWindow(QWidget): def __init__(self, f: typing.Union['QMainWindow.DockOptions', 'QMainWindow.DockOption']) -> None: ... @typing.overload def __init__(self, a0: 'QMainWindow.DockOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QMainWindow.DockOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QMainWindow.DockOptions', 'QMainWindow.DockOption', int]) -> 'QMainWindow.DockOptions': ... + def __and__(self, other: typing.Union['QMainWindow.DockOptions', 'QMainWindow.DockOption', int]) -> 'QMainWindow.DockOptions': ... + def __xor__(self, other: typing.Union['QMainWindow.DockOptions', 'QMainWindow.DockOption', int]) -> 'QMainWindow.DockOptions': ... + def __ror__ (self, other: 'QMainWindow.DockOption') -> 'QMainWindow.DockOptions': ... + def __rand__(self, other: 'QMainWindow.DockOption') -> 'QMainWindow.DockOptions': ... + def __rxor__(self, other: 'QMainWindow.DockOption') -> 'QMainWindow.DockOptions': ... def __init__(self, parent: typing.Optional[QWidget] = ..., flags: typing.Union[QtCore.Qt.WindowFlags, QtCore.Qt.WindowType] = ...) -> None: ... @@ -7300,6 +7555,9 @@ class QMdiArea(QAbstractScrollArea): TabbedView = ... # type: QMdiArea.ViewMode class AreaOption(int): + def __or__ (self, other: 'QMdiArea.AreaOption') -> 'QMdiArea.AreaOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QMdiArea.AreaOptions': ... # type: ignore[override, misc] + DontMaximizeSubWindowOnActivation = ... # type: QMdiArea.AreaOption DontMaximizeSubWindowOnActivation = ... # type: QMdiArea.AreaOption @@ -7312,12 +7570,20 @@ class QMdiArea(QAbstractScrollArea): def __init__(self, f: typing.Union['QMdiArea.AreaOptions', 'QMdiArea.AreaOption']) -> None: ... @typing.overload def __init__(self, a0: 'QMdiArea.AreaOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QMdiArea.AreaOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QMdiArea.AreaOptions', 'QMdiArea.AreaOption', int]) -> 'QMdiArea.AreaOptions': ... + def __and__(self, other: typing.Union['QMdiArea.AreaOptions', 'QMdiArea.AreaOption', int]) -> 'QMdiArea.AreaOptions': ... + def __xor__(self, other: typing.Union['QMdiArea.AreaOptions', 'QMdiArea.AreaOption', int]) -> 'QMdiArea.AreaOptions': ... + def __ror__ (self, other: 'QMdiArea.AreaOption') -> 'QMdiArea.AreaOptions': ... + def __rand__(self, other: 'QMdiArea.AreaOption') -> 'QMdiArea.AreaOptions': ... + def __rxor__(self, other: 'QMdiArea.AreaOption') -> 'QMdiArea.AreaOptions': ... def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -7369,6 +7635,9 @@ class QMdiArea(QAbstractScrollArea): class QMdiSubWindow(QWidget): class SubWindowOption(int): + def __or__ (self, other: 'QMdiSubWindow.SubWindowOption') -> 'QMdiSubWindow.SubWindowOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QMdiSubWindow.SubWindowOptions': ... # type: ignore[override, misc] + RubberBandResize = ... # type: QMdiSubWindow.SubWindowOption RubberBandMove = ... # type: QMdiSubWindow.SubWindowOption @@ -7383,12 +7652,20 @@ class QMdiSubWindow(QWidget): def __init__(self, f: typing.Union['QMdiSubWindow.SubWindowOptions', 'QMdiSubWindow.SubWindowOption']) -> None: ... @typing.overload def __init__(self, a0: 'QMdiSubWindow.SubWindowOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QMdiSubWindow.SubWindowOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QMdiSubWindow.SubWindowOptions', 'QMdiSubWindow.SubWindowOption', int]) -> 'QMdiSubWindow.SubWindowOptions': ... + def __and__(self, other: typing.Union['QMdiSubWindow.SubWindowOptions', 'QMdiSubWindow.SubWindowOption', int]) -> 'QMdiSubWindow.SubWindowOptions': ... + def __xor__(self, other: typing.Union['QMdiSubWindow.SubWindowOptions', 'QMdiSubWindow.SubWindowOption', int]) -> 'QMdiSubWindow.SubWindowOptions': ... + def __ror__ (self, other: 'QMdiSubWindow.SubWindowOption') -> 'QMdiSubWindow.SubWindowOptions': ... + def __rand__(self, other: 'QMdiSubWindow.SubWindowOption') -> 'QMdiSubWindow.SubWindowOptions': ... + def __rxor__(self, other: 'QMdiSubWindow.SubWindowOption') -> 'QMdiSubWindow.SubWindowOptions': ... def __init__(self, parent: typing.Optional[QWidget] = ..., flags: typing.Union[QtCore.Qt.WindowFlags, QtCore.Qt.WindowType] = ...) -> None: ... @@ -7586,11 +7863,10 @@ class QMenuBar(QWidget): class QMessageBox(QDialog): class StandardButton(int): - @typing.overload # type: ignore[override] - def __or__(self, other: typing.Union['QMessageBox.StandardButton', 'QMessageBox.StandardButtons']) -> 'QMessageBox.StandardButtons': ... # type: ignore[misc] - @typing.overload - def __or__(self, other: int) -> int: ... + def __or__ (self, other: 'QMessageBox.StandardButton') -> 'QMessageBox.StandardButtons': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QMessageBox.StandardButtons': ... # type: ignore[override, misc] + NoButton = ... # type: 'QMessageBox.StandardButton' Ok = ... # type: 'QMessageBox.StandardButton' Save = ... # type: 'QMessageBox.StandardButton' @@ -7691,13 +7967,20 @@ class QMessageBox(QDialog): def __init__(self, f: typing.Union['QMessageBox.StandardButtons', 'QMessageBox.StandardButton']) -> None: ... @typing.overload def __init__(self, a0: 'QMessageBox.StandardButtons') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QMessageBox.StandardButtons': ... def __index__(self) -> int: ... def __int__(self) -> int: ... - def __or__(self, other: typing.Union[int, 'QMessageBox.StandardButtons', 'QMessageBox.StandardButton']) -> 'QMessageBox.StandardButtons': ... + def __or__ (self, other: typing.Union['QMessageBox.StandardButtons', 'QMessageBox.StandardButton', int]) -> 'QMessageBox.StandardButtons': ... + def __and__(self, other: typing.Union['QMessageBox.StandardButtons', 'QMessageBox.StandardButton', int]) -> 'QMessageBox.StandardButtons': ... + def __xor__(self, other: typing.Union['QMessageBox.StandardButtons', 'QMessageBox.StandardButton', int]) -> 'QMessageBox.StandardButtons': ... + def __ror__ (self, other: 'QMessageBox.StandardButton') -> 'QMessageBox.StandardButtons': ... + def __rand__(self, other: 'QMessageBox.StandardButton') -> 'QMessageBox.StandardButtons': ... + def __rxor__(self, other: 'QMessageBox.StandardButton') -> 'QMessageBox.StandardButtons': ... @typing.overload def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -8392,6 +8675,9 @@ class QSizeGrip(QWidget): class QSizePolicy(sip.simplewrapper): class ControlType(int): + def __or__ (self, other: 'QSizePolicy.ControlType') -> 'QSizePolicy.ControlTypes': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QSizePolicy.ControlTypes': ... # type: ignore[override, misc] + DefaultType = ... # type: QSizePolicy.ControlType ButtonBox = ... # type: QSizePolicy.ControlType CheckBox = ... # type: QSizePolicy.ControlType @@ -8460,12 +8746,20 @@ class QSizePolicy(sip.simplewrapper): def __init__(self, f: typing.Union['QSizePolicy.ControlTypes', 'QSizePolicy.ControlType']) -> None: ... @typing.overload def __init__(self, a0: 'QSizePolicy.ControlTypes') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QSizePolicy.ControlTypes': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QSizePolicy.ControlTypes', 'QSizePolicy.ControlType', int]) -> 'QSizePolicy.ControlTypes': ... + def __and__(self, other: typing.Union['QSizePolicy.ControlTypes', 'QSizePolicy.ControlType', int]) -> 'QSizePolicy.ControlTypes': ... + def __xor__(self, other: typing.Union['QSizePolicy.ControlTypes', 'QSizePolicy.ControlType', int]) -> 'QSizePolicy.ControlTypes': ... + def __ror__ (self, other: 'QSizePolicy.ControlType') -> 'QSizePolicy.ControlTypes': ... + def __rand__(self, other: 'QSizePolicy.ControlType') -> 'QSizePolicy.ControlTypes': ... + def __rxor__(self, other: 'QSizePolicy.ControlType') -> 'QSizePolicy.ControlTypes': ... @typing.overload def __init__(self) -> None: ... @@ -8903,6 +9197,9 @@ class QStyleOptionFocusRect(QStyleOption): class QStyleOptionFrame(QStyleOption): class FrameFeature(int): + def __or__ (self, other: 'QStyleOptionFrame.FrameFeature') -> 'QStyleOptionFrame.FrameFeatures': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStyleOptionFrame.FrameFeatures': ... # type: ignore[override, misc] + None_ = ... # type: QStyleOptionFrame.FrameFeature Flat = ... # type: QStyleOptionFrame.FrameFeature Rounded = ... # type: QStyleOptionFrame.FrameFeature @@ -8929,12 +9226,20 @@ class QStyleOptionFrame(QStyleOption): def __init__(self, f: typing.Union['QStyleOptionFrame.FrameFeatures', 'QStyleOptionFrame.FrameFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QStyleOptionFrame.FrameFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyleOptionFrame.FrameFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyleOptionFrame.FrameFeatures', 'QStyleOptionFrame.FrameFeature', int]) -> 'QStyleOptionFrame.FrameFeatures': ... + def __and__(self, other: typing.Union['QStyleOptionFrame.FrameFeatures', 'QStyleOptionFrame.FrameFeature', int]) -> 'QStyleOptionFrame.FrameFeatures': ... + def __xor__(self, other: typing.Union['QStyleOptionFrame.FrameFeatures', 'QStyleOptionFrame.FrameFeature', int]) -> 'QStyleOptionFrame.FrameFeatures': ... + def __ror__ (self, other: 'QStyleOptionFrame.FrameFeature') -> 'QStyleOptionFrame.FrameFeatures': ... + def __rand__(self, other: 'QStyleOptionFrame.FrameFeature') -> 'QStyleOptionFrame.FrameFeatures': ... + def __rxor__(self, other: 'QStyleOptionFrame.FrameFeature') -> 'QStyleOptionFrame.FrameFeatures': ... features = ... # type: typing.Union['QStyleOptionFrame.FrameFeatures', 'QStyleOptionFrame.FrameFeature'] frameShape = ... # type: QFrame.Shape @@ -9059,6 +9364,9 @@ class QStyleOptionHeader(QStyleOption): class QStyleOptionButton(QStyleOption): class ButtonFeature(int): + def __or__ (self, other: 'QStyleOptionButton.ButtonFeature') -> 'QStyleOptionButton.ButtonFeatures': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStyleOptionButton.ButtonFeatures': ... # type: ignore[override, misc] + None_ = ... # type: QStyleOptionButton.ButtonFeature Flat = ... # type: QStyleOptionButton.ButtonFeature HasMenu = ... # type: QStyleOptionButton.ButtonFeature @@ -9091,12 +9399,20 @@ class QStyleOptionButton(QStyleOption): def __init__(self, f: typing.Union['QStyleOptionButton.ButtonFeatures', 'QStyleOptionButton.ButtonFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QStyleOptionButton.ButtonFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyleOptionButton.ButtonFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyleOptionButton.ButtonFeatures', 'QStyleOptionButton.ButtonFeature', int]) -> 'QStyleOptionButton.ButtonFeatures': ... + def __and__(self, other: typing.Union['QStyleOptionButton.ButtonFeatures', 'QStyleOptionButton.ButtonFeature', int]) -> 'QStyleOptionButton.ButtonFeatures': ... + def __xor__(self, other: typing.Union['QStyleOptionButton.ButtonFeatures', 'QStyleOptionButton.ButtonFeature', int]) -> 'QStyleOptionButton.ButtonFeatures': ... + def __ror__ (self, other: 'QStyleOptionButton.ButtonFeature') -> 'QStyleOptionButton.ButtonFeatures': ... + def __rand__(self, other: 'QStyleOptionButton.ButtonFeature') -> 'QStyleOptionButton.ButtonFeatures': ... + def __rxor__(self, other: 'QStyleOptionButton.ButtonFeature') -> 'QStyleOptionButton.ButtonFeatures': ... features = ... # type: typing.Union['QStyleOptionButton.ButtonFeatures', 'QStyleOptionButton.ButtonFeature'] icon = ... # type: QtGui.QIcon @@ -9119,6 +9435,9 @@ class QStyleOptionTab(QStyleOption): HasFrame = ... # type: QStyleOptionTab.TabFeature class CornerWidget(int): + def __or__ (self, other: 'QStyleOptionTab.CornerWidget') -> 'QStyleOptionTab.CornerWidgets': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStyleOptionTab.CornerWidgets': ... # type: ignore[override, misc] + NoCornerWidgets = ... # type: QStyleOptionTab.CornerWidget LeftCornerWidget = ... # type: QStyleOptionTab.CornerWidget RightCornerWidget = ... # type: QStyleOptionTab.CornerWidget @@ -9165,12 +9484,20 @@ class QStyleOptionTab(QStyleOption): def __init__(self, f: typing.Union['QStyleOptionTab.CornerWidgets', 'QStyleOptionTab.CornerWidget']) -> None: ... @typing.overload def __init__(self, a0: 'QStyleOptionTab.CornerWidgets') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyleOptionTab.CornerWidgets': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyleOptionTab.CornerWidgets', 'QStyleOptionTab.CornerWidget', int]) -> 'QStyleOptionTab.CornerWidgets': ... + def __and__(self, other: typing.Union['QStyleOptionTab.CornerWidgets', 'QStyleOptionTab.CornerWidget', int]) -> 'QStyleOptionTab.CornerWidgets': ... + def __xor__(self, other: typing.Union['QStyleOptionTab.CornerWidgets', 'QStyleOptionTab.CornerWidget', int]) -> 'QStyleOptionTab.CornerWidgets': ... + def __ror__ (self, other: 'QStyleOptionTab.CornerWidget') -> 'QStyleOptionTab.CornerWidgets': ... + def __rand__(self, other: 'QStyleOptionTab.CornerWidget') -> 'QStyleOptionTab.CornerWidgets': ... + def __rxor__(self, other: 'QStyleOptionTab.CornerWidget') -> 'QStyleOptionTab.CornerWidgets': ... class TabFeatures(sip.simplewrapper): @@ -9180,12 +9507,20 @@ class QStyleOptionTab(QStyleOption): def __init__(self, f: typing.Union['QStyleOptionTab.TabFeatures', 'QStyleOptionTab.TabFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QStyleOptionTab.TabFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyleOptionTab.TabFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyleOptionTab.TabFeatures', 'QStyleOptionTab.TabFeature', int]) -> 'QStyleOptionTab.TabFeatures': ... + def __and__(self, other: typing.Union['QStyleOptionTab.TabFeatures', 'QStyleOptionTab.TabFeature', int]) -> 'QStyleOptionTab.TabFeatures': ... + def __xor__(self, other: typing.Union['QStyleOptionTab.TabFeatures', 'QStyleOptionTab.TabFeature', int]) -> 'QStyleOptionTab.TabFeatures': ... + def __ror__ (self, other: 'QStyleOptionTab.TabFeature') -> 'QStyleOptionTab.TabFeatures': ... + def __rand__(self, other: 'QStyleOptionTab.TabFeature') -> 'QStyleOptionTab.TabFeatures': ... + def __rxor__(self, other: 'QStyleOptionTab.TabFeature') -> 'QStyleOptionTab.TabFeatures': ... cornerWidgets = ... # type: typing.Union['QStyleOptionTab.CornerWidgets', 'QStyleOptionTab.CornerWidget'] documentMode = ... # type: bool @@ -9346,6 +9681,9 @@ class QStyleOptionViewItem(QStyleOption): OnlyOne = ... # type: QStyleOptionViewItem.ViewItemPosition class ViewItemFeature(int): + def __or__ (self, other: 'QStyleOptionViewItem.ViewItemFeature') -> 'QStyleOptionViewItem.ViewItemFeatures': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStyleOptionViewItem.ViewItemFeatures': ... # type: ignore[override, misc] + None_ = ... # type: QStyleOptionViewItem.ViewItemFeature WrapText = ... # type: QStyleOptionViewItem.ViewItemFeature Alternate = ... # type: QStyleOptionViewItem.ViewItemFeature @@ -9389,12 +9727,20 @@ class QStyleOptionViewItem(QStyleOption): def __init__(self, f: typing.Union['QStyleOptionViewItem.ViewItemFeatures', 'QStyleOptionViewItem.ViewItemFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QStyleOptionViewItem.ViewItemFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyleOptionViewItem.ViewItemFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyleOptionViewItem.ViewItemFeatures', 'QStyleOptionViewItem.ViewItemFeature', int]) -> 'QStyleOptionViewItem.ViewItemFeatures': ... + def __and__(self, other: typing.Union['QStyleOptionViewItem.ViewItemFeatures', 'QStyleOptionViewItem.ViewItemFeature', int]) -> 'QStyleOptionViewItem.ViewItemFeatures': ... + def __xor__(self, other: typing.Union['QStyleOptionViewItem.ViewItemFeatures', 'QStyleOptionViewItem.ViewItemFeature', int]) -> 'QStyleOptionViewItem.ViewItemFeatures': ... + def __ror__ (self, other: 'QStyleOptionViewItem.ViewItemFeature') -> 'QStyleOptionViewItem.ViewItemFeatures': ... + def __rand__(self, other: 'QStyleOptionViewItem.ViewItemFeature') -> 'QStyleOptionViewItem.ViewItemFeatures': ... + def __rxor__(self, other: 'QStyleOptionViewItem.ViewItemFeature') -> 'QStyleOptionViewItem.ViewItemFeatures': ... backgroundBrush = ... # type: typing.Union[QtGui.QBrush, QtGui.QColor, QtCore.Qt.GlobalColor, QtGui.QGradient] checkState = ... # type: QtCore.Qt.CheckState @@ -9560,6 +9906,9 @@ class QStyleOptionSpinBox(QStyleOptionComplex): class QStyleOptionToolButton(QStyleOptionComplex): class ToolButtonFeature(int): + def __or__ (self, other: 'QStyleOptionToolButton.ToolButtonFeature') -> 'QStyleOptionToolButton.ToolButtonFeatures': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStyleOptionToolButton.ToolButtonFeatures': ... # type: ignore[override, misc] + None_ = ... # type: QStyleOptionToolButton.ToolButtonFeature Arrow = ... # type: QStyleOptionToolButton.ToolButtonFeature Menu = ... # type: QStyleOptionToolButton.ToolButtonFeature @@ -9592,12 +9941,20 @@ class QStyleOptionToolButton(QStyleOptionComplex): def __init__(self, f: typing.Union['QStyleOptionToolButton.ToolButtonFeatures', 'QStyleOptionToolButton.ToolButtonFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QStyleOptionToolButton.ToolButtonFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyleOptionToolButton.ToolButtonFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyleOptionToolButton.ToolButtonFeatures', 'QStyleOptionToolButton.ToolButtonFeature', int]) -> 'QStyleOptionToolButton.ToolButtonFeatures': ... + def __and__(self, other: typing.Union['QStyleOptionToolButton.ToolButtonFeatures', 'QStyleOptionToolButton.ToolButtonFeature', int]) -> 'QStyleOptionToolButton.ToolButtonFeatures': ... + def __xor__(self, other: typing.Union['QStyleOptionToolButton.ToolButtonFeatures', 'QStyleOptionToolButton.ToolButtonFeature', int]) -> 'QStyleOptionToolButton.ToolButtonFeatures': ... + def __ror__ (self, other: 'QStyleOptionToolButton.ToolButtonFeature') -> 'QStyleOptionToolButton.ToolButtonFeatures': ... + def __rand__(self, other: 'QStyleOptionToolButton.ToolButtonFeature') -> 'QStyleOptionToolButton.ToolButtonFeatures': ... + def __rxor__(self, other: 'QStyleOptionToolButton.ToolButtonFeature') -> 'QStyleOptionToolButton.ToolButtonFeatures': ... arrowType = ... # type: QtCore.Qt.ArrowType features = ... # type: typing.Union['QStyleOptionToolButton.ToolButtonFeatures', 'QStyleOptionToolButton.ToolButtonFeature'] @@ -9715,6 +10072,9 @@ class QStyleHintReturnMask(QStyleHintReturn): class QStyleOptionToolBar(QStyleOption): class ToolBarFeature(int): + def __or__ (self, other: 'QStyleOptionToolBar.ToolBarFeature') -> 'QStyleOptionToolBar.ToolBarFeatures': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QStyleOptionToolBar.ToolBarFeatures': ... # type: ignore[override, misc] + None_ = ... # type: QStyleOptionToolBar.ToolBarFeature Movable = ... # type: QStyleOptionToolBar.ToolBarFeature @@ -9750,12 +10110,20 @@ class QStyleOptionToolBar(QStyleOption): def __init__(self, f: typing.Union['QStyleOptionToolBar.ToolBarFeatures', 'QStyleOptionToolBar.ToolBarFeature']) -> None: ... @typing.overload def __init__(self, a0: 'QStyleOptionToolBar.ToolBarFeatures') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QStyleOptionToolBar.ToolBarFeatures': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QStyleOptionToolBar.ToolBarFeatures', 'QStyleOptionToolBar.ToolBarFeature', int]) -> 'QStyleOptionToolBar.ToolBarFeatures': ... + def __and__(self, other: typing.Union['QStyleOptionToolBar.ToolBarFeatures', 'QStyleOptionToolBar.ToolBarFeature', int]) -> 'QStyleOptionToolBar.ToolBarFeatures': ... + def __xor__(self, other: typing.Union['QStyleOptionToolBar.ToolBarFeatures', 'QStyleOptionToolBar.ToolBarFeature', int]) -> 'QStyleOptionToolBar.ToolBarFeatures': ... + def __ror__ (self, other: 'QStyleOptionToolBar.ToolBarFeature') -> 'QStyleOptionToolBar.ToolBarFeatures': ... + def __rand__(self, other: 'QStyleOptionToolBar.ToolBarFeature') -> 'QStyleOptionToolBar.ToolBarFeatures': ... + def __rxor__(self, other: 'QStyleOptionToolBar.ToolBarFeature') -> 'QStyleOptionToolBar.ToolBarFeatures': ... features = ... # type: typing.Union['QStyleOptionToolBar.ToolBarFeatures', 'QStyleOptionToolBar.ToolBarFeature'] lineWidth = ... # type: int @@ -10402,6 +10770,9 @@ class QTabWidget(QWidget): class QTextEdit(QAbstractScrollArea): class AutoFormattingFlag(int): + def __or__ (self, other: 'QTextEdit.AutoFormattingFlag') -> 'QTextEdit.AutoFormatting': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTextEdit.AutoFormatting': ... # type: ignore[override, misc] + AutoNone = ... # type: QTextEdit.AutoFormattingFlag AutoBulletList = ... # type: QTextEdit.AutoFormattingFlag AutoAll = ... # type: QTextEdit.AutoFormattingFlag @@ -10439,12 +10810,20 @@ class QTextEdit(QAbstractScrollArea): def __init__(self, f: typing.Union['QTextEdit.AutoFormatting', 'QTextEdit.AutoFormattingFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTextEdit.AutoFormatting') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTextEdit.AutoFormatting': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTextEdit.AutoFormatting', 'QTextEdit.AutoFormattingFlag', int]) -> 'QTextEdit.AutoFormatting': ... + def __and__(self, other: typing.Union['QTextEdit.AutoFormatting', 'QTextEdit.AutoFormattingFlag', int]) -> 'QTextEdit.AutoFormatting': ... + def __xor__(self, other: typing.Union['QTextEdit.AutoFormatting', 'QTextEdit.AutoFormattingFlag', int]) -> 'QTextEdit.AutoFormatting': ... + def __ror__ (self, other: 'QTextEdit.AutoFormattingFlag') -> 'QTextEdit.AutoFormatting': ... + def __rand__(self, other: 'QTextEdit.AutoFormattingFlag') -> 'QTextEdit.AutoFormatting': ... + def __rxor__(self, other: 'QTextEdit.AutoFormattingFlag') -> 'QTextEdit.AutoFormatting': ... @typing.overload def __init__(self, parent: typing.Optional[QWidget] = ...) -> None: ... @@ -11078,6 +11457,9 @@ class QTreeWidget(QTreeView): class QTreeWidgetItemIterator(sip.simplewrapper): class IteratorFlag(int): + def __or__ (self, other: 'QTreeWidgetItemIterator.IteratorFlag') -> 'QTreeWidgetItemIterator.IteratorFlags': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QTreeWidgetItemIterator.IteratorFlags': ... # type: ignore[override, misc] + All = ... # type: QTreeWidgetItemIterator.IteratorFlag Hidden = ... # type: QTreeWidgetItemIterator.IteratorFlag NotHidden = ... # type: QTreeWidgetItemIterator.IteratorFlag @@ -11128,12 +11510,20 @@ class QTreeWidgetItemIterator(sip.simplewrapper): def __init__(self, f: typing.Union['QTreeWidgetItemIterator.IteratorFlags', 'QTreeWidgetItemIterator.IteratorFlag']) -> None: ... @typing.overload def __init__(self, a0: 'QTreeWidgetItemIterator.IteratorFlags') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QTreeWidgetItemIterator.IteratorFlags': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QTreeWidgetItemIterator.IteratorFlags', 'QTreeWidgetItemIterator.IteratorFlag', int]) -> 'QTreeWidgetItemIterator.IteratorFlags': ... + def __and__(self, other: typing.Union['QTreeWidgetItemIterator.IteratorFlags', 'QTreeWidgetItemIterator.IteratorFlag', int]) -> 'QTreeWidgetItemIterator.IteratorFlags': ... + def __xor__(self, other: typing.Union['QTreeWidgetItemIterator.IteratorFlags', 'QTreeWidgetItemIterator.IteratorFlag', int]) -> 'QTreeWidgetItemIterator.IteratorFlags': ... + def __ror__ (self, other: 'QTreeWidgetItemIterator.IteratorFlag') -> 'QTreeWidgetItemIterator.IteratorFlags': ... + def __rand__(self, other: 'QTreeWidgetItemIterator.IteratorFlag') -> 'QTreeWidgetItemIterator.IteratorFlags': ... + def __rxor__(self, other: 'QTreeWidgetItemIterator.IteratorFlag') -> 'QTreeWidgetItemIterator.IteratorFlags': ... @typing.overload def __init__(self, it: 'QTreeWidgetItemIterator') -> None: ... @@ -11285,6 +11675,9 @@ class QWidgetAction(QAction): class QWizard(QDialog): class WizardOption(int): + def __or__ (self, other: 'QWizard.WizardOption') -> 'QWizard.WizardOptions': ... # type: ignore[override] + def __ror__ (self, other: int) -> 'QWizard.WizardOptions': ... # type: ignore[override, misc] + IndependentPages = ... # type: QWizard.WizardOption IgnoreSubTitles = ... # type: QWizard.WizardOption ExtendedWatermarkPixmap = ... # type: QWizard.WizardOption @@ -11374,12 +11767,20 @@ class QWizard(QDialog): def __init__(self, f: typing.Union['QWizard.WizardOptions', 'QWizard.WizardOption']) -> None: ... @typing.overload def __init__(self, a0: 'QWizard.WizardOptions') -> None: ... + @typing.overload + def __init__(self, f: int) -> None: ... def __hash__(self) -> int: ... def __bool__(self) -> int: ... def __invert__(self) -> 'QWizard.WizardOptions': ... def __index__(self) -> int: ... def __int__(self) -> int: ... + def __or__ (self, other: typing.Union['QWizard.WizardOptions', 'QWizard.WizardOption', int]) -> 'QWizard.WizardOptions': ... + def __and__(self, other: typing.Union['QWizard.WizardOptions', 'QWizard.WizardOption', int]) -> 'QWizard.WizardOptions': ... + def __xor__(self, other: typing.Union['QWizard.WizardOptions', 'QWizard.WizardOption', int]) -> 'QWizard.WizardOptions': ... + def __ror__ (self, other: 'QWizard.WizardOption') -> 'QWizard.WizardOptions': ... + def __rand__(self, other: 'QWizard.WizardOption') -> 'QWizard.WizardOptions': ... + def __rxor__(self, other: 'QWizard.WizardOption') -> 'QWizard.WizardOptions': ... def __init__(self, parent: typing.Optional[QWidget] = ..., flags: typing.Union[QtCore.Qt.WindowFlags, QtCore.Qt.WindowType] = ...) -> None: ... diff --git a/tests/qflags/README_qflags.md b/tests/qflags/README_qflags.md new file mode 100644 index 00000000..16725c22 --- /dev/null +++ b/tests/qflags/README_qflags.md @@ -0,0 +1,76 @@ +# QFlag stubs semi-automatic generation process + +This directory is dedicated to helping with the generation of stubs related to all QFlags used in PyQt5. + +## Overview + +The general idea of the generation is: +* Grep Qt sources, looking for all QFlag based classes and store the result in a text file +* Process the grep text file to identify the QFlag names and their module. Generates a `qflags_modules_analysis.json` +* Using `qflags_modules_analysis.json` , extract the QFlags where the module is cleary identified and put + them into a `qflags_to_process.json` file. +* Process each flag one by one from `qflags_to_process.json` and output a `qflags_process_result.json` . For + each QFlag: + ** verify with code analysis if the QFlag is indeed present in this module + ** check if the stubs for all qflags operation are already present. If yes, stops. + ** if not, add the missing stubs to the module and generate a test file in the form test__.py + ** run `pytest` and `mypy` on the generated test file + ** if successful, stage the changes to git + ** if there is any error in the process, stops. + + +## Details + +To run all the above steps, proceed with the following steps. + + +### Grep the Qt sources + +The command-line to use is: + + qt-src\qt5\qtbase>rg --type-add "headers:*.h" -t headers Q_DECLARE_FLAGS --no-heading > qt-qflag-grep-result.txt + + +### Analyse the QFlags module location + +Run: + + python generate_qflags_stubs_and_tests.py analyse_grep_results qt-qflag-grep-result.txt + +You get two files: + * qflags_modules_analysis.json + * qflags_to_process.json + +With human verification, you can add more QFlags to the `qflags_to_process.json` file. You +can also point the exact full class name for the QFlags in case where this program does +not identify it correctly. The fields `human_hint_qflag_full_class_name` and +`human_hint_enum_full_class_name` are available for this purpose. + +### Generate and test the new stubs + +Run: + python generate_qflags_stubs_and_tests.py gen_qflag_stub 5 --auto-commit + +This will process 5 QFlags from qflags_to_process.json . The result of the processing is: +* the file `qflags_to_process.json` is read to find the list of items to process +* the list is compared with the already processed items in `qflags_process_result.json` + to find the items needing processing. +* the file `qflags_process_result.json` is updated with the results of the processing. +* when the generation and test is successful: + ** the qt module is updated + ** a new test file is added in the format test__.py + ** a git commit with the test file and updated module is performed (only if you specifed --auto-commit) + +To process all qflags: + + python generate_qflags_stubs_and_tests.py gen_qflag_stub all --auto-commit + +## Conclusion + +The process is semi-manual at the moment. The tool will process QFlags in batches and let the user perform +the final git commit and push. + +Note that more intelligence shall be put in the future to handle QFlags with identical names located in +multiple classes or modules. + + diff --git a/tests/qflags/generate_qflags_stubs_and_tests.py b/tests/qflags/generate_qflags_stubs_and_tests.py new file mode 100644 index 00000000..ff3a51e1 --- /dev/null +++ b/tests/qflags/generate_qflags_stubs_and_tests.py @@ -0,0 +1,1122 @@ +from typing import List, Tuple, Dict, Union, Any, Optional, cast + +import dataclasses +import functools +import json +import os +import sys +import subprocess +import traceback +from enum import Enum + +from PyQt5 import (QtCore, QtWidgets, QtGui, QtNetwork, QtDBus, QtOpenGL, + QtPrintSupport, QtSql, QtTest, QtXml) +try: + import libcst as cst + import libcst.matchers as matchers +except ImportError: + raise ImportError('You need libcst to run the missing stubs generation\n' + 'Please run the command:\n\tpython -m pip install libcst') + + +USAGE = '''Usage 1: {prog} analyse_grep_results + Process the to extract all the qflag location information. Generates + two output: + - qflags_modules_analysis.json : a general file describing which qflag are suitable for processing + - qflags_to_process.json: a list of qflag ready to process with the next command. + +Usage 2: {prog} gen_qflag_stub (|all) (--auto-commit) + Using file qflag_to_process.json, process qflags and modify the PyQt modules. + The output of this processing is available in qflags_process_result.json + + If is not provided, defaults to 1. If "all" is provied, all qflags + are processed. + + If --auto-commit is specified, a git commit is performed after each successful QFlag validation + +'''.format(prog=sys.argv[0]) + + +QTBASE_MODULES = { + 'QtCore': '../../PyQt5-stubs/QtCore.pyi', + 'QtWidgets': '../../PyQt5-stubs/QtWidgets.pyi', + 'QtGui': '../../PyQt5-stubs/QtGui.pyi', + 'QtNetwork': '../../PyQt5-stubs/QtNetwork.pyi', + 'QtDBus': '../../PyQt5-stubs/QtDBus.pyi', + 'QtOpenGL': '../../PyQt5-stubs/QtOpenGL.pyi', + 'QtPrintSupport': '../../PyQt5-stubs/QtPrintSupport.pyi', + 'QtSql': '../../PyQt5-stubs/QtSql.pyi', + 'QtTest': '../../PyQt5-stubs/QtTest.pyi', + 'QtXml': '../../PyQt5-stubs/QtXml.pyi', +} + +def log_progress(s: str) -> None: + print('>>>>>>>>>>>>>>', s) + +@dataclasses.dataclass +class QFlagLocationInfo: + + # qflag and enum name used in the QDECLARE() grep line + qflag_class: str + enum_class: str + + # sometimes, human help is needed to identify a qflag/enum pair + human_hint_qflag_full_class_name: str = '' + human_hint_enum_full_class_name: str = '' + + # one or more grep lines where this qflag name has been found + grep_line: Tuple[str] = dataclasses.field(default_factory=tuple) + + # full class name (including nesting classes) generated in a second pass + qflag_full_class_name: str = '' + enum_full_class_name: str = '' + enum_value1: str = '' + enum_value2: str = '' + + # number of occurence in this module + module_count: int = 0 + + # index of occurence in this module + module_idx: int = -1 + + # module name and path + module_name: str = '' + module_path: str = '' + + # specific behavior of some QFlag classes varies slightly + # this helps to define the exact behavior + or_converts_to_multi: bool = True + or_int_converts_to_multi: bool = False + int_or_converts_to_multi: bool = True + + +def json_encode_qflaglocationinfo(flag_loc_info: object) -> Union[object, Dict[str, Any]]: + """Encode the QFlagClassLoationInfo into a format suitable for json export (a dict)""" + if not isinstance(flag_loc_info, QFlagLocationInfo): + # oups, we don't know how to encode that + return flag_loc_info + + d = dataclasses.asdict(flag_loc_info) + # when returning the result of the grep analysis, we want only a specific subset + # of the datablass fields + del d["or_converts_to_multi"] + del d["or_int_converts_to_multi"] + del d["int_or_converts_to_multi"] + + return d + + +def identify_qflag_location(fname_grep_result: str, + qt_modules: Dict[str, str], + ) -> List[ QFlagLocationInfo ]: + """Parses the grep results to extract each qflag, and then look into all Qt modules + to see where the flag is located. + + Return a list of QFlagLocationInfo indicating in which module the flag has been located. + """ + # the file defining the qflag implementation, to be skipped when performing QDECLARE analysis + QFLAG_SRC = 'src\\corelib\\global\\qflags.h' + + parsed_qflags = {} # type: Dict[ Tuple[str, str], QFlagLocationInfo ] + with open(fname_grep_result) as f: + for l in f.readlines()[:]: + grep_line = l.strip() + if len(grep_line) == 0: + continue + qflag_fname, qflag_declare_stmt = [s.strip(' \t\n') for s in grep_line.split(':')] + if qflag_fname == QFLAG_SRC: + # do not include actual implementation of qflags + continue + assert 'Q_DECLARE_FLAGS' in qflag_declare_stmt + s = qflag_declare_stmt[qflag_declare_stmt.index('(')+1:qflag_declare_stmt.index(')')] + qflag_class, enum_class = [v.strip(' ') for v in s.split(',')] + if (qflag_class, enum_class) in parsed_qflags: + # we already have one similar name in our DB + # just extend the grep line then + parsed_qflags[(qflag_class, enum_class)].grep_line += (grep_line,) + else: + parsed_qflags[(qflag_class, enum_class)] = QFlagLocationInfo(qflag_class, enum_class, grep_line=(grep_line,)) + + # fill up modules with content + qt_modules_content = [ (mod_name, open(mod_stub_path, encoding='utf8').read()) + for (mod_name, mod_stub_path) in qt_modules.items()] + + # associate a qflag enum/class with a mapping from module to QFlagLocationInfo + module_mapping: Dict[ Tuple[str, str], Dict[str, QFlagLocationInfo]] = {} + + for qflag_key, flag_info in parsed_qflags.items(): + decl_qflag_class = 'class %s(sip.simplewrapper' % flag_info.qflag_class + decl_enum_class = 'class %s(int' % flag_info.enum_class + for mod_name, mod_content in qt_modules_content: + + if decl_qflag_class in mod_content and decl_enum_class in mod_content: + # we have found one module + # print('Adding QFlags %s to module %s' % (flag_info.qflag_class, mod_name)) + if qflag_key not in module_mapping: + module_mapping[qflag_key] = {} + else: + pass + mod_map = module_mapping[qflag_key] + + if mod_name in mod_map: + raise ValueError('Not supposed to happen!') + + # register the number of time where this flag happens in this specific module + mod_map[mod_name] = dataclasses.replace(flag_info) # this means a fresh copy of flag_info + mod_map[mod_name].module_count = 1 + + count_qflag_class = mod_content.count(decl_qflag_class) + count_enum_class = mod_content.count(decl_enum_class) + if count_qflag_class > 1 and count_enum_class > 1: + # print('QFlag present more than once, adding it more than once') + mod_map[mod_name].module_count += min(count_qflag_class, count_enum_class) - 1 + + # now, we flatten the structure by recreating one QFlagLocationInfo per module location + + all_qflags: List[QFlagLocationInfo] = [] + for mod_map in module_mapping.values(): + for mod_name, flag_info in mod_map.items(): + idx = 0 + while idx < flag_info.module_count: + all_qflags.append(dataclasses.replace(flag_info, module_idx=idx, + module_name=mod_name, + module_path=qt_modules[mod_name])) + idx += 1 + + return all_qflags + + +def group_qflags(qflag_location: List[QFlagLocationInfo] ) -> Dict[str, List[QFlagLocationInfo]]: + """Group the QFlags into the following groups (inside a dictionnary): + * flag_and_module_identified: this flag is present once in one module exactly. + * flag_without_module: this flag is not present in any modules at all. + + The first group is suitable for automatic processing. + The last group reflects the QFlags not exported to PyQt or coming from modules not present in PyQt + """ + d = { + 'flag_and_module_identified': [ + flag_info for flag_info in qflag_location + if flag_info.module_name != '' + ], + 'flag_without_module': [ + flag_info for flag_info in qflag_location + if flag_info.module_name == '' + ], + } + + return d + + +def extract_qflags_to_process(qflags_modules_analysis_json: str, + qflags_to_process_json: str, + ) -> None: + """Take the json file as input describing qflags and their modules and output a json file of qflags planned to be processed. + + The qflags which are located in a single module will be selected for further processing. + The others are marked as skipped with a proper reason. + """ + with open(qflags_modules_analysis_json) as f: + d = json.load(f) + + result = { + '__': 'This file can be adjusted manually by a human prior to being processed by the tool', + 'qflags_to_process': [], + 'qflags_to_skip': [], + } + + for flag_info in d['flag_without_module']: + cast(List, result['qflags_to_skip']).append( + { + 'qflag_class': flag_info['qflag_class'], + 'enum_class': flag_info['enum_class'], + 'skip_reason': 'QFlag not found', + } + ) + + for flag_info in d['flag_and_module_identified']: + cast(List, result['qflags_to_process']).append( flag_info ) + + with open(qflags_to_process_json, 'w') as f: + json.dump(result, f, indent=4) + + +def process_qflag(qflag_to_process_json: str, qflag_result_json: str, auto_commit: bool) -> int: + """Read the qflags to process from the json file + + Process one qflag, by either: + * identifying that this flag is already processed and add the flag to qflags_alraedy_done + * identifying a reason why this flag can't be processed and adding the flag to qflags_processed_error + * performing the qflag ajustment process: + * generate a test file for this qflag usage + * change the .pyi module for this qflag for supporting all the qflag operations + * run pytest on the result + * run mypy on the result + * run the tox on result + * add the flag to qflag_processed_done + + * auto_commit: if True, a git commit is performed after each successful QFlag validation + + Return number of remaining flags to process (0 when everything done) + """ + + with open(qflag_to_process_json) as f: + d = json.load(f) + + qflags_to_process = d['qflags_to_process'] + + result_json: Dict[str, List[Dict]] = { + 'qflag_already_done': [], + 'qflag_processed_done': [], + 'qflag_process_error': [], + } + + if os.path.exists(qflag_result_json): + with open(qflag_result_json, 'r') as f: + result_json = json.loads(f.read()) + + def qflag_already_processed(flag_info: QFlagLocationInfo) -> bool: + """Return True if the qflag is already included in one of the result lists + of result_json""" + flag_desc = (flag_info.module_name, flag_info.module_idx, + flag_info.qflag_class, flag_info.enum_class) + already_done_set = set( (flag_info_dict['module_name'], + flag_info_dict['module_idx'], + flag_info_dict['qflag_class'], + flag_info_dict['enum_class']) + for flag_info_dict in result_json['qflag_already_done']) + processed_done_set = set( (flag_info_dict['module_name'], + flag_info_dict['module_idx'], + flag_info_dict['qflag_class'], + flag_info_dict['enum_class']) + for flag_info_dict in result_json['qflag_processed_done']) + process_error_set = set( (flag_info_dict['module_name'], + flag_info_dict['module_idx'], + flag_info_dict['qflag_class'], + flag_info_dict['enum_class']) + for flag_info_dict in result_json['qflag_process_error']) + if flag_desc in already_done_set or flag_desc in processed_done_set or flag_desc in process_error_set: + return True + return False + + while len(qflags_to_process) != 0: + flag_info_dict = qflags_to_process.pop(0) + flag_info = QFlagLocationInfo(**flag_info_dict) + flag_info.grep_line = tuple(flag_info.grep_line) # to make it hashable + if not qflag_already_processed(flag_info): + break + else: + # we have exhausted the list of qflag to process + return 0 + + log_progress('Processing %s and %s in module %s, index %d' % + (flag_info.qflag_class, flag_info.enum_class, flag_info.module_name, flag_info.module_idx)) + + # check that the qflag is actually in the module + gen_result, error_msg, old_mod_content = generate_missing_stubs(flag_info) + flag_info_dict = dataclasses.asdict(flag_info) + test_qflag_fname = gen_test_fname(flag_info) + + # Note that flag_info has been modified in-place with additional info: + # enum_value1, enum_value2, full_enum_class_name, full_qflag_class_name + if gen_result == QFlagGenResult.CodeModifiedSuccessfully: + generate_qflag_test_file(flag_info) + log_progress('Running pytest %s' % test_qflag_fname) + p = subprocess.run(['pytest', '-v', '--capture=no', test_qflag_fname]) + if p.returncode != 0: + error_msg += 'pytest failed:\n' + # Re-run the same command to capture the output in the error message + # in the first run, the stdout/stderr was simply displayed and not captured + # here, we want to capture it and not display it + p = subprocess.run(['pytest', '-v', '--capture=no', test_qflag_fname], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf8') + error_msg += p.stdout + gen_result = QFlagGenResult.ErrorDuringProcessing + log_progress('Restoring module content') + with open(flag_info.module_path, 'w') as f: + f.write(old_mod_content) + os.unlink(test_qflag_fname) + else: + log_progress('Running mypy %s' % test_qflag_fname) + p = subprocess.run(['mypy', test_qflag_fname]) + if p.returncode != 0: + error_msg += 'mypy failed\n' + # Re-run the same command to capture the output in the error message + # in the first run, the stdout/stderr was simply displayed and not captured + # here, we want to capture it and not display it + p = subprocess.run(['mypy', test_qflag_fname], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf8') + error_msg += p.stdout + gen_result = QFlagGenResult.ErrorDuringProcessing + log_progress('Restoring module content') + with open(flag_info.module_path, 'w') as f: + f.write(old_mod_content) + os.unlink(test_qflag_fname) + else: + log_progress('validation completed successfully') + result_json['qflag_processed_done'].append(flag_info_dict) + + if auto_commit: + log_progress('Performing git commit') + subprocess.run(['git', 'add', test_qflag_fname, flag_info.module_path]) + subprocess.run(['git', 'commit', '-m', 'QFlag operations for %s, %s in module %s' % + (flag_info.qflag_full_class_name, flag_info.enum_full_class_name, flag_info.module_name)]) + + if gen_result == QFlagGenResult.CodeAlreadyModified: + # qflag methods are already there, check that the test filename is here too + if os.path.exists(test_qflag_fname): + log_progress('QFlag %s %s already supported by %s' % (flag_info.qflag_class, + flag_info.enum_class, + flag_info.module_name)) + result_json['qflag_already_done'].append(flag_info_dict) + else: + error_msg += 'QFlag methods presents but test file %s is missing\n' % test_qflag_fname + gen_result = QFlagGenResult.ErrorDuringProcessing + + if gen_result == QFlagGenResult.ErrorDuringProcessing: + log_progress('Error during processing of QFlag %s %s' % (flag_info.qflag_class, + flag_info.enum_class)) + print(error_msg) + flag_info_dict['error'] = error_msg.splitlines() + result_json['qflag_process_error'].append(flag_info_dict) + + # save our processing result + with open(qflag_result_json, 'w') as f: + json.dump(result_json, f, indent=4) + + # return True to indicate that more flags may be processed + log_progress('.') + return len(qflags_to_process) + + + +class QFlagGenResult(Enum): + """Enum indicating the result of generating the possibly missing stubs on the qflag classes""" + CodeModifiedSuccessfully = 0 + CodeAlreadyModified = 1 + ErrorDuringProcessing = 2 + + +def generate_missing_stubs(flag_info: 'QFlagLocationInfo') -> Tuple[QFlagGenResult, str, str]: + """ + Check that the QFlag enum+class are present in the module and check whether they support + all the advanced QFlag operations. + + If they do not, generate the missing methods. + + The flag_info input is also extended with additional information: + * full qflag class name + * full enum class name + * enum value 1 + * enum value 2 + These are needed for generating a proper test file. I don't like in-place modification + but here, it's the simplest. + + The generation consists of: + + 1. On the enum class, add two methods: + class KeyboardModifier(int): + + def __or__ (self, other: 'Qt.KeyboardModifier') -> 'Qt.KeyboardModifiers': ... # type: ignore[override] + + def __ror__ (self, other: int) -> 'Qt.KeyboardModifiers': ... # type: ignore[override, misc] + + 2. On the qflag class, add one more overload of __init__() + + @typing.overload + + def __init__(self, f: int) -> None: ... + + 3. On the qflag class, add more methods: + + def __or__ (self, other: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier', int]) -> 'Qt.KeyboardModifiers': ... + + def __and__(self, other: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier', int]) -> 'Qt.KeyboardModifiers': ... + + def __xor__(self, other: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier', int]) -> 'Qt.KeyboardModifiers': ... + + def __ror__ (self, other: 'Qt.KeyboardModifier') -> 'Qt.KeyboardModifiers': ... + + def __rand__(self, other: 'Qt.KeyboardModifier') -> 'Qt.KeyboardModifiers': ... + + def __rxor__(self, other: 'Qt.KeyboardModifier') -> 'Qt.KeyboardModifiers': ... + + Returns a tuple of (QFlagGenResult, error_msg, mod_content): + * CodeModifiedSuccessfully: + All modifications to the code of the module have been performed successfully. + Error message is empty. + mod_content contains the full text of the module. If when performing verifications on this + change, it turns out that the change is not valid, you can restore the module to its + previous content using mod_content + + * CodeAlreadyModified: + All modifications to the code were already done, no processing done. + Error message also indicates this information. + mod_content is empty (not useful) + + * ErrorDuringProcessing: + Some error occured during the processing, such as some modifications were partially done, + class not found, class found multiple times, ... + + The detail of the error is provided in the second argument of the return value. + mod_content is empty (not useful) +""" + log_progress('Opening module %s' % flag_info.module_name) + with open(flag_info.module_path) as f: + mod_content = f.read() + + log_progress('Parsing module %s' % flag_info.module_name) + mod_cst = cst.parse_module(mod_content) + + log_progress('Looking for class %s and %s in module %s, index %d' % + (flag_info.qflag_class, flag_info.enum_class, flag_info.module_name, flag_info.module_idx)) + if len(flag_info.human_hint_enum_full_class_name) and len(flag_info.human_hint_qflag_full_class_name): + log_progress('Using hints: %s and %s' % (flag_info.human_hint_enum_full_class_name, flag_info.human_hint_qflag_full_class_name)) + visitor = QFlagAndEnumFinder(flag_info.enum_class, flag_info.qflag_class, + flag_info.module_count, flag_info.module_idx, + flag_info.human_hint_enum_full_class_name, + flag_info.human_hint_qflag_full_class_name, + ) + mod_cst.visit(visitor) + + # storing the enum_values + full class name for further usage + flag_info.enum_full_class_name = visitor.enum_class_full_name + flag_info.enum_value1 = visitor.enum_value1 + flag_info.enum_value2 = visitor.enum_value2 + flag_info.qflag_full_class_name = visitor.qflag_class_full_name + + # evaluate exact behavior of QFlag + try: + flag_info.or_converts_to_multi = not eval('''type({qtmodule}.{oneFlagName}.{value1} | {qtmodule}.{oneFlagName}.{value2}) == int'''.format( + value1=flag_info.enum_value1, value2=flag_info.enum_value2, + qtmodule=flag_info.module_name, + oneFlagName=flag_info.enum_full_class_name)) + except Exception as exc: + return (QFlagGenResult.ErrorDuringProcessing, traceback.format_exc(), '') + + flag_info.or_int_converts_to_multi = not eval('''type({qtmodule}.{oneFlagName}.{value1} | 33) == int'''.format( + value1=flag_info.enum_value1, qtmodule = flag_info.module_name, oneFlagName = flag_info.enum_full_class_name)) + flag_info.int_or_converts_to_multi = not eval('''type(33 | {qtmodule}.{oneFlagName}.{value1}) == int'''.format( + value1=flag_info.enum_value1, qtmodule = flag_info.module_name, oneFlagName = flag_info.enum_full_class_name)) + + if visitor.enum_class_full_name == '': + return (QFlagGenResult.ErrorDuringProcessing, 'Could not locate class %s' % visitor.enum_class_name, '') + + if visitor.qflag_class_full_name == '': + return (QFlagGenResult.ErrorDuringProcessing, 'Could not locate class %s' % visitor.qflag_class_name, '') + + if (visitor.enum_methods_present, visitor.qflag_method_present) == (MethodPresent.All, MethodPresent.All): + return (QFlagGenResult.CodeAlreadyModified, visitor.error_msg, '') + + if (visitor.enum_methods_present, visitor.qflag_method_present) == (MethodPresent.All, MethodPresent.Not): + visitor.error_msg += 'Enum methods are present but not QFlag methods\n' + + if (visitor.enum_methods_present, visitor.qflag_method_present) == (MethodPresent.Not, MethodPresent.All): + # this is ok if enum does not need any special method + if (flag_info.or_converts_to_multi + or flag_info.int_or_converts_to_multi + or flag_info.or_int_converts_to_multi): + # this means __or__ or __ror__ must be present, we have an error + visitor.error_msg += 'QFlag methods are present but not Enum methods\n' + + if visitor.error_msg: + return (QFlagGenResult.ErrorDuringProcessing, visitor.error_msg, '') + + log_progress('Found %s and %s' % (flag_info.qflag_full_class_name, flag_info.enum_full_class_name)) + + print('OR behavior:') + print('- or_converts_to_multi: ', flag_info.or_converts_to_multi) + print('- or_int_converts_to_multi: ', flag_info.or_int_converts_to_multi) + print('- int_or_converts_to_multi: ', flag_info.int_or_converts_to_multi) + + log_progress('Updating module %s by adding new methods' % flag_info.module_name) + transformer = QFlagAndEnumUpdater(visitor.enum_class_name, visitor.enum_class_full_name, + visitor.qflag_class_name, visitor.qflag_class_full_name, flag_info.module_idx, + flag_info.human_hint_enum_full_class_name, + flag_info.human_hint_qflag_full_class_name, + flag_info.or_converts_to_multi, + flag_info.or_int_converts_to_multi, + flag_info.int_or_converts_to_multi) + updated_mod_cst = mod_cst.visit(transformer) + + if transformer.error_msg: + return (QFlagGenResult.ErrorDuringProcessing, visitor.error_msg, '') + + log_progress('Saving updated module %s' % flag_info.module_name) + with open(flag_info.module_path, 'w') as f: + f.write(updated_mod_cst.code) + + return (QFlagGenResult.CodeModifiedSuccessfully, '', mod_content) + + +class MethodPresent(Enum): + """An enum to reflect if a method is already present or not""" + Unset = 0 + All = 1 + Not = 2 + Partial = 3 + + +class QFlagAndEnumFinder(cst.CSTVisitor): + + def __init__(self, enum_class: str, qflag_class: str, + module_count: int, module_idx: int, + human_hint_enum_full_class_name: str = '', + human_hint_qflag_full_class_name: str = '', + ) -> None: + super().__init__() + + # used internally to generate the full class name + self.full_name_stack: List[str] = [] + + # the class name we are looking for + self.enum_class_name = enum_class + self.qflag_class_name = qflag_class + + # human help for finding the class + if human_hint_enum_full_class_name: + self.human_hint_enum_full_class_name = human_hint_enum_full_class_name.split('.') + else: + self.human_hint_enum_full_class_name = '' + + if human_hint_qflag_full_class_name: + self.human_hint_qflag_full_class_name = human_hint_qflag_full_class_name.split('.') + else: + self.human_hint_qflag_full_class_name = human_hint_qflag_full_class_name + + # the number of expected occurences in this module of this flag + self.module_count = module_count + + # the index of the flag in the module which we are looking for + # useful if there are multiple same name flags + self.module_idx = module_idx + + # our internal index for finding this class + self.visit_enum_idx = -1 + self.visit_qflag_idx = -1 + + # the class full name + self.enum_class_full_name = '' + self.qflag_class_full_name = '' + + # the name of two values of the enum class + self.enum_value1 = '' + self.enum_value2 = '' + + # the node of the class, for debugging purpose + + # when filled, set to one of the MethodPresent values + self.enum_methods_present = MethodPresent.Unset + self.qflag_method_present = MethodPresent.Unset + + # set when enum_methods_present is set to partial, to add more contect information + self.error_msg = '' + + + def visit_ClassDef(self, node: cst.ClassDef) -> Optional[bool]: + self.full_name_stack.append( node.name.value ) + if node.name.value == self.enum_class_name: + self.visit_enum_idx += 1 + found_enum_class = False + if self.human_hint_enum_full_class_name: + if self.human_hint_enum_full_class_name == self.full_name_stack: + found_enum_class = True + else: + if self.visit_enum_idx > self.module_count: + self.error_msg = 'class %s found too many times: %d\n' % (self.enum_class_name, self.visit_enum_idx) + return None + + if self.visit_enum_idx == self.module_idx: + # we found the index we are looking for + found_enum_class = True + + if found_enum_class: + if self.check_enum_method_present(node): + self.enum_class_full_name = '.'.join(self.full_name_stack) + self.collect_enum_values(node) + return None + + elif node.name.value == self.qflag_class_name: + self.visit_qflag_idx += 1 + found_qflag_class = False + if self.human_hint_qflag_full_class_name: + if self.human_hint_qflag_full_class_name == self.full_name_stack: + found_qflag_class = True + else: + if self.visit_qflag_idx > self.module_count: + self.error_msg = 'class %s found too times: %d\n' % (self.qflag_class_name, self.visit_qflag_idx) + return None + + if self.visit_qflag_idx == self.module_idx: + # we found the index we are looking for + found_qflag_class = True + + if found_qflag_class: + if self.check_qflag_method_present(node): + self.qflag_class_full_name = '.'.join(self.full_name_stack) + return None + + return None + + + def check_enum_method_present(self, enum_node: cst.ClassDef) -> bool: + """Check if the class contains method __or__ and __ror__ with one argument and if class + inherit from int""" + if len(enum_node.bases) == 0 or enum_node.bases[0].value.value != 'int': + # class does not inherit from int, not the one we are looking for + return False + has_or = matchers.findall(enum_node.body, matchers.FunctionDef(name=matchers.Name('__or__'))) + has_ror = matchers.findall(enum_node.body, matchers.FunctionDef(name=matchers.Name('__ror__'))) + self.enum_methods_present = { + 0: MethodPresent.Not, + 1: MethodPresent.Partial, + 2: MethodPresent.All + }[len(has_or) + len(has_ror)] + + if self.enum_methods_present == MethodPresent.Partial: + if has_or: + args = ('__or__', '__ror__') + else: + args = ('__ror__', '__or__') + + self.error_msg += 'class %s, method %s present without method %s\n' % ((self.enum_class_full_name,)+args) + + return True + + + def collect_enum_values(self, enum_node: cst.ClassDef) -> None: + """Collect two actual values for the enum and store them into self.enum_value1 and enum_value2 + """ + # find all lines consisting of an assignment to an ellipsis, like "AlignLeft = ..." + enum_values = matchers.findall(enum_node.body, matchers.SimpleStatementLine( + body=[matchers.Assign(value=matchers.Ellipsis())])) + if len(enum_values) == 0: + self.error_msg += 'class %s, could not find any enum values\n' % self.enum_class_full_name + return + + self.enum_value1 = enum_values[0].body[0].targets[0].target.value + if len(enum_values) > 1: + self.enum_value2 = enum_values[1].body[0].targets[0].target.value + else: + # it works find if both values are the same so don't bother + self.enum_value2 = self.enum_value1 + + + def check_qflag_method_present(self, qflag_node: cst.ClassDef) -> bool: + """Check if the class contains method: + def __or__ + def __and__ + def __xor__ + def __ror__ + def __rand__ + def __rxor__ + + with one argument. + + def __init__(self, f: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier']) -> None: + def __init__(self, f: typing.Union['Qt.KeyboardModifiers', 'Qt.KeyboardModifier', int]) -> None: + """ + if (len(qflag_node.bases) == 0 + or not matchers.matches(qflag_node.bases[0], + matchers.Arg(value=matchers.Attribute(value=matchers.Name('sip'), + attr=matchers.Name('simplewrapper') + ) + ) + ) + ): + # 'Class does not inherit from sip.simplewrapper' + return False + + has_method = [ + (m, matchers.findall(qflag_node.body, matchers.FunctionDef(name=matchers.Name(m)))) + for m in ('__or__', '__and__', '__xor__', '__ror__', '__rxor__', '__rand__') + ] + + if all(has_info[1] for has_info in has_method): + # all method presents + self.qflag_method_present = MethodPresent.All + return True + + if all(not has_info[1] for has_info in has_method): + # all method absent + self.qflag_method_present = MethodPresent.Not + return True + + self.qflag_method_present = MethodPresent.Partial + + for m_name, m_has in has_method: + if m_has: + self.error_msg += 'class %s, method %s present without all others\n' \ + % ((self.qflag_class_full_name, m_name)) + else: + self.error_msg += 'class %s, method %s missing\n' \ + % ((self.qflag_class_full_name, m_name)) + return True + + + def visit_FunctionDef(self, node: cst.FunctionDef) -> Optional[bool]: + self.full_name_stack.append( node.name.value ) + return None + + def leave_ClassDef(self, node: cst.ClassDef) -> None: + self.full_name_stack.pop() + + def leave_FunctionDef(self, node: cst.FunctionDef) -> None: + self.full_name_stack.pop() + + +class QFlagAndEnumUpdater(cst.CSTTransformer): + + def __init__(self, enum_class: str, enum_full_name: str, qflag_class: str, qflag_full_name: str, + module_idx: int, + human_hint_enum_full_class_name: str, + human_hint_qflag_full_class_name: str, + or_converts_to_multi: bool, + or_int_converts_to_multi: bool, + int_or_converts_to_multi: bool) -> None: + super().__init__() + + # used internally to generate the full class name + self.full_name_stack: List[str] = [] + + self.error_msg = '' + + # the class name we are looking for + self.enum_class = enum_class + self.qflag_class = qflag_class + self.enum_full_name = enum_full_name + self.qflag_full_name = qflag_full_name + + # human help for finding the class + self.human_hint_enum_full_class_name = '' + if human_hint_enum_full_class_name: + self.human_hint_enum_full_class_name = human_hint_enum_full_class_name.split('.') + self.human_hint_qflag_full_class_name = '' + if human_hint_qflag_full_class_name: + self.human_hint_qflag_full_class_name = human_hint_qflag_full_class_name.split('.') + + # the index in this module of the class we are looking for + self.module_idx = module_idx + + # our current count of visit + self.visit_enum_idx = -1 + self.visit_qflag_idx = -1 + + self.or_converts_to_multi = or_converts_to_multi + self.or_int_converts_to_multi = or_int_converts_to_multi + self.int_or_converts_to_multi = int_or_converts_to_multi + + # set when enum_methods_present is set to partial, to add more contect information + self.error_msg = '' + + def visit_ClassDef(self, node: cst.ClassDef) -> Optional[bool]: + self.full_name_stack.append( node.name.value ) + return None + + def visit_FunctionDef(self, node: cst.FunctionDef) -> Optional[bool]: + self.full_name_stack.append( node.name.value ) + return None + + def leave_FunctionDef(self, node: cst.FunctionDef, updated_node: cst.FunctionDef) -> cst.FunctionDef: + self.full_name_stack.pop() + return updated_node + + def leave_ClassDef(self, original_node: cst.ClassDef, updated_node: cst.ClassDef) -> cst.ClassDef: + found_enum_class = False + found_qflag_class = False + + if self.human_hint_enum_full_class_name: + if self.human_hint_enum_full_class_name == self.full_name_stack: + found_enum_class = True + else: + if original_node.name.value == self.enum_class: + self.visit_enum_idx += 1 + if self.visit_enum_idx == self.module_idx: + found_enum_class = True + + if self.human_hint_qflag_full_class_name: + if self.human_hint_qflag_full_class_name == self.full_name_stack: + found_qflag_class = True + else: + if original_node.name.value == self.qflag_class: + self.visit_qflag_idx += 1 + if self.visit_qflag_idx == self.module_idx: + found_qflag_class = True + + self.full_name_stack.pop() + + if found_enum_class: + return self.transform_enum_class(original_node, updated_node) + + if found_qflag_class: + return self.transform_qflag_class(original_node, updated_node) + + return updated_node + + + def transform_enum_class(self, original_node: cst.ClassDef, updated_node: cst.ClassDef) -> cst.ClassDef: + """Add the two methods __or__ and __ror__ to the class body""" + + # we keep comments separated to align them properly in the final file + or_behavior = (self.or_converts_to_multi, self.or_int_converts_to_multi, self.int_or_converts_to_multi) + if or_behavior == (True, False, True): + new_methods_parts = ( + ("def __or__ (self, other: '{enum}') -> '{qflag}': ...", "# type: ignore[override]\n"), + ("def __ror__ (self, other: int) -> '{qflag}': ...", "# type: ignore[override, misc]\n\n") + ) + elif or_behavior == (True, True, True): + new_methods_parts = ( + ("def __or__ (self, other: typing.Union[int, '{enum}']) -> '{qflag}': ...", "# type: ignore[override]\n"), + ("def __ror__ (self, other: int) -> '{qflag}': ...", "# type: ignore[override, misc]\n\n") + ) + elif or_behavior == (False, False, False): + # no changes needed + return updated_node + else: + raise ValueError('Unsupported or behavior:', or_behavior) + + + # fill the class names + new_methods_filled = tuple( + (code.format(enum=self.enum_full_name, qflag=self.qflag_full_name), comment) + for code, comment in new_methods_parts + ) + + # now calculate the proper spacing to have aligned comments + max_code_len = max(len(code) for code, comment in new_methods_filled) + new_methods_spaced = tuple( + code + ' '*(4+max_code_len-len(code)) + comment + for code, comment in new_methods_filled + ) + new_methods_cst = tuple(cst.parse_statement(s) for s in new_methods_spaced) + return updated_node.with_changes(body=updated_node.body.with_changes(body= + new_methods_cst \ + + (updated_node.body.body[0].with_changes(leading_lines= + updated_node.body.body[0].leading_lines + + (cst.EmptyLine(),)),) \ + + updated_node.body.body[1:] ) ) + + + def transform_qflag_class(self, original_node: cst.ClassDef, updated_node: cst.ClassDef) -> cst.ClassDef: + """ + On the qflag class, add one more overload __init__() and add more methods + + @typing.overload + + def __init__(self, f: int) -> None: ... + """ + init_methods = matchers.findall(updated_node.body, matchers.FunctionDef(name=matchers.Name('__init__'))) + if len(init_methods) == 1: + # we do not handle the case where there is only one init function + # to handle it, we would need to do the following: + # * add an @typing.overload to the current init function + # * add a new init function + # + # This is not difficult, it's just that I don't think we have such cases + self.error_msg += 'Only one __init__ method in QFlag class %s, do not know how to transform it\n' % self.qflag_full_name + return updated_node + + # find the last __init__() method index + last_init_idx = 0 + nb_init_found = 0 + for i, body_element in enumerate(updated_node.body.body): + if matchers.matches(body_element, matchers.FunctionDef(name=matchers.Name('__init__'))): + nb_init_found += 1 + if nb_init_found == len(init_methods): + last_init_idx = i + break + + if last_init_idx == 0: + self.error_msg += 'No __init__ method found in class %s' % self.qflag_full_name + return updated_node + + + cst_init = cst.parse_statement( '@typing.overload\ndef __init__(self, f: int) -> None: ...' ) + updated_node = updated_node.with_changes(body=updated_node.body.with_changes(body= + tuple(updated_node.body.body[:last_init_idx+1]) + + (cst_init,) + + tuple(updated_node.body.body[last_init_idx+1:]) + ) + ) + + new_methods = ( + "def __or__ (self, other: typing.Union['{qflag}', '{enum}', int]) -> '{qflag}': ...", + "def __and__(self, other: typing.Union['{qflag}', '{enum}', int]) -> '{qflag}': ...", + "def __xor__(self, other: typing.Union['{qflag}', '{enum}', int]) -> '{qflag}': ...", + "def __ror__ (self, other: '{enum}') -> '{qflag}': ...", + "def __rand__(self, other: '{enum}') -> '{qflag}': ...", + "def __rxor__(self, other: '{enum}') -> '{qflag}': ...", + ) + new_methods_cst = tuple( + cst.parse_statement(s.format(enum=self.enum_full_name, qflag=self.qflag_full_name)) + for s in new_methods + ) + return updated_node.with_changes(body=updated_node.body.with_changes(body= + tuple(updated_node.body.body) + new_methods_cst ) ) + + + +@functools.lru_cache(maxsize=1) +def read_qflag_test_template(template_fname: str) -> Tuple[List[str], List[str], List[str]]: + """Return the source of the template for generating qflags test. + + Return 3 parts as a list of strings: + - the first part should be unmodified + - the second part should be replaced for a specific QFlag class + - the third part should be unmodified + """ + + # the markers inside the above template to identify the parts to replace + MARKER_SPECIFIC_START = '### Specific part' + MARKER_SPECIFIC_END = '### End of specific part' + + with open(template_fname) as f: + lines = f.readlines() + + source_part_before, source_part_middle, source_part_after = [], [], [] + fill_middle, fill_after = False, False + for l in lines: + if fill_after: + source_part_after.append(l) + continue + + if fill_middle: + if MARKER_SPECIFIC_END in l: + fill_after = True + source_part_after.append(l) + continue + + source_part_middle.append(l) + continue + + source_part_before.append(l) + if MARKER_SPECIFIC_START in l: + fill_middle = True + + return source_part_before, source_part_middle, source_part_after + + +def gen_test_fname(fli: QFlagLocationInfo) -> str: + """Generate the name of the test file which will verify this qflag""" + return 'test_{fli.module_name}_{fli.qflag_class}_{fli.enum_class}.py'.format(fli=fli) + + +def generate_qflag_test_file(flag_info: QFlagLocationInfo) -> None: + """Generate a qflag test file. + + The filename is inferred from flag_info using gen_test_fname() + """ + + # the template after which we model all generated qflag tests + TEMPLATE_QFLAGS_TESTS = 'qflags_test_template.py' + + test_qflag_fname = gen_test_fname(flag_info) + generic_part_before, _replacable_part, generic_part_after = read_qflag_test_template(TEMPLATE_QFLAGS_TESTS) + + with open(test_qflag_fname, 'w') as f: + f.writelines(generic_part_before) + + # replace the repplacable_part with code dedicated to our qflag + f.write('''# file generated from {source} for QFlags class "{multiFlagName}" and flag class "{oneFlagName}" +from PyQt5 import {qtmodule} + +OneFlagClass = {qtmodule}.{oneFlagName} +MultiFlagClass = {qtmodule}.{multiFlagName} + +oneFlagRefValue1 = {qtmodule}.{oneFlagName}.{oneFlagValue1} +oneFlagRefValue2 = {qtmodule}.{oneFlagName}.{oneFlagValue2} + +OR_CONVERTS_TO_MULTI: Literal[{or_converts_to_multi}] = {or_converts_to_multi} +OR_INT_CONVERTS_TO_MULTI: Literal[{or_int_converts_to_multi}] = {or_int_converts_to_multi} +INT_OR_CONVERTS_TO_MULTI: Literal[{int_or_converts_to_multi}] = {int_or_converts_to_multi} +'''.format(source=TEMPLATE_QFLAGS_TESTS, + multiFlagName=flag_info.qflag_full_class_name, + oneFlagName=flag_info.enum_full_class_name, + oneFlagValue1=flag_info.enum_value1, + oneFlagValue2=flag_info.enum_value2, + qtmodule=flag_info.module_name, + or_converts_to_multi=flag_info.or_converts_to_multi, + or_int_converts_to_multi=flag_info.or_int_converts_to_multi, + int_or_converts_to_multi=flag_info.int_or_converts_to_multi + )) + f.writelines(generic_part_after) + log_progress('Test file generated: %s' % test_qflag_fname) + + +def generate_qflags_to_process(qt_qflag_grep_result_fname): + """Run the generation process from the grep output parsing to the generation of json file listing the flags to process""" + location_qflags = identify_qflag_location(qt_qflag_grep_result_fname, QTBASE_MODULES) + log_progress('%d qflags extracted from grep file' % len(location_qflags)) + qflags_groups = group_qflags(location_qflags) + log_progress('%d qflags ready to be processed' % len(qflags_groups['flag_and_module_identified'])) + + qflags_modules_analysis_json = 'qflags_modules_analysis.json' + # put our intermediate classification into a json file for human review + with open(qflags_modules_analysis_json, 'w') as f: + json.dump(qflags_groups, f, indent=4, default=json_encode_qflaglocationinfo) + log_progress('QFlag analysis saved to: %s' % qflags_modules_analysis_json) + + qflags_to_process_json = 'qflags_to_process.json' + extract_qflags_to_process(qflags_modules_analysis_json, qflags_to_process_json) + log_progress('qflag file ready to process: %s' % qflags_to_process_json) + + +def regen_test_files(qflag_process_results: str) -> None: + with open(qflag_process_results) as f: + results_content = f.read() + results = json.loads(results_content) + + flags_to_process = results['qflag_processed_done'] + results['qflag_already_done'] + log_progress('%d test files to regenerate' % len(flags_to_process)) + for flag_info_dict in flags_to_process: + flag_info = QFlagLocationInfo(**flag_info_dict) + test_qflag_fname = gen_test_fname(flag_info) + print('Updating', test_qflag_fname) + generate_qflag_test_file(flag_info) + + + +if __name__ == '__main__': + + if len(sys.argv) <= 1: + print(USAGE) + sys.exit(1) + + auto_commit = False + if '--auto-commit' in sys.argv: + auto_commit = True + + + if sys.argv[1] == 'gen_qflag_stub': + nb = 1 + process_all = False + if len(sys.argv) > 2: + if sys.argv[2] == 'all': + process_all = True + else: + nb = int(sys.argv[2]) + + qflags_to_process_json = 'qflags_to_process.json' + qflag_result_json = 'qflags_process_result.json' + more_available = -1 + while (nb > 0 or process_all) and (more_available == -1 or more_available > 0): + nb -= 1 + more_available = process_qflag(qflags_to_process_json, qflag_result_json, auto_commit) + if more_available: + log_progress('Still %d flags to process' % more_available) + log_progress('All qflags are processed.') + + elif sys.argv[1] == 'analyse_grep_results': + if len(sys.argv) <= 2: + print('Error, you must provide the filename of the grep results\n') + print(USAGE) + sys.exit(1) + + grep_fname = sys.argv[2] + generate_qflags_to_process(grep_fname) + + + elif sys.argv[1] == 'regen_test_files': + + if len(sys.argv) <= 2: + print('Error, you must provide the filename of the qflag-process-results\n') + print(USAGE) + sys.exit(1) + + qflag_process_results = sys.argv[2] + regen_test_files(qflag_process_results) + + else: + print('Error, invalid command line arguments\n') + print(USAGE) + sys.exit(1) + + diff --git a/tests/qflags/qflags_test_template.py b/tests/qflags/qflags_test_template.py new file mode 100644 index 00000000..e7af2d73 --- /dev/null +++ b/tests/qflags/qflags_test_template.py @@ -0,0 +1,267 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# This file is used as a source to generate all qflags related tests. The specific part +# changes for each test but the rest of the file is totally identical +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.WindowType +MultiFlagClass = QtCore.Qt.WindowFlags + +oneFlagRefValue1 = QtCore.Qt.WindowContextHelpButtonHint +oneFlagRefValue2 = QtCore.Qt.WindowMaximizeButtonHint + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/qflags_to_process.json b/tests/qflags/qflags_to_process.json new file mode 100644 index 00000000..9c7e56b7 --- /dev/null +++ b/tests/qflags/qflags_to_process.json @@ -0,0 +1,2193 @@ +{ + "__": "This file can be adjusted manually by a human prior to being processed by the tool", + "qflags_to_process": [ + { + "qflag_class": "RegisterOptions", + "enum_class": "RegisterOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\dbus\\qdbusconnection.h: Q_DECLARE_FLAGS(RegisterOptions, RegisterOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtDBus", + "module_path": "../../PyQt5-stubs/QtDBus.pyi" + }, + { + "qflag_class": "ConnectionCapabilities", + "enum_class": "ConnectionCapability", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\dbus\\qdbusconnection.h: Q_DECLARE_FLAGS(ConnectionCapabilities, ConnectionCapability)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtDBus", + "module_path": "../../PyQt5-stubs/QtDBus.pyi" + }, + { + "qflag_class": "FormatOptions", + "enum_class": "FormatOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\opengl\\qgl.h: Q_DECLARE_FLAGS(FormatOptions, FormatOption)", + "src\\gui\\kernel\\qsurfaceformat.h: Q_DECLARE_FLAGS(FormatOptions, FormatOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "FormatOptions", + "enum_class": "FormatOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\opengl\\qgl.h: Q_DECLARE_FLAGS(FormatOptions, FormatOption)", + "src\\gui\\kernel\\qsurfaceformat.h: Q_DECLARE_FLAGS(FormatOptions, FormatOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtOpenGL", + "module_path": "../../PyQt5-stubs/QtOpenGL.pyi" + }, + { + "qflag_class": "OpenGLVersionFlags", + "enum_class": "OpenGLVersionFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\opengl\\qgl.h: Q_DECLARE_FLAGS(OpenGLVersionFlags, OpenGLVersionFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtOpenGL", + "module_path": "../../PyQt5-stubs/QtOpenGL.pyi" + }, + { + "qflag_class": "BindOptions", + "enum_class": "BindOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\opengl\\qgl.h: Q_DECLARE_FLAGS(BindOptions, BindOption)", + "src\\gui\\opengl\\qopengltextureuploader_p.h: Q_DECLARE_FLAGS(BindOptions, BindOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtOpenGL", + "module_path": "../../PyQt5-stubs/QtOpenGL.pyi" + }, + { + "qflag_class": "ShaderType", + "enum_class": "ShaderTypeBit", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\opengl\\qglshaderprogram.h: Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)", + "src\\gui\\opengl\\qopenglshaderprogram.h: Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "WatchMode", + "enum_class": "WatchModeFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\dbus\\qdbusservicewatcher.h: Q_DECLARE_FLAGS(WatchMode, WatchModeFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtDBus", + "module_path": "../../PyQt5-stubs/QtDBus.pyi" + }, + { + "qflag_class": "ConversionFlags", + "enum_class": "ConversionFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\codecs\\qtextcodec.h: Q_DECLARE_FLAGS(ConversionFlags, ConversionFlag)", + "src\\corelib\\codecs\\qtextcodec_p.h: Q_DECLARE_FLAGS(ConversionFlags, ConversionFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "CheckIndexOptions", + "enum_class": "CheckIndexOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\itemmodels\\qabstractitemmodel.h: Q_DECLARE_FLAGS(CheckIndexOptions, CheckIndexOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "Filters", + "enum_class": "Filter", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qdir.h: Q_DECLARE_FLAGS(Filters, Filter)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "SortFlags", + "enum_class": "SortFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qdir.h: Q_DECLARE_FLAGS(SortFlags, SortFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "IteratorFlags", + "enum_class": "IteratorFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qdiriterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)", + "src\\widgets\\itemviews\\qtreewidgetitemiterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)", + "tests\\benchmarks\\corelib\\io\\qdiriterator\\qfilesystemiterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "IteratorFlags", + "enum_class": "IteratorFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qdiriterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)", + "src\\widgets\\itemviews\\qtreewidgetitemiterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)", + "tests\\benchmarks\\corelib\\io\\qdiriterator\\qfilesystemiterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "Permissions", + "enum_class": "Permission", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qfiledevice.h: Q_DECLARE_FLAGS(Permissions, Permission)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "FileHandleFlags", + "enum_class": "FileHandleFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qfiledevice.h: Q_DECLARE_FLAGS(FileHandleFlags, FileHandleFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "SelectionFlags", + "enum_class": "SelectionFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\itemmodels\\qitemselectionmodel.h: Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "KeyboardModifiers", + "enum_class": "KeyboardModifier", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "MouseButtons", + "enum_class": "MouseButton", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(MouseButtons, MouseButton)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "Orientations", + "enum_class": "Orientation", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(Orientations, Orientation)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "Alignment", + "enum_class": "AlignmentFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(Alignment, AlignmentFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "WindowFlags", + "enum_class": "WindowType", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(WindowFlags, WindowType)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "WindowStates", + "enum_class": "WindowState", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(WindowStates, WindowState)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "ApplicationStates", + "enum_class": "ApplicationState", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(ApplicationStates, ApplicationState)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "ScreenOrientations", + "enum_class": "ScreenOrientation", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(ScreenOrientations, ScreenOrientation)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "ImageConversionFlags", + "enum_class": "ImageConversionFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(ImageConversionFlags, ImageConversionFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "DockWidgetAreas", + "enum_class": "DockWidgetArea", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "ToolBarAreas", + "enum_class": "ToolBarArea", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(ToolBarAreas, ToolBarArea)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "Edges", + "enum_class": "Edge", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(Edges, Edge)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "InputMethodQueries", + "enum_class": "InputMethodQuery", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(InputMethodQueries, InputMethodQuery)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "InputMethodHints", + "enum_class": "InputMethodHint", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "FindChildOptions", + "enum_class": "FindChildOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(FindChildOptions, FindChildOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "DropActions", + "enum_class": "DropAction", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(DropActions, DropAction)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "ItemFlags", + "enum_class": "ItemFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(ItemFlags, ItemFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "MatchFlags", + "enum_class": "MatchFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(MatchFlags, MatchFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "TextInteractionFlags", + "enum_class": "TextInteractionFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(TextInteractionFlags, TextInteractionFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "TouchPointStates", + "enum_class": "TouchPointState", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(TouchPointStates, TouchPointState)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "GestureFlags", + "enum_class": "GestureFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(GestureFlags, GestureFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "MouseEventFlags", + "enum_class": "MouseEventFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\global\\qnamespace.h: Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "Transformations", + "enum_class": "Transformation", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\image\\qimageiohandler.h: Q_DECLARE_FLAGS(Transformations, Transformation)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "Capabilities", + "enum_class": "Capability", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\image\\qimageiohandler.h: Q_DECLARE_FLAGS(Capabilities, Capability)", + "src\\gui\\kernel\\qplatformcursor.h: Q_DECLARE_FLAGS(Capabilities, Capability)", + "src\\gui\\painting\\qblittable_p.h: Q_DECLARE_FLAGS (Capabilities, Capability)", + "src\\network\\bearer\\qnetworkconfigmanager.h: Q_DECLARE_FLAGS(Capabilities, Capability)", + "src\\network\\kernel\\qnetworkproxy.h: Q_DECLARE_FLAGS(Capabilities, Capability)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 2, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "Capabilities", + "enum_class": "Capability", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\image\\qimageiohandler.h: Q_DECLARE_FLAGS(Capabilities, Capability)", + "src\\gui\\kernel\\qplatformcursor.h: Q_DECLARE_FLAGS(Capabilities, Capability)", + "src\\gui\\painting\\qblittable_p.h: Q_DECLARE_FLAGS (Capabilities, Capability)", + "src\\network\\bearer\\qnetworkconfigmanager.h: Q_DECLARE_FLAGS(Capabilities, Capability)", + "src\\network\\kernel\\qnetworkproxy.h: Q_DECLARE_FLAGS(Capabilities, Capability)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 2, + "module_idx": 1, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "ProcessEventsFlags", + "enum_class": "ProcessEventsFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\kernel\\qeventloop.h: Q_DECLARE_FLAGS(ProcessEventsFlags, ProcessEventsFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "OpenMode", + "enum_class": "OpenModeFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qiodevice.h: Q_DECLARE_FLAGS(OpenMode, OpenModeFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "InfoFlags", + "enum_class": "InfoFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\kernel\\qevent.h: Q_DECLARE_FLAGS(InfoFlags, InfoFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "LoadHints", + "enum_class": "LoadHint", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\plugin\\qlibrary.h: Q_DECLARE_FLAGS(LoadHints, LoadHint)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "RangeAccessFlags", + "enum_class": "RangeAccessFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\opengl\\qopenglbuffer.h: Q_DECLARE_FLAGS(RangeAccessFlags, RangeAccessFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "Sources", + "enum_class": "Source", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\opengl\\qopengldebug.h: Q_DECLARE_FLAGS(Sources, Source)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "Types", + "enum_class": "Type", + "human_hint_qflag_full_class_name": "QOpenGLDebugMessage.Types", + "human_hint_enum_full_class_name": "QOpenGLDebugMessage.Type", + "grep_line": [ + "src\\gui\\opengl\\qopengldebug.h: Q_DECLARE_FLAGS(Types, Type)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "Severities", + "enum_class": "Severity", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\opengl\\qopengldebug.h: Q_DECLARE_FLAGS(Severities, Severity)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "TypeFlags", + "enum_class": "TypeFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\kernel\\qmetatype.h: Q_DECLARE_FLAGS(TypeFlags, TypeFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "LocateOptions", + "enum_class": "LocateOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qstandardpaths.h: Q_DECLARE_FLAGS(LocateOptions, LocateOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "Flags", + "enum_class": "Flag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\kernel\\qppsattribute_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\painting\\qplatformbackingstore.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\vulkan\\qvulkaninstance.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qshader_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\vulkan\\qvulkanwindow.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\text\\qtextoption.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\corelib\\tools\\qcommandlineoption.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\platformsupport\\eglconvenience\\qeglplatformcontext_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\platformsupport\\fbconvenience\\qfbscreen_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\plugins\\platforms\\direct2d\\qwindowsdirect2dpaintengine.h: Q_DECLARE_FLAGS(Flags, Flag)", + "tests\\auto\\tools\\moc\\namespaced-flags.h: Q_DECLARE_FLAGS( Flags, Flag )", + "src\\plugins\\platforms\\eglfs\\api\\qeglfswindow_p.h: Q_DECLARE_FLAGS(Flags, Flag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "Flags", + "enum_class": "Flag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\kernel\\qppsattribute_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\painting\\qplatformbackingstore.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\vulkan\\qvulkaninstance.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\rhi\\qshader_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\vulkan\\qvulkanwindow.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\gui\\text\\qtextoption.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\corelib\\tools\\qcommandlineoption.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\platformsupport\\eglconvenience\\qeglplatformcontext_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\platformsupport\\fbconvenience\\qfbscreen_p.h: Q_DECLARE_FLAGS(Flags, Flag)", + "src\\plugins\\platforms\\direct2d\\qwindowsdirect2dpaintengine.h: Q_DECLARE_FLAGS(Flags, Flag)", + "tests\\auto\\tools\\moc\\namespaced-flags.h: Q_DECLARE_FLAGS( Flags, Flag )", + "src\\plugins\\platforms\\eglfs\\api\\qeglfswindow_p.h: Q_DECLARE_FLAGS(Flags, Flag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "PolicyFlags", + "enum_class": "PolicyFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\network\\access\\qhstspolicy.h: Q_DECLARE_FLAGS(PolicyFlags, PolicyFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "StandardButtons", + "enum_class": "StandardButton", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\kernel\\qplatformdialoghelper.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton)", + "src\\widgets\\dialogs\\qmessagebox.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton)", + "src\\widgets\\widgets\\qdialogbuttonbox.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 2, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "StandardButtons", + "enum_class": "StandardButton", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\kernel\\qplatformdialoghelper.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton)", + "src\\widgets\\dialogs\\qmessagebox.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton)", + "src\\widgets\\widgets\\qdialogbuttonbox.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 2, + "module_idx": 1, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "ColorDialogOptions", + "enum_class": "ColorDialogOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\kernel\\qplatformdialoghelper.h: Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption)", + "src\\widgets\\dialogs\\qcolordialog.h: Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "FontDialogOptions", + "enum_class": "FontDialogOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\kernel\\qplatformdialoghelper.h: Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)", + "src\\widgets\\dialogs\\qfontdialog.h: Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "ComponentFormattingOptions", + "enum_class": "ComponentFormattingOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qurl.h: Q_DECLARE_FLAGS(ComponentFormattingOptions, ComponentFormattingOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "FormattingOptions", + "enum_class": "UrlFormattingOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qurl.h: Q_DECLARE_FLAGS(FormattingOptions, UrlFormattingOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "UserInputResolutionOptions", + "enum_class": "UserInputResolutionOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\io\\qurl.h: Q_DECLARE_FLAGS(UserInputResolutionOptions, UserInputResolutionOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "StateFlags", + "enum_class": "StateFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\network\\bearer\\qnetworkconfiguration.h: Q_DECLARE_FLAGS(StateFlags, StateFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "UsagePolicies", + "enum_class": "UsagePolicy", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\network\\bearer\\qnetworksession.h: Q_DECLARE_FLAGS(UsagePolicies, UsagePolicy)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "RenderFlags", + "enum_class": "RenderFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\painting\\qpaintengine.h: Q_DECLARE_FLAGS(RenderFlags, RenderFlag)", + "src\\widgets\\kernel\\qwidget.h: Q_DECLARE_FLAGS(RenderFlags, RenderFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "RenderFlags", + "enum_class": "RenderFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\painting\\qpaintengine.h: Q_DECLARE_FLAGS(RenderFlags, RenderFlag)", + "src\\widgets\\kernel\\qwidget.h: Q_DECLARE_FLAGS(RenderFlags, RenderFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "PaintEngineFeatures", + "enum_class": "PaintEngineFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\painting\\qpaintengine.h: Q_DECLARE_FLAGS(PaintEngineFeatures, PaintEngineFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "DirtyFlags", + "enum_class": "DirtyFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\painting\\qpaintengine.h: Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "Capabilities", + "enum_class": "CapabilityFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\kernel\\qtouchdevice.h: Q_DECLARE_FLAGS(Capabilities, CapabilityFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "Features", + "enum_class": "Feature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\opengl\\qopengltexture.h: Q_DECLARE_FLAGS(Features, Feature)", + "src\\gui\\text\\qtextmarkdownimporter_p.h: Q_DECLARE_FLAGS(Features, Feature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "RenderHints", + "enum_class": "RenderHint", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\painting\\qpainter.h: Q_DECLARE_FLAGS(RenderHints, RenderHint)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "PixmapFragmentHints", + "enum_class": "PixmapFragmentHint", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\painting\\qpainter.h: Q_DECLARE_FLAGS(PixmapFragmentHints, PixmapFragmentHint)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "ControlTypes", + "enum_class": "ControlType", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\util\\qlayoutpolicy_p.h: Q_DECLARE_FLAGS(ControlTypes, ControlType)", + "src\\widgets\\kernel\\qsizepolicy.h: Q_DECLARE_FLAGS(ControlTypes, ControlType)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "GlyphRunFlags", + "enum_class": "GlyphRunFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\text\\qglyphrun.h: Q_DECLARE_FLAGS(GlyphRunFlags, GlyphRunFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "LayoutFlags", + "enum_class": "LayoutFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\text\\qrawfont.h: Q_DECLARE_FLAGS(LayoutFlags, LayoutFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "MarkdownFeatures", + "enum_class": "MarkdownFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\text\\qtextdocument.h: Q_DECLARE_FLAGS(MarkdownFeatures, MarkdownFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "FindFlags", + "enum_class": "FindFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\text\\qtextdocument.h: Q_DECLARE_FLAGS(FindFlags, FindFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "ConversionMode", + "enum_class": "ConversionModeFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\network\\kernel\\qhostaddress.h: Q_DECLARE_FLAGS(ConversionMode, ConversionModeFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "BindMode", + "enum_class": "BindFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\network\\socket\\qabstractsocket.h: Q_DECLARE_FLAGS(BindMode, BindFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "PauseModes", + "enum_class": "PauseMode", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\network\\socket\\qabstractsocket.h: Q_DECLARE_FLAGS(PauseModes, PauseMode)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "PageBreakFlags", + "enum_class": "PageBreakFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\gui\\text\\qtextformat.h: Q_DECLARE_FLAGS(PageBreakFlags, PageBreakFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtGui", + "module_path": "../../PyQt5-stubs/QtGui.pyi" + }, + { + "qflag_class": "SocketOptions", + "enum_class": "SocketOption", + "human_hint_qflag_full_class_name": "QLocalServer.SocketOptions", + "human_hint_enum_full_class_name": "QLocalServer.SocketOption", + "grep_line": [ + "src\\network\\socket\\qlocalserver.h: Q_DECLARE_FLAGS(SocketOptions, SocketOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "InterfaceFlags", + "enum_class": "InterfaceFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\network\\kernel\\qnetworkinterface.h: Q_DECLARE_FLAGS(InterfaceFlags, InterfaceFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "SslOptions", + "enum_class": "SslOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\network\\ssl\\qssl.h: Q_DECLARE_FLAGS(SslOptions, SslOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtNetwork", + "module_path": "../../PyQt5-stubs/QtNetwork.pyi" + }, + { + "qflag_class": "Base64Options", + "enum_class": "Base64Option", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\text\\qbytearray.h: Q_DECLARE_FLAGS(Base64Options, Base64Option)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "NumberOptions", + "enum_class": "NumberOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\text\\qlocale.h: Q_DECLARE_FLAGS(NumberOptions, NumberOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "DataSizeFormats", + "enum_class": "DataSizeFormat", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\text\\qlocale.h: Q_DECLARE_FLAGS(DataSizeFormats, DataSizeFormat)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "Sections", + "enum_class": "Section", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\time\\qdatetimeparser_p.h: Q_DECLARE_FLAGS(Sections, Section)", + "src\\widgets\\widgets\\qdatetimeedit.h: Q_DECLARE_FLAGS(Sections, Section)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "PatternOptions", + "enum_class": "PatternOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\text\\qregularexpression.h: Q_DECLARE_FLAGS(PatternOptions, PatternOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "MatchOptions", + "enum_class": "MatchOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\text\\qregularexpression.h: Q_DECLARE_FLAGS(MatchOptions, MatchOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "NumberFlags", + "enum_class": "NumberFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\serialization\\qtextstream.h: Q_DECLARE_FLAGS(NumberFlags, NumberFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "BoundaryReasons", + "enum_class": "BoundaryReason", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\corelib\\text\\qtextboundaryfinder.h: Q_DECLARE_FLAGS( BoundaryReasons, BoundaryReason )" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtCore", + "module_path": "../../PyQt5-stubs/QtCore.pyi" + }, + { + "qflag_class": "PrintDialogOptions", + "enum_class": "PrintDialogOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\printsupport\\dialogs\\qabstractprintdialog.h: Q_DECLARE_FLAGS(PrintDialogOptions, PrintDialogOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtPrintSupport", + "module_path": "../../PyQt5-stubs/QtPrintSupport.pyi" + }, + { + "qflag_class": "ParamType", + "enum_class": "ParamTypeFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\sql\\kernel\\qtsqlglobal.h: Q_DECLARE_FLAGS(ParamType, ParamTypeFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtSql", + "module_path": "../../PyQt5-stubs/QtSql.pyi" + }, + { + "qflag_class": "Options", + "enum_class": "Option", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\dialogs\\qfiledialog.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\widgets\\dialogs\\qfilesystemmodel.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\widgets\\itemviews\\qfileiconprovider.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\plugins\\platforms\\cocoa\\qcocoaintegration.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\plugins\\platforms\\qnx\\qqnxintegration.h: Q_DECLARE_FLAGS(Options, Option)", + "tests\\benchmarks\\widgets\\graphicsview\\functional\\GraphicsViewBenchmark\\widgets\\settings.h: Q_DECLARE_FLAGS(Options, Option)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 3, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "Options", + "enum_class": "Option", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\dialogs\\qfiledialog.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\widgets\\dialogs\\qfilesystemmodel.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\widgets\\itemviews\\qfileiconprovider.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\plugins\\platforms\\cocoa\\qcocoaintegration.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\plugins\\platforms\\qnx\\qqnxintegration.h: Q_DECLARE_FLAGS(Options, Option)", + "tests\\benchmarks\\widgets\\graphicsview\\functional\\GraphicsViewBenchmark\\widgets\\settings.h: Q_DECLARE_FLAGS(Options, Option)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 3, + "module_idx": 1, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "Options", + "enum_class": "Option", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\dialogs\\qfiledialog.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\widgets\\dialogs\\qfilesystemmodel.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\widgets\\itemviews\\qfileiconprovider.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\plugins\\platforms\\cocoa\\qcocoaintegration.h: Q_DECLARE_FLAGS(Options, Option)", + "src\\plugins\\platforms\\qnx\\qqnxintegration.h: Q_DECLARE_FLAGS(Options, Option)", + "tests\\benchmarks\\widgets\\graphicsview\\functional\\GraphicsViewBenchmark\\widgets\\settings.h: Q_DECLARE_FLAGS(Options, Option)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 3, + "module_idx": 2, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "ChangeFlags", + "enum_class": "ChangeFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\effects\\qgraphicseffect.h: Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)", + "src\\widgets\\kernel\\qgesture.h: Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 2, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "ChangeFlags", + "enum_class": "ChangeFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\effects\\qgraphicseffect.h: Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)", + "src\\widgets\\kernel\\qgesture.h: Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 2, + "module_idx": 1, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "BlurHints", + "enum_class": "BlurHint", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\effects\\qgraphicseffect.h: Q_DECLARE_FLAGS(BlurHints, BlurHint)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "InputDialogOptions", + "enum_class": "InputDialogOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\dialogs\\qinputdialog.h: Q_DECLARE_FLAGS(InputDialogOptions, InputDialogOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "WizardOptions", + "enum_class": "WizardOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\dialogs\\qwizard.h: Q_DECLARE_FLAGS(WizardOptions, WizardOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "EditTriggers", + "enum_class": "EditTrigger", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\itemviews\\qabstractitemview.h: Q_DECLARE_FLAGS(EditTriggers, EditTrigger)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "GraphicsItemFlags", + "enum_class": "GraphicsItemFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\graphicsview\\qgraphicsitem.h: Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "Result", + "enum_class": "ResultFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\kernel\\qgesturerecognizer.h: Q_DECLARE_FLAGS(Result, ResultFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "SceneLayers", + "enum_class": "SceneLayer", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\graphicsview\\qgraphicsscene.h: Q_DECLARE_FLAGS(SceneLayers, SceneLayer)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "CacheMode", + "enum_class": "CacheModeFlag", + "human_hint_qflag_full_class_name": "QGraphicsView.CacheMode", + "human_hint_enum_full_class_name": "QGraphicsView.CacheModeFlag", + "grep_line": [ + "src\\widgets\\graphicsview\\qgraphicsview.h: Q_DECLARE_FLAGS(CacheMode, CacheModeFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "OptimizationFlags", + "enum_class": "OptimizationFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\graphicsview\\qgraphicsview.h: Q_DECLARE_FLAGS(OptimizationFlags, OptimizationFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "State", + "enum_class": "StateFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyle.h: Q_DECLARE_FLAGS(State, StateFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "SubControls", + "enum_class": "SubControl", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyle.h: Q_DECLARE_FLAGS(SubControls, SubControl)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "StepEnabled", + "enum_class": "StepEnabledFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\widgets\\qabstractspinbox.h: Q_DECLARE_FLAGS(StepEnabled, StepEnabledFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "FrameFeatures", + "enum_class": "FrameFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyleoption.h: Q_DECLARE_FLAGS(FrameFeatures, FrameFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "ButtonFeatures", + "enum_class": "ButtonFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyleoption.h: Q_DECLARE_FLAGS(ButtonFeatures, ButtonFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "CornerWidgets", + "enum_class": "CornerWidget", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyleoption.h: Q_DECLARE_FLAGS(CornerWidgets, CornerWidget)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "TabFeatures", + "enum_class": "TabFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyleoption.h: Q_DECLARE_FLAGS(TabFeatures, TabFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "ToolBarFeatures", + "enum_class": "ToolBarFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyleoption.h: Q_DECLARE_FLAGS(ToolBarFeatures, ToolBarFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "ViewItemFeatures", + "enum_class": "ViewItemFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyleoption.h: Q_DECLARE_FLAGS(ViewItemFeatures, ViewItemFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "ToolButtonFeatures", + "enum_class": "ToolButtonFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\styles\\qstyleoption.h: Q_DECLARE_FLAGS(ToolButtonFeatures, ToolButtonFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "DockWidgetFeatures", + "enum_class": "DockWidgetFeature", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\widgets\\qdockwidget.h: Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "FontFilters", + "enum_class": "FontFilter", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\widgets\\qfontcombobox.h: Q_DECLARE_FLAGS(FontFilters, FontFilter)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "AreaOptions", + "enum_class": "AreaOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\widgets\\qmdiarea.h: Q_DECLARE_FLAGS(AreaOptions, AreaOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "SubWindowOptions", + "enum_class": "SubWindowOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\widgets\\qmdisubwindow.h: Q_DECLARE_FLAGS(SubWindowOptions, SubWindowOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "DockOptions", + "enum_class": "DockOption", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\widgets\\qmainwindow.h: Q_DECLARE_FLAGS(DockOptions, DockOption)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + }, + { + "qflag_class": "AutoFormatting", + "enum_class": "AutoFormattingFlag", + "human_hint_qflag_full_class_name": "", + "human_hint_enum_full_class_name": "", + "grep_line": [ + "src\\widgets\\widgets\\qtextedit.h: Q_DECLARE_FLAGS(AutoFormatting, AutoFormattingFlag)" + ], + "qflag_full_class_name": "", + "enum_full_class_name": "", + "enum_value1": "", + "enum_value2": "", + "module_count": 1, + "module_idx": 0, + "module_name": "QtWidgets", + "module_path": "../../PyQt5-stubs/QtWidgets.pyi" + } + ], + "qflags_to_skip": [] +} \ No newline at end of file diff --git a/tests/qflags/qt-qflag-grep-result.txt b/tests/qflags/qt-qflag-grep-result.txt new file mode 100644 index 00000000..e92d42a0 --- /dev/null +++ b/tests/qflags/qt-qflag-grep-result.txt @@ -0,0 +1,227 @@ +qmake\library\qmakeevaluator.h: Q_DECLARE_FLAGS(LoadFlags, LoadFlag) +qmake\library\qmakeparser.h: Q_DECLARE_FLAGS(ParseFlags, ParseFlag) +qmake\library\qmakevfs.h: Q_DECLARE_FLAGS(VfsFlags, VfsFlag) +qmake\generators\makefile.h: Q_DECLARE_FLAGS(FileFixifyTypes, FileFixifyType) +src\concurrent\qtconcurrentreducekernel.h:Q_DECLARE_FLAGS(ReduceOptions, ReduceOption) +src\dbus\qdbusconnection.h: Q_DECLARE_FLAGS(RegisterOptions, RegisterOption) +src\dbus\qdbusconnection.h: Q_DECLARE_FLAGS(VirtualObjectRegisterOptions, VirtualObjectRegisterOption) +src\dbus\qdbusconnection.h: Q_DECLARE_FLAGS(ConnectionCapabilities, ConnectionCapability) +src\opengl\qgl.h: Q_DECLARE_FLAGS(FormatOptions, FormatOption) +src\opengl\qgl.h: Q_DECLARE_FLAGS(OpenGLVersionFlags, OpenGLVersionFlag) +src\opengl\qgl.h: Q_DECLARE_FLAGS(BindOptions, BindOption) +src\opengl\qglfunctions.h: Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature) +src\opengl\qglshaderprogram.h: Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit) +src\dbus\qdbusservicewatcher.h: Q_DECLARE_FLAGS(WatchMode, WatchModeFlag) +examples\network\torrent\peerwireclient.h: Q_DECLARE_FLAGS(PeerWireState, PeerWireStateFlag) +src\corelib\codecs\qtextcodec.h: Q_DECLARE_FLAGS(ConversionFlags, ConversionFlag) +src\corelib\codecs\qtextcodec_p.h: Q_DECLARE_FLAGS(ConversionFlags, ConversionFlag) +src\gui\accessible\qaccessible.h: Q_DECLARE_FLAGS(Relation, RelationFlag) +src\corelib\io\qabstractfileengine_p.h: Q_DECLARE_FLAGS(FileFlags, FileFlag) +src\corelib\global\qflags.h:#define Q_DECLARE_FLAGS(Flags, Enum)\ +src\corelib\global\qflags.h:#define Q_DECLARE_FLAGS(Flags, Enum)\ +src\corelib\itemmodels\qabstractitemmodel.h: Q_DECLARE_FLAGS(CheckIndexOptions, CheckIndexOption) +src\corelib\io\qdir.h: Q_DECLARE_FLAGS(Filters, Filter) +src\corelib\io\qdir.h: Q_DECLARE_FLAGS(SortFlags, SortFlag) +src\corelib\io\qdiriterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag) +src\corelib\io\qdir_p.h: Q_DECLARE_FLAGS(PathNormalizations, PathNormalization) +src\corelib\io\qfiledevice.h: Q_DECLARE_FLAGS(Permissions, Permission) +src\corelib\io\qfiledevice.h: Q_DECLARE_FLAGS(FileHandleFlags, FileHandleFlag) +src\corelib\itemmodels\qitemselectionmodel.h: Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(MouseButtons, MouseButton) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(Orientations, Orientation) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(SplitBehavior, SplitBehaviorFlags) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(Alignment, AlignmentFlag) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(WindowFlags, WindowType) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(WindowStates, WindowState) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(ApplicationStates, ApplicationState) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(ScreenOrientations, ScreenOrientation) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(ImageConversionFlags, ImageConversionFlag) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(ToolBarAreas, ToolBarArea) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(Edges, Edge) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(InputMethodQueries, InputMethodQuery) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(FindChildOptions, FindChildOption) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(DropActions, DropAction) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(ItemFlags, ItemFlag) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(MatchFlags, MatchFlag) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(TextInteractionFlags, TextInteractionFlag) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(TouchPointStates, TouchPointState) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(GestureFlags, GestureFlag) +src\corelib\global\qnamespace.h: Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag) +src\corelib\io\qfilesystemmetadata_p.h: Q_DECLARE_FLAGS(MetaDataFlags, MetaDataFlag) +src\gui\image\qimageiohandler.h: Q_DECLARE_FLAGS(Transformations, Transformation) +src\gui\image\qimageiohandler.h: Q_DECLARE_FLAGS(Capabilities, Capability) +src\corelib\kernel\qeventloop.h: Q_DECLARE_FLAGS(ProcessEventsFlags, ProcessEventsFlag) +src\corelib\io\qiodevice.h: Q_DECLARE_FLAGS(OpenMode, OpenModeFlag) +src\gui\kernel\qevent.h: Q_DECLARE_FLAGS(InfoFlags, InfoFlag) +src\corelib\io\qloggingregistry_p.h: Q_DECLARE_FLAGS(PatternFlags, PatternFlag) +src\corelib\plugin\qlibrary.h: Q_DECLARE_FLAGS(LoadHints, LoadHint) +src\gui\opengl\qopenglbuffer.h: Q_DECLARE_FLAGS(RangeAccessFlags, RangeAccessFlag) +src\corelib\kernel\qmetaobjectbuilder_p.h: Q_DECLARE_FLAGS(AddMembers, AddMember) +src\corelib\kernel\qmetaobjectbuilder_p.h: Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag) +src\gui\opengl\qopengldebug.h: Q_DECLARE_FLAGS(Sources, Source) +src\gui\opengl\qopengldebug.h: Q_DECLARE_FLAGS(Types, Type) +src\gui\opengl\qopengldebug.h: Q_DECLARE_FLAGS(Severities, Severity) +src\corelib\kernel\qmetatype.h: Q_DECLARE_FLAGS(TypeFlags, TypeFlag) +src\gui\opengl\qopenglextensions_p.h: Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension) +src\corelib\io\qstandardpaths.h: Q_DECLARE_FLAGS(LocateOptions, LocateOption) +src\gui\opengl\qopenglfunctions.h: Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature) +src\corelib\kernel\qppsattribute_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\corelib\kernel\qppsobject_p.h: Q_DECLARE_FLAGS(OpenModes, OpenMode) +src\gui\kernel\qplatformcursor.h: Q_DECLARE_FLAGS(Capabilities, Capability) +src\network\access\qhstspolicy.h: Q_DECLARE_FLAGS(PolicyFlags, PolicyFlag) +src\gui\kernel\qplatformdialoghelper.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton) +src\gui\kernel\qplatformdialoghelper.h: Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption) +src\gui\kernel\qplatformdialoghelper.h: Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption) +src\gui\kernel\qplatformdialoghelper.h: Q_DECLARE_FLAGS(FileDialogOptions, FileDialogOption) +src\gui\kernel\qplatformgraphicsbuffer.h: Q_DECLARE_FLAGS(AccessTypes, AccessType); +src\gui\painting\qblittable_p.h: Q_DECLARE_FLAGS (Capabilities, Capability) +src\corelib\io\qurl.h: Q_DECLARE_FLAGS(ComponentFormattingOptions, ComponentFormattingOption) +src\corelib\io\qurl.h: Q_DECLARE_FLAGS(FormattingOptions, UrlFormattingOption) +src\corelib\io\qurl.h: Q_DECLARE_FLAGS(UserInputResolutionOptions, UserInputResolutionOption) +src\gui\painting\qcolortransform_p.h: Q_DECLARE_FLAGS(TransformFlags, TransformFlag) +src\gui\kernel\qplatformtheme.h: Q_DECLARE_FLAGS(IconOptions, IconOption) +src\network\bearer\qnetworkconfigmanager.h: Q_DECLARE_FLAGS(Capabilities, Capability) +src\network\bearer\qnetworkconfiguration.h: Q_DECLARE_FLAGS(StateFlags, StateFlag) +src\gui\kernel\qsurfaceformat.h: Q_DECLARE_FLAGS(FormatOptions, FormatOption) +src\network\bearer\qnetworksession.h: Q_DECLARE_FLAGS(UsagePolicies, UsagePolicy) +src\gui\painting\qpaintengine.h: Q_DECLARE_FLAGS(RenderFlags, RenderFlag) +src\gui\painting\qpaintengine.h: Q_DECLARE_FLAGS(PaintEngineFeatures, PaintEngineFeature) +src\gui\painting\qpaintengine.h: Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag) +src\gui\kernel\qtouchdevice.h: Q_DECLARE_FLAGS(Capabilities, CapabilityFlag) +src\gui\opengl\qopenglshaderprogram.h: Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit) +src\gui\opengl\qopengltexture.h: Q_DECLARE_FLAGS(Features, Feature) +src\gui\painting\qpainter.h: Q_DECLARE_FLAGS(RenderHints, RenderHint) +src\gui\painting\qpainter.h: Q_DECLARE_FLAGS(PixmapFragmentHints, PixmapFragmentHint) +src\gui\opengl\qopengltextureuploader_p.h: Q_DECLARE_FLAGS(BindOptions, BindOption) +src\network\access\qspdyprotocolhandler_p.h: Q_DECLARE_FLAGS(DataFrameFlags, DataFrameFlag) +src\network\access\qspdyprotocolhandler_p.h: Q_DECLARE_FLAGS(ControlFrameFlags, ControlFrameFlag) +src\network\access\qspdyprotocolhandler_p.h: Q_DECLARE_FLAGS(SETTINGS_Flags, SETTINGS_Flag) +src\network\access\qspdyprotocolhandler_p.h: Q_DECLARE_FLAGS(SETTINGS_ID_Flags, SETTINGS_ID_Flag) +src\gui\painting\qplatformbackingstore.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\painting\qplatformbackingstore.h: Q_DECLARE_FLAGS(TextureFlags, TextureFlag) +src\gui\text\qfontengine_p.h: Q_DECLARE_FLAGS(ShaperFlags, ShaperFlag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(StageFlags, StageFlag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(UsageFlags, UsageFlag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(ColorMask, ColorMaskComponent) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(BeginFrameFlags, BeginFrameFlag) +src\gui\rhi\qrhi_p.h: Q_DECLARE_FLAGS(EndFrameFlags, EndFrameFlag) +src\gui\rhi\qshaderdescription_p.h: Q_DECLARE_FLAGS(ImageFlags, ImageFlag) +src\gui\vulkan\qvulkaninstance.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\rhi\qshader_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\util\qlayoutpolicy_p.h: Q_DECLARE_FLAGS(ControlTypes, ControlType) +src\gui\vulkan\qvulkanwindow.h: Q_DECLARE_FLAGS(Flags, Flag) +src\gui\text\qglyphrun.h: Q_DECLARE_FLAGS(GlyphRunFlags, GlyphRunFlag) +src\gui\text\qrawfont.h: Q_DECLARE_FLAGS(LayoutFlags, LayoutFlag) +src\gui\text\qtextdocument.h: Q_DECLARE_FLAGS(MarkdownFeatures, MarkdownFeature) +src\gui\text\qtextdocument.h: Q_DECLARE_FLAGS(FindFlags, FindFlag) +src\network\kernel\qhostaddress.h: Q_DECLARE_FLAGS(ConversionMode, ConversionModeFlag) +src\network\socket\qabstractsocket.h: Q_DECLARE_FLAGS(BindMode, BindFlag) +src\network\socket\qabstractsocket.h: Q_DECLARE_FLAGS(PauseModes, PauseMode) +src\network\socket\qabstractsocketengine_p.h: Q_DECLARE_FLAGS(PacketHeaderOptions, PacketHeaderOption) +src\gui\text\qtextformat.h: Q_DECLARE_FLAGS(PageBreakFlags, PageBreakFlag) +src\network\socket\qlocalserver.h: Q_DECLARE_FLAGS(SocketOptions, SocketOption) +src\gui\text\qtextmarkdownimporter_p.h: Q_DECLARE_FLAGS(Features, Feature) +src\network\kernel\qnetworkinterface.h: Q_DECLARE_FLAGS(InterfaceFlags, InterfaceFlag) +src\gui\text\qtextoption.h: Q_DECLARE_FLAGS(Flags, Flag) +src\network\ssl\qssl.h: Q_DECLARE_FLAGS(SslOptions, SslOption) +src\network\kernel\qnetworkproxy.h: Q_DECLARE_FLAGS(Capabilities, Capability) +src\corelib\text\qbytearray.h: Q_DECLARE_FLAGS(Base64Options, Base64Option) +src\corelib\text\qlocale.h: Q_DECLARE_FLAGS(NumberOptions, NumberOption) +src\corelib\text\qlocale.h: Q_DECLARE_FLAGS(DataSizeFormats, DataSizeFormat) +src\corelib\serialization\qcborvalue.h: Q_DECLARE_FLAGS(EncodingOptions, EncodingOption) +src\corelib\serialization\qcborvalue.h: Q_DECLARE_FLAGS(DiagnosticNotationOptions, DiagnosticNotationOption) +src\corelib\serialization\qcborvalue_p.h: Q_DECLARE_FLAGS(ValueFlags, ValueFlag) +src\corelib\time\qdatetimeparser_p.h: Q_DECLARE_FLAGS(Sections, Section) +src\corelib\time\qdatetimeparser_p.h: Q_DECLARE_FLAGS(FieldInfo, FieldInfoFlag) +src\corelib\time\qdatetime_p.h: Q_DECLARE_FLAGS(StatusFlags, StatusFlag) +src\corelib\text\qregularexpression.h: Q_DECLARE_FLAGS(PatternOptions, PatternOption) +src\corelib\text\qregularexpression.h: Q_DECLARE_FLAGS(MatchOptions, MatchOption) +src\corelib\text\qstring.h: Q_DECLARE_FLAGS(SectionFlags, SectionFlag) +src\corelib\serialization\qtextstream.h: Q_DECLARE_FLAGS(NumberFlags, NumberFlag) +src\corelib\text\qtextboundaryfinder.h: Q_DECLARE_FLAGS( BoundaryReasons, BoundaryReason ) +src\corelib\text\qunicodetools_p.h:Q_DECLARE_FLAGS(CharAttributeOptions, CharAttributeOption) +src\corelib\tools\qarraydata.h: Q_DECLARE_FLAGS(AllocationOptions, AllocationOption) +src\corelib\tools\qcommandlineoption.h: Q_DECLARE_FLAGS(Flags, Flag) +src\platformheaders\windowsfunctions\qwindowswindowfunctions.h: Q_DECLARE_FLAGS(TouchWindowTouchTypes, TouchWindowTouchType) +src\platformheaders\xcbfunctions\qxcbwindowfunctions.h: Q_DECLARE_FLAGS(WmWindowTypes, WmWindowType) +src\platformsupport\devicediscovery\qdevicediscovery_p.h: Q_DECLARE_FLAGS(QDeviceTypes, QDeviceType) +src\platformsupport\eglconvenience\qeglplatformcontext_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\platformsupport\fbconvenience\qfbscreen_p.h: Q_DECLARE_FLAGS(Flags, Flag) +src\printsupport\dialogs\qabstractprintdialog.h: Q_DECLARE_FLAGS(PrintDialogOptions, PrintDialogOption) +src\platformsupport\kmsconvenience\qkmsdevice_p.h: Q_DECLARE_FLAGS(Rotations, Rotation) +src\sql\kernel\qtsqlglobal.h: Q_DECLARE_FLAGS(ParamType, ParamTypeFlag) +src\widgets\dialogs\qcolordialog.h: Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption) +src\widgets\dialogs\qfiledialog.h: Q_DECLARE_FLAGS(Options, Option) +src\widgets\dialogs\qfilesystemmodel.h: Q_DECLARE_FLAGS(Options, Option) +src\widgets\dialogs\qfontdialog.h: Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption) +src\widgets\effects\qgraphicseffect.h: Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag) +src\widgets\effects\qgraphicseffect.h: Q_DECLARE_FLAGS(BlurHints, BlurHint) +src\widgets\dialogs\qinputdialog.h: Q_DECLARE_FLAGS(InputDialogOptions, InputDialogOption) +src\widgets\dialogs\qmessagebox.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton) +src\widgets\dialogs\qwizard.h: Q_DECLARE_FLAGS(WizardOptions, WizardOption) +src\widgets\itemviews\qabstractitemview.h: Q_DECLARE_FLAGS(EditTriggers, EditTrigger) +src\widgets\graphicsview\qgraphicsitem.h: Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag) +src\widgets\itemviews\qfileiconprovider.h: Q_DECLARE_FLAGS(Options, Option) +src\widgets\kernel\qgesture.h: Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag) +src\widgets\kernel\qgesturerecognizer.h: Q_DECLARE_FLAGS(Result, ResultFlag) +src\widgets\graphicsview\qgraphicsscene.h: Q_DECLARE_FLAGS(SceneLayers, SceneLayer) +src\widgets\graphicsview\qgraphicsview.h: Q_DECLARE_FLAGS(CacheMode, CacheModeFlag) +src\widgets\graphicsview\qgraphicsview.h: Q_DECLARE_FLAGS(OptimizationFlags, OptimizationFlag) +src\widgets\kernel\qsizepolicy.h: Q_DECLARE_FLAGS(ControlTypes, ControlType) +src\widgets\itemviews\qtreewidgetitemiterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag) +src\widgets\kernel\qwidget.h: Q_DECLARE_FLAGS(RenderFlags, RenderFlag) +src\widgets\kernel\qwidget_p.h: Q_DECLARE_FLAGS(DrawWidgetFlags, DrawWidgetFlag) +src\widgets\styles\qdrawutil.h: Q_DECLARE_FLAGS(DrawingHints, DrawingHint) +src\widgets\styles\qstyle.h: Q_DECLARE_FLAGS(State, StateFlag) +src\widgets\styles\qstyle.h: Q_DECLARE_FLAGS(SubControls, SubControl) +src\widgets\widgets\qabstractspinbox.h: Q_DECLARE_FLAGS(StepEnabled, StepEnabledFlag) +src\widgets\styles\qstyleoption.h: Q_DECLARE_FLAGS(FrameFeatures, FrameFeature) +src\widgets\styles\qstyleoption.h: Q_DECLARE_FLAGS(ButtonFeatures, ButtonFeature) +src\widgets\styles\qstyleoption.h: Q_DECLARE_FLAGS(CornerWidgets, CornerWidget) +src\widgets\styles\qstyleoption.h: Q_DECLARE_FLAGS(TabFeatures, TabFeature) +src\widgets\styles\qstyleoption.h: Q_DECLARE_FLAGS(ToolBarFeatures, ToolBarFeature) +src\widgets\styles\qstyleoption.h: Q_DECLARE_FLAGS(ViewItemFeatures, ViewItemFeature) +src\widgets\styles\qstyleoption.h: Q_DECLARE_FLAGS(ToolButtonFeatures, ToolButtonFeature) +src\widgets\widgets\qdialogbuttonbox.h: Q_DECLARE_FLAGS(StandardButtons, StandardButton) +src\widgets\widgets\qdockwidget.h: Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature) +src\widgets\widgets\qfontcombobox.h: Q_DECLARE_FLAGS(FontFilters, FontFilter) +src\widgets\widgets\qdatetimeedit.h: Q_DECLARE_FLAGS(Sections, Section) +src\widgets\widgets\qmdiarea.h: Q_DECLARE_FLAGS(AreaOptions, AreaOption) +src\widgets\widgets\qmdisubwindow.h: Q_DECLARE_FLAGS(SubWindowOptions, SubWindowOption) +src\widgets\widgets\qmainwindow.h: Q_DECLARE_FLAGS(DockOptions, DockOption) +tests\manual\diaglib\eventfilter.h: Q_DECLARE_FLAGS(EventCategories, EventCategory) +tests\manual\diaglib\eventfilter.h: Q_DECLARE_FLAGS(ObjectTypes, ObjectType) +src\widgets\widgets\qtextedit.h: Q_DECLARE_FLAGS(AutoFormatting, AutoFormattingFlag) +tests\manual\diaglib\qwindowdump.h:Q_DECLARE_FLAGS(FormatWindowOptions, FormatWindowOption) +src\network\access\http2\http2protocol_p.h:Q_DECLARE_FLAGS(FrameFlags, FrameFlag) +src\plugins\bearer\networkmanager\qnetworkmanagerservice.h: Q_DECLARE_FLAGS(ApFlags, ApFlag) +src\plugins\bearer\networkmanager\qnetworkmanagerservice.h: Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag) +src\plugins\bearer\networkmanager\qnetworkmanagerservice.h: Q_DECLARE_FLAGS(ModemCapabilities, ModemCapability) +src\plugins\platforms\android\qandroidinputcontext.h: Q_DECLARE_FLAGS(HandleModes, HandleMode) +src\plugins\platforms\direct2d\qwindowsdirect2dpaintengine.h: Q_DECLARE_FLAGS(Flags, Flag) +src\plugins\platforms\cocoa\qcocoaintegration.h: Q_DECLARE_FLAGS(Options, Option) +src\plugins\platforms\wasm\qwasmcompositor.h: Q_DECLARE_FLAGS(SubControls, QWasmSubControl) +src\plugins\platforms\wasm\qwasmcompositor.h: Q_DECLARE_FLAGS(StateFlags, QWasmStateFlag) +src\plugins\platforms\cocoa\qcocoawindow.h: Q_DECLARE_FLAGS(RecreationReasons, RecreationReason) +src\plugins\platforms\qnx\qqnxintegration.h: Q_DECLARE_FLAGS(Options, Option) +src\plugins\platforms\xcb\qxcbeventqueue.h: Q_DECLARE_FLAGS(PeekOptions, PeekOption) +src\plugins\platforms\windows\qwindowsopengltester.h: Q_DECLARE_FLAGS(Renderers, Renderer) +src\plugins\platforms\xcb\qxcbwindow.h: Q_DECLARE_FLAGS(NetWmStates, NetWmState) +tests\auto\other\macgui\guitest.h: Q_DECLARE_FLAGS(Directions, Direction) +tests\auto\tools\moc\cxx11-enums.h: Q_DECLARE_FLAGS(ClassFlags, ClassFlag) +tests\auto\tools\moc\cxx11-enums.h: Q_DECLARE_FLAGS(StructFlags, StructFlag) +tests\auto\tools\moc\cxx11-enums.h: Q_DECLARE_FLAGS(ClassFlags, ClassFlag) +tests\auto\tools\moc\namespaced-flags.h: Q_DECLARE_FLAGS( Flags, Flag ) +src\plugins\platforms\eglfs\api\qeglfswindow_p.h: Q_DECLARE_FLAGS(Flags, Flag) +tests\auto\corelib\tools\qsharedpointer\externaltests.h: Q_DECLARE_FLAGS(QtModules, QtModule) +tests\benchmarks\corelib\io\qdiriterator\qfilesystemiterator.h: Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag) +tests\benchmarks\widgets\graphicsview\functional\GraphicsViewBenchmark\widgets\settings.h: Q_DECLARE_FLAGS(Options, Option) diff --git a/tests/qflags/test_QtCore_Alignment_AlignmentFlag.py b/tests/qflags/test_QtCore_Alignment_AlignmentFlag.py new file mode 100644 index 00000000..e1045204 --- /dev/null +++ b/tests/qflags/test_QtCore_Alignment_AlignmentFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.Alignment" and flag class "Qt.AlignmentFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.AlignmentFlag +MultiFlagClass = QtCore.Qt.Alignment + +oneFlagRefValue1 = QtCore.Qt.AlignmentFlag.AlignLeft +oneFlagRefValue2 = QtCore.Qt.AlignmentFlag.AlignLeading + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_ApplicationStates_ApplicationState.py b/tests/qflags/test_QtCore_ApplicationStates_ApplicationState.py new file mode 100644 index 00000000..fb8e27df --- /dev/null +++ b/tests/qflags/test_QtCore_ApplicationStates_ApplicationState.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.ApplicationStates" and flag class "Qt.ApplicationState" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.ApplicationState +MultiFlagClass = QtCore.Qt.ApplicationStates + +oneFlagRefValue1 = QtCore.Qt.ApplicationState.ApplicationSuspended +oneFlagRefValue2 = QtCore.Qt.ApplicationState.ApplicationHidden + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_Base64Options_Base64Option.py b/tests/qflags/test_QtCore_Base64Options_Base64Option.py new file mode 100644 index 00000000..60534242 --- /dev/null +++ b/tests/qflags/test_QtCore_Base64Options_Base64Option.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QByteArray.Base64Options" and flag class "QByteArray.Base64Option" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QByteArray.Base64Option +MultiFlagClass = QtCore.QByteArray.Base64Options + +oneFlagRefValue1 = QtCore.QByteArray.Base64Option.Base64Encoding +oneFlagRefValue2 = QtCore.QByteArray.Base64Option.Base64UrlEncoding + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_BoundaryReasons_BoundaryReason.py b/tests/qflags/test_QtCore_BoundaryReasons_BoundaryReason.py new file mode 100644 index 00000000..90eb8dbd --- /dev/null +++ b/tests/qflags/test_QtCore_BoundaryReasons_BoundaryReason.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextBoundaryFinder.BoundaryReasons" and flag class "QTextBoundaryFinder.BoundaryReason" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QTextBoundaryFinder.BoundaryReason +MultiFlagClass = QtCore.QTextBoundaryFinder.BoundaryReasons + +oneFlagRefValue1 = QtCore.QTextBoundaryFinder.BoundaryReason.NotAtBoundary +oneFlagRefValue2 = QtCore.QTextBoundaryFinder.BoundaryReason.SoftHyphen + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_CheckIndexOptions_CheckIndexOption.py b/tests/qflags/test_QtCore_CheckIndexOptions_CheckIndexOption.py new file mode 100644 index 00000000..e6282bdf --- /dev/null +++ b/tests/qflags/test_QtCore_CheckIndexOptions_CheckIndexOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QAbstractItemModel.CheckIndexOptions" and flag class "QAbstractItemModel.CheckIndexOption" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QAbstractItemModel.CheckIndexOption +MultiFlagClass = QtCore.QAbstractItemModel.CheckIndexOptions + +oneFlagRefValue1 = QtCore.QAbstractItemModel.CheckIndexOption.NoOption +oneFlagRefValue2 = QtCore.QAbstractItemModel.CheckIndexOption.IndexIsValid + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_ComponentFormattingOptions_ComponentFormattingOption.py b/tests/qflags/test_QtCore_ComponentFormattingOptions_ComponentFormattingOption.py new file mode 100644 index 00000000..a461db58 --- /dev/null +++ b/tests/qflags/test_QtCore_ComponentFormattingOptions_ComponentFormattingOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QUrl.ComponentFormattingOptions" and flag class "QUrl.ComponentFormattingOption" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QUrl.ComponentFormattingOption +MultiFlagClass = QtCore.QUrl.ComponentFormattingOptions + +oneFlagRefValue1 = QtCore.QUrl.ComponentFormattingOption.PrettyDecoded +oneFlagRefValue2 = QtCore.QUrl.ComponentFormattingOption.EncodeSpaces + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_ConversionFlags_ConversionFlag.py b/tests/qflags/test_QtCore_ConversionFlags_ConversionFlag.py new file mode 100644 index 00000000..94f556df --- /dev/null +++ b/tests/qflags/test_QtCore_ConversionFlags_ConversionFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextCodec.ConversionFlags" and flag class "QTextCodec.ConversionFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QTextCodec.ConversionFlag +MultiFlagClass = QtCore.QTextCodec.ConversionFlags + +oneFlagRefValue1 = QtCore.QTextCodec.ConversionFlag.DefaultConversion +oneFlagRefValue2 = QtCore.QTextCodec.ConversionFlag.ConvertInvalidToNull + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_DataSizeFormats_DataSizeFormat.py b/tests/qflags/test_QtCore_DataSizeFormats_DataSizeFormat.py new file mode 100644 index 00000000..0bcf8d1f --- /dev/null +++ b/tests/qflags/test_QtCore_DataSizeFormats_DataSizeFormat.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QLocale.DataSizeFormats" and flag class "QLocale.DataSizeFormat" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QLocale.DataSizeFormat +MultiFlagClass = QtCore.QLocale.DataSizeFormats + +oneFlagRefValue1 = QtCore.QLocale.DataSizeFormat.DataSizeIecFormat +oneFlagRefValue2 = QtCore.QLocale.DataSizeFormat.DataSizeTraditionalFormat + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_DockWidgetAreas_DockWidgetArea.py b/tests/qflags/test_QtCore_DockWidgetAreas_DockWidgetArea.py new file mode 100644 index 00000000..6cce4761 --- /dev/null +++ b/tests/qflags/test_QtCore_DockWidgetAreas_DockWidgetArea.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.DockWidgetAreas" and flag class "Qt.DockWidgetArea" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.DockWidgetArea +MultiFlagClass = QtCore.Qt.DockWidgetAreas + +oneFlagRefValue1 = QtCore.Qt.DockWidgetArea.LeftDockWidgetArea +oneFlagRefValue2 = QtCore.Qt.DockWidgetArea.RightDockWidgetArea + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_DropActions_DropAction.py b/tests/qflags/test_QtCore_DropActions_DropAction.py new file mode 100644 index 00000000..6c5a8ceb --- /dev/null +++ b/tests/qflags/test_QtCore_DropActions_DropAction.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.DropActions" and flag class "Qt.DropAction" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.DropAction +MultiFlagClass = QtCore.Qt.DropActions + +oneFlagRefValue1 = QtCore.Qt.DropAction.CopyAction +oneFlagRefValue2 = QtCore.Qt.DropAction.MoveAction + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_Edges_Edge.py b/tests/qflags/test_QtCore_Edges_Edge.py new file mode 100644 index 00000000..05048e21 --- /dev/null +++ b/tests/qflags/test_QtCore_Edges_Edge.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.Edges" and flag class "Qt.Edge" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.Edge +MultiFlagClass = QtCore.Qt.Edges + +oneFlagRefValue1 = QtCore.Qt.Edge.TopEdge +oneFlagRefValue2 = QtCore.Qt.Edge.LeftEdge + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_FileHandleFlags_FileHandleFlag.py b/tests/qflags/test_QtCore_FileHandleFlags_FileHandleFlag.py new file mode 100644 index 00000000..8339fa5d --- /dev/null +++ b/tests/qflags/test_QtCore_FileHandleFlags_FileHandleFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QFileDevice.FileHandleFlags" and flag class "QFileDevice.FileHandleFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QFileDevice.FileHandleFlag +MultiFlagClass = QtCore.QFileDevice.FileHandleFlags + +oneFlagRefValue1 = QtCore.QFileDevice.FileHandleFlag.AutoCloseHandle +oneFlagRefValue2 = QtCore.QFileDevice.FileHandleFlag.DontCloseHandle + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_Filters_Filter.py b/tests/qflags/test_QtCore_Filters_Filter.py new file mode 100644 index 00000000..f3a9e61f --- /dev/null +++ b/tests/qflags/test_QtCore_Filters_Filter.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QDir.Filters" and flag class "QDir.Filter" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QDir.Filter +MultiFlagClass = QtCore.QDir.Filters + +oneFlagRefValue1 = QtCore.QDir.Filter.Dirs +oneFlagRefValue2 = QtCore.QDir.Filter.Files + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_FindChildOptions_FindChildOption.py b/tests/qflags/test_QtCore_FindChildOptions_FindChildOption.py new file mode 100644 index 00000000..32efffe3 --- /dev/null +++ b/tests/qflags/test_QtCore_FindChildOptions_FindChildOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.FindChildOptions" and flag class "Qt.FindChildOption" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.FindChildOption +MultiFlagClass = QtCore.Qt.FindChildOptions + +oneFlagRefValue1 = QtCore.Qt.FindChildOption.FindDirectChildrenOnly +oneFlagRefValue2 = QtCore.Qt.FindChildOption.FindChildrenRecursively + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_Flags_Flag.py b/tests/qflags/test_QtCore_Flags_Flag.py new file mode 100644 index 00000000..389b580f --- /dev/null +++ b/tests/qflags/test_QtCore_Flags_Flag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QCommandLineOption.Flags" and flag class "QCommandLineOption.Flag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QCommandLineOption.Flag +MultiFlagClass = QtCore.QCommandLineOption.Flags + +oneFlagRefValue1 = QtCore.QCommandLineOption.Flag.HiddenFromHelp +oneFlagRefValue2 = QtCore.QCommandLineOption.Flag.ShortOptionStyle + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_FormattingOptions_UrlFormattingOption.py b/tests/qflags/test_QtCore_FormattingOptions_UrlFormattingOption.py new file mode 100644 index 00000000..6a4cd2dd --- /dev/null +++ b/tests/qflags/test_QtCore_FormattingOptions_UrlFormattingOption.py @@ -0,0 +1,269 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# This file is used as a source to generate all qflags related tests. The specific part +# changes for each test but the rest of the file is totally identical +from PyQt5 import QtCore + +OneFlagClass = QtCore.QUrl.UrlFormattingOption +MultiFlagClass = QtCore.QUrl.FormattingOptions + +oneFlagRefValue1 = QtCore.QUrl.None_ +oneFlagRefValue2 = QtCore.QUrl.RemoveScheme + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 1. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + +### Disable the tests on multiflag for QUrl.FormattingOptions because the implementation does not support anything. +''' +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass(oneFlagValue1 | oneFlagValue1) + multiFlagValue2 = MultiFlagClass(oneFlagValue1 | oneFlagValue1) + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f4) +''' + diff --git a/tests/qflags/test_QtCore_GestureFlags_GestureFlag.py b/tests/qflags/test_QtCore_GestureFlags_GestureFlag.py new file mode 100644 index 00000000..0410daae --- /dev/null +++ b/tests/qflags/test_QtCore_GestureFlags_GestureFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.GestureFlags" and flag class "Qt.GestureFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.GestureFlag +MultiFlagClass = QtCore.Qt.GestureFlags + +oneFlagRefValue1 = QtCore.Qt.GestureFlag.DontStartGestureOnChildren +oneFlagRefValue2 = QtCore.Qt.GestureFlag.ReceivePartialGestures + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_ImageConversionFlags_ImageConversionFlag.py b/tests/qflags/test_QtCore_ImageConversionFlags_ImageConversionFlag.py new file mode 100644 index 00000000..c790de7c --- /dev/null +++ b/tests/qflags/test_QtCore_ImageConversionFlags_ImageConversionFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.ImageConversionFlags" and flag class "Qt.ImageConversionFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.ImageConversionFlag +MultiFlagClass = QtCore.Qt.ImageConversionFlags + +oneFlagRefValue1 = QtCore.Qt.ImageConversionFlag.AutoColor +oneFlagRefValue2 = QtCore.Qt.ImageConversionFlag.ColorOnly + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_InputMethodHints_InputMethodHint.py b/tests/qflags/test_QtCore_InputMethodHints_InputMethodHint.py new file mode 100644 index 00000000..556c7018 --- /dev/null +++ b/tests/qflags/test_QtCore_InputMethodHints_InputMethodHint.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.InputMethodHints" and flag class "Qt.InputMethodHint" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.InputMethodHint +MultiFlagClass = QtCore.Qt.InputMethodHints + +oneFlagRefValue1 = QtCore.Qt.InputMethodHint.ImhNone +oneFlagRefValue2 = QtCore.Qt.InputMethodHint.ImhHiddenText + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_InputMethodQueries_InputMethodQuery.py b/tests/qflags/test_QtCore_InputMethodQueries_InputMethodQuery.py new file mode 100644 index 00000000..e3db721e --- /dev/null +++ b/tests/qflags/test_QtCore_InputMethodQueries_InputMethodQuery.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.InputMethodQueries" and flag class "Qt.InputMethodQuery" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.InputMethodQuery +MultiFlagClass = QtCore.Qt.InputMethodQueries + +oneFlagRefValue1 = QtCore.Qt.InputMethodQuery.ImMicroFocus +oneFlagRefValue2 = QtCore.Qt.InputMethodQuery.ImFont + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_ItemFlags_ItemFlag.py b/tests/qflags/test_QtCore_ItemFlags_ItemFlag.py new file mode 100644 index 00000000..dc5b0b7b --- /dev/null +++ b/tests/qflags/test_QtCore_ItemFlags_ItemFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.ItemFlags" and flag class "Qt.ItemFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.ItemFlag +MultiFlagClass = QtCore.Qt.ItemFlags + +oneFlagRefValue1 = QtCore.Qt.ItemFlag.NoItemFlags +oneFlagRefValue2 = QtCore.Qt.ItemFlag.ItemIsSelectable + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_IteratorFlags_IteratorFlag.py b/tests/qflags/test_QtCore_IteratorFlags_IteratorFlag.py new file mode 100644 index 00000000..3c23bef5 --- /dev/null +++ b/tests/qflags/test_QtCore_IteratorFlags_IteratorFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QDirIterator.IteratorFlags" and flag class "QDirIterator.IteratorFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QDirIterator.IteratorFlag +MultiFlagClass = QtCore.QDirIterator.IteratorFlags + +oneFlagRefValue1 = QtCore.QDirIterator.IteratorFlag.NoIteratorFlags +oneFlagRefValue2 = QtCore.QDirIterator.IteratorFlag.FollowSymlinks + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_KeyboardModifiers_KeyboardModifier.py b/tests/qflags/test_QtCore_KeyboardModifiers_KeyboardModifier.py new file mode 100644 index 00000000..857e2d46 --- /dev/null +++ b/tests/qflags/test_QtCore_KeyboardModifiers_KeyboardModifier.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.KeyboardModifiers" and flag class "Qt.KeyboardModifier" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.KeyboardModifier +MultiFlagClass = QtCore.Qt.KeyboardModifiers + +oneFlagRefValue1 = QtCore.Qt.KeyboardModifier.NoModifier +oneFlagRefValue2 = QtCore.Qt.KeyboardModifier.ShiftModifier + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_LoadHints_LoadHint.py b/tests/qflags/test_QtCore_LoadHints_LoadHint.py new file mode 100644 index 00000000..ec0b54dc --- /dev/null +++ b/tests/qflags/test_QtCore_LoadHints_LoadHint.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QLibrary.LoadHints" and flag class "QLibrary.LoadHint" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QLibrary.LoadHint +MultiFlagClass = QtCore.QLibrary.LoadHints + +oneFlagRefValue1 = QtCore.QLibrary.LoadHint.ResolveAllSymbolsHint +oneFlagRefValue2 = QtCore.QLibrary.LoadHint.ExportExternalSymbolsHint + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_LocateOptions_LocateOption.py b/tests/qflags/test_QtCore_LocateOptions_LocateOption.py new file mode 100644 index 00000000..9beb26d1 --- /dev/null +++ b/tests/qflags/test_QtCore_LocateOptions_LocateOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStandardPaths.LocateOptions" and flag class "QStandardPaths.LocateOption" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QStandardPaths.LocateOption +MultiFlagClass = QtCore.QStandardPaths.LocateOptions + +oneFlagRefValue1 = QtCore.QStandardPaths.LocateOption.LocateFile +oneFlagRefValue2 = QtCore.QStandardPaths.LocateOption.LocateDirectory + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_MatchFlags_MatchFlag.py b/tests/qflags/test_QtCore_MatchFlags_MatchFlag.py new file mode 100644 index 00000000..649447fb --- /dev/null +++ b/tests/qflags/test_QtCore_MatchFlags_MatchFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.MatchFlags" and flag class "Qt.MatchFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.MatchFlag +MultiFlagClass = QtCore.Qt.MatchFlags + +oneFlagRefValue1 = QtCore.Qt.MatchFlag.MatchExactly +oneFlagRefValue2 = QtCore.Qt.MatchFlag.MatchFixedString + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_MatchOptions_MatchOption.py b/tests/qflags/test_QtCore_MatchOptions_MatchOption.py new file mode 100644 index 00000000..ffadbf1a --- /dev/null +++ b/tests/qflags/test_QtCore_MatchOptions_MatchOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QRegularExpression.MatchOptions" and flag class "QRegularExpression.MatchOption" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QRegularExpression.MatchOption +MultiFlagClass = QtCore.QRegularExpression.MatchOptions + +oneFlagRefValue1 = QtCore.QRegularExpression.MatchOption.NoMatchOption +oneFlagRefValue2 = QtCore.QRegularExpression.MatchOption.AnchoredMatchOption + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_MouseButtons_MouseButton.py b/tests/qflags/test_QtCore_MouseButtons_MouseButton.py new file mode 100644 index 00000000..420131c2 --- /dev/null +++ b/tests/qflags/test_QtCore_MouseButtons_MouseButton.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.MouseButtons" and flag class "Qt.MouseButton" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.MouseButton +MultiFlagClass = QtCore.Qt.MouseButtons + +oneFlagRefValue1 = QtCore.Qt.MouseButton.NoButton +oneFlagRefValue2 = QtCore.Qt.MouseButton.AllButtons + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_MouseEventFlags_MouseEventFlag.py b/tests/qflags/test_QtCore_MouseEventFlags_MouseEventFlag.py new file mode 100644 index 00000000..3a6485f9 --- /dev/null +++ b/tests/qflags/test_QtCore_MouseEventFlags_MouseEventFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.MouseEventFlags" and flag class "Qt.MouseEventFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.MouseEventFlag +MultiFlagClass = QtCore.Qt.MouseEventFlags + +oneFlagRefValue1 = QtCore.Qt.MouseEventFlag.MouseEventCreatedDoubleClick +oneFlagRefValue2 = QtCore.Qt.MouseEventFlag.MouseEventCreatedDoubleClick + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_NumberFlags_NumberFlag.py b/tests/qflags/test_QtCore_NumberFlags_NumberFlag.py new file mode 100644 index 00000000..9dca3d75 --- /dev/null +++ b/tests/qflags/test_QtCore_NumberFlags_NumberFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextStream.NumberFlags" and flag class "QTextStream.NumberFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QTextStream.NumberFlag +MultiFlagClass = QtCore.QTextStream.NumberFlags + +oneFlagRefValue1 = QtCore.QTextStream.NumberFlag.ShowBase +oneFlagRefValue2 = QtCore.QTextStream.NumberFlag.ForcePoint + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_NumberOptions_NumberOption.py b/tests/qflags/test_QtCore_NumberOptions_NumberOption.py new file mode 100644 index 00000000..f40e09bc --- /dev/null +++ b/tests/qflags/test_QtCore_NumberOptions_NumberOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QLocale.NumberOptions" and flag class "QLocale.NumberOption" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QLocale.NumberOption +MultiFlagClass = QtCore.QLocale.NumberOptions + +oneFlagRefValue1 = QtCore.QLocale.NumberOption.OmitGroupSeparator +oneFlagRefValue2 = QtCore.QLocale.NumberOption.RejectGroupSeparator + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_OpenMode_OpenModeFlag.py b/tests/qflags/test_QtCore_OpenMode_OpenModeFlag.py new file mode 100644 index 00000000..175d2504 --- /dev/null +++ b/tests/qflags/test_QtCore_OpenMode_OpenModeFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QIODevice.OpenMode" and flag class "QIODevice.OpenModeFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QIODevice.OpenModeFlag +MultiFlagClass = QtCore.QIODevice.OpenMode + +oneFlagRefValue1 = QtCore.QIODevice.OpenModeFlag.NotOpen +oneFlagRefValue2 = QtCore.QIODevice.OpenModeFlag.ReadOnly + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_Orientations_Orientation.py b/tests/qflags/test_QtCore_Orientations_Orientation.py new file mode 100644 index 00000000..0b74b4c0 --- /dev/null +++ b/tests/qflags/test_QtCore_Orientations_Orientation.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.Orientations" and flag class "Qt.Orientation" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.Orientation +MultiFlagClass = QtCore.Qt.Orientations + +oneFlagRefValue1 = QtCore.Qt.Orientation.Horizontal +oneFlagRefValue2 = QtCore.Qt.Orientation.Vertical + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_PatternOptions_PatternOption.py b/tests/qflags/test_QtCore_PatternOptions_PatternOption.py new file mode 100644 index 00000000..dba0a118 --- /dev/null +++ b/tests/qflags/test_QtCore_PatternOptions_PatternOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QRegularExpression.PatternOptions" and flag class "QRegularExpression.PatternOption" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QRegularExpression.PatternOption +MultiFlagClass = QtCore.QRegularExpression.PatternOptions + +oneFlagRefValue1 = QtCore.QRegularExpression.PatternOption.NoPatternOption +oneFlagRefValue2 = QtCore.QRegularExpression.PatternOption.CaseInsensitiveOption + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_Permissions_Permission.py b/tests/qflags/test_QtCore_Permissions_Permission.py new file mode 100644 index 00000000..97575313 --- /dev/null +++ b/tests/qflags/test_QtCore_Permissions_Permission.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QFileDevice.Permissions" and flag class "QFileDevice.Permission" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QFileDevice.Permission +MultiFlagClass = QtCore.QFileDevice.Permissions + +oneFlagRefValue1 = QtCore.QFileDevice.Permission.ReadOwner +oneFlagRefValue2 = QtCore.QFileDevice.Permission.WriteOwner + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_ProcessEventsFlags_ProcessEventsFlag.py b/tests/qflags/test_QtCore_ProcessEventsFlags_ProcessEventsFlag.py new file mode 100644 index 00000000..5426fb3a --- /dev/null +++ b/tests/qflags/test_QtCore_ProcessEventsFlags_ProcessEventsFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QEventLoop.ProcessEventsFlags" and flag class "QEventLoop.ProcessEventsFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QEventLoop.ProcessEventsFlag +MultiFlagClass = QtCore.QEventLoop.ProcessEventsFlags + +oneFlagRefValue1 = QtCore.QEventLoop.ProcessEventsFlag.AllEvents +oneFlagRefValue2 = QtCore.QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_ScreenOrientations_ScreenOrientation.py b/tests/qflags/test_QtCore_ScreenOrientations_ScreenOrientation.py new file mode 100644 index 00000000..c3bfd0e0 --- /dev/null +++ b/tests/qflags/test_QtCore_ScreenOrientations_ScreenOrientation.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.ScreenOrientations" and flag class "Qt.ScreenOrientation" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.ScreenOrientation +MultiFlagClass = QtCore.Qt.ScreenOrientations + +oneFlagRefValue1 = QtCore.Qt.ScreenOrientation.PrimaryOrientation +oneFlagRefValue2 = QtCore.Qt.ScreenOrientation.PortraitOrientation + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_SelectionFlags_SelectionFlag.py b/tests/qflags/test_QtCore_SelectionFlags_SelectionFlag.py new file mode 100644 index 00000000..7139ee33 --- /dev/null +++ b/tests/qflags/test_QtCore_SelectionFlags_SelectionFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QItemSelectionModel.SelectionFlags" and flag class "QItemSelectionModel.SelectionFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QItemSelectionModel.SelectionFlag +MultiFlagClass = QtCore.QItemSelectionModel.SelectionFlags + +oneFlagRefValue1 = QtCore.QItemSelectionModel.SelectionFlag.NoUpdate +oneFlagRefValue2 = QtCore.QItemSelectionModel.SelectionFlag.Clear + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_SortFlags_SortFlag.py b/tests/qflags/test_QtCore_SortFlags_SortFlag.py new file mode 100644 index 00000000..1a340949 --- /dev/null +++ b/tests/qflags/test_QtCore_SortFlags_SortFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QDir.SortFlags" and flag class "QDir.SortFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QDir.SortFlag +MultiFlagClass = QtCore.QDir.SortFlags + +oneFlagRefValue1 = QtCore.QDir.SortFlag.Name +oneFlagRefValue2 = QtCore.QDir.SortFlag.Time + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_TextInteractionFlags_TextInteractionFlag.py b/tests/qflags/test_QtCore_TextInteractionFlags_TextInteractionFlag.py new file mode 100644 index 00000000..3108ae97 --- /dev/null +++ b/tests/qflags/test_QtCore_TextInteractionFlags_TextInteractionFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.TextInteractionFlags" and flag class "Qt.TextInteractionFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.TextInteractionFlag +MultiFlagClass = QtCore.Qt.TextInteractionFlags + +oneFlagRefValue1 = QtCore.Qt.TextInteractionFlag.NoTextInteraction +oneFlagRefValue2 = QtCore.Qt.TextInteractionFlag.TextSelectableByMouse + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_ToolBarAreas_ToolBarArea.py b/tests/qflags/test_QtCore_ToolBarAreas_ToolBarArea.py new file mode 100644 index 00000000..3eff8d7b --- /dev/null +++ b/tests/qflags/test_QtCore_ToolBarAreas_ToolBarArea.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.ToolBarAreas" and flag class "Qt.ToolBarArea" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.ToolBarArea +MultiFlagClass = QtCore.Qt.ToolBarAreas + +oneFlagRefValue1 = QtCore.Qt.ToolBarArea.LeftToolBarArea +oneFlagRefValue2 = QtCore.Qt.ToolBarArea.RightToolBarArea + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_TouchPointStates_TouchPointState.py b/tests/qflags/test_QtCore_TouchPointStates_TouchPointState.py new file mode 100644 index 00000000..60e48426 --- /dev/null +++ b/tests/qflags/test_QtCore_TouchPointStates_TouchPointState.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.TouchPointStates" and flag class "Qt.TouchPointState" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.TouchPointState +MultiFlagClass = QtCore.Qt.TouchPointStates + +oneFlagRefValue1 = QtCore.Qt.TouchPointState.TouchPointPressed +oneFlagRefValue2 = QtCore.Qt.TouchPointState.TouchPointMoved + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_TypeFlags_TypeFlag.py b/tests/qflags/test_QtCore_TypeFlags_TypeFlag.py new file mode 100644 index 00000000..a9516077 --- /dev/null +++ b/tests/qflags/test_QtCore_TypeFlags_TypeFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QMetaType.TypeFlags" and flag class "QMetaType.TypeFlag" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QMetaType.TypeFlag +MultiFlagClass = QtCore.QMetaType.TypeFlags + +oneFlagRefValue1 = QtCore.QMetaType.TypeFlag.NeedsConstruction +oneFlagRefValue2 = QtCore.QMetaType.TypeFlag.NeedsDestruction + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_UserInputResolutionOptions_UserInputResolutionOption.py b/tests/qflags/test_QtCore_UserInputResolutionOptions_UserInputResolutionOption.py new file mode 100644 index 00000000..41d9a397 --- /dev/null +++ b/tests/qflags/test_QtCore_UserInputResolutionOptions_UserInputResolutionOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QUrl.UserInputResolutionOptions" and flag class "QUrl.UserInputResolutionOption" +from PyQt5 import QtCore + +OneFlagClass = QtCore.QUrl.UserInputResolutionOption +MultiFlagClass = QtCore.QUrl.UserInputResolutionOptions + +oneFlagRefValue1 = QtCore.QUrl.UserInputResolutionOption.DefaultResolution +oneFlagRefValue2 = QtCore.QUrl.UserInputResolutionOption.AssumeLocalFile + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_WindowFlags_WindowType.py b/tests/qflags/test_QtCore_WindowFlags_WindowType.py new file mode 100644 index 00000000..7d861d22 --- /dev/null +++ b/tests/qflags/test_QtCore_WindowFlags_WindowType.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.WindowFlags" and flag class "Qt.WindowType" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.WindowType +MultiFlagClass = QtCore.Qt.WindowFlags + +oneFlagRefValue1 = QtCore.Qt.WindowType.Widget +oneFlagRefValue2 = QtCore.Qt.WindowType.Window + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtCore_WindowStates_WindowState.py b/tests/qflags/test_QtCore_WindowStates_WindowState.py new file mode 100644 index 00000000..e8d4b5f4 --- /dev/null +++ b/tests/qflags/test_QtCore_WindowStates_WindowState.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "Qt.WindowStates" and flag class "Qt.WindowState" +from PyQt5 import QtCore + +OneFlagClass = QtCore.Qt.WindowState +MultiFlagClass = QtCore.Qt.WindowStates + +oneFlagRefValue1 = QtCore.Qt.WindowState.WindowNoState +oneFlagRefValue2 = QtCore.Qt.WindowState.WindowMinimized + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtDBus_ConnectionCapabilities_ConnectionCapability.py b/tests/qflags/test_QtDBus_ConnectionCapabilities_ConnectionCapability.py new file mode 100644 index 00000000..56a682fe --- /dev/null +++ b/tests/qflags/test_QtDBus_ConnectionCapabilities_ConnectionCapability.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QDBusConnection.ConnectionCapabilities" and flag class "QDBusConnection.ConnectionCapability" +from PyQt5 import QtDBus + +OneFlagClass = QtDBus.QDBusConnection.ConnectionCapability +MultiFlagClass = QtDBus.QDBusConnection.ConnectionCapabilities + +oneFlagRefValue1 = QtDBus.QDBusConnection.ConnectionCapability.UnixFileDescriptorPassing +oneFlagRefValue2 = QtDBus.QDBusConnection.ConnectionCapability.UnixFileDescriptorPassing + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtDBus_RegisterOptions_RegisterOption.py b/tests/qflags/test_QtDBus_RegisterOptions_RegisterOption.py new file mode 100644 index 00000000..fd360243 --- /dev/null +++ b/tests/qflags/test_QtDBus_RegisterOptions_RegisterOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QDBusConnection.RegisterOptions" and flag class "QDBusConnection.RegisterOption" +from PyQt5 import QtDBus + +OneFlagClass = QtDBus.QDBusConnection.RegisterOption +MultiFlagClass = QtDBus.QDBusConnection.RegisterOptions + +oneFlagRefValue1 = QtDBus.QDBusConnection.RegisterOption.ExportAdaptors +oneFlagRefValue2 = QtDBus.QDBusConnection.RegisterOption.ExportScriptableSlots + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[True] = True +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtDBus_WatchMode_WatchModeFlag.py b/tests/qflags/test_QtDBus_WatchMode_WatchModeFlag.py new file mode 100644 index 00000000..035a52b3 --- /dev/null +++ b/tests/qflags/test_QtDBus_WatchMode_WatchModeFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QDBusServiceWatcher.WatchMode" and flag class "QDBusServiceWatcher.WatchModeFlag" +from PyQt5 import QtDBus + +OneFlagClass = QtDBus.QDBusServiceWatcher.WatchModeFlag +MultiFlagClass = QtDBus.QDBusServiceWatcher.WatchMode + +oneFlagRefValue1 = QtDBus.QDBusServiceWatcher.WatchModeFlag.WatchForRegistration +oneFlagRefValue2 = QtDBus.QDBusServiceWatcher.WatchModeFlag.WatchForUnregistration + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[True] = True +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_Capabilities_CapabilityFlag.py b/tests/qflags/test_QtGui_Capabilities_CapabilityFlag.py new file mode 100644 index 00000000..9c4555e8 --- /dev/null +++ b/tests/qflags/test_QtGui_Capabilities_CapabilityFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTouchDevice.Capabilities" and flag class "QTouchDevice.CapabilityFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QTouchDevice.CapabilityFlag +MultiFlagClass = QtGui.QTouchDevice.Capabilities + +oneFlagRefValue1 = QtGui.QTouchDevice.CapabilityFlag.Position +oneFlagRefValue2 = QtGui.QTouchDevice.CapabilityFlag.Area + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_DirtyFlags_DirtyFlag.py b/tests/qflags/test_QtGui_DirtyFlags_DirtyFlag.py new file mode 100644 index 00000000..60ac001f --- /dev/null +++ b/tests/qflags/test_QtGui_DirtyFlags_DirtyFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QPaintEngine.DirtyFlags" and flag class "QPaintEngine.DirtyFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QPaintEngine.DirtyFlag +MultiFlagClass = QtGui.QPaintEngine.DirtyFlags + +oneFlagRefValue1 = QtGui.QPaintEngine.DirtyFlag.DirtyPen +oneFlagRefValue2 = QtGui.QPaintEngine.DirtyFlag.DirtyBrush + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_Features_Feature.py b/tests/qflags/test_QtGui_Features_Feature.py new file mode 100644 index 00000000..c92b96cd --- /dev/null +++ b/tests/qflags/test_QtGui_Features_Feature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QOpenGLTexture.Features" and flag class "QOpenGLTexture.Feature" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QOpenGLTexture.Feature +MultiFlagClass = QtGui.QOpenGLTexture.Features + +oneFlagRefValue1 = QtGui.QOpenGLTexture.Feature.ImmutableStorage +oneFlagRefValue2 = QtGui.QOpenGLTexture.Feature.ImmutableMultisampleStorage + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_FindFlags_FindFlag.py b/tests/qflags/test_QtGui_FindFlags_FindFlag.py new file mode 100644 index 00000000..1b66051a --- /dev/null +++ b/tests/qflags/test_QtGui_FindFlags_FindFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextDocument.FindFlags" and flag class "QTextDocument.FindFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QTextDocument.FindFlag +MultiFlagClass = QtGui.QTextDocument.FindFlags + +oneFlagRefValue1 = QtGui.QTextDocument.FindFlag.FindBackward +oneFlagRefValue2 = QtGui.QTextDocument.FindFlag.FindCaseSensitively + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_Flags_Flag.py b/tests/qflags/test_QtGui_Flags_Flag.py new file mode 100644 index 00000000..418999dd --- /dev/null +++ b/tests/qflags/test_QtGui_Flags_Flag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextOption.Flags" and flag class "QTextOption.Flag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QTextOption.Flag +MultiFlagClass = QtGui.QTextOption.Flags + +oneFlagRefValue1 = QtGui.QTextOption.Flag.IncludeTrailingSpaces +oneFlagRefValue2 = QtGui.QTextOption.Flag.ShowTabsAndSpaces + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_FormatOptions_FormatOption.py b/tests/qflags/test_QtGui_FormatOptions_FormatOption.py new file mode 100644 index 00000000..20624463 --- /dev/null +++ b/tests/qflags/test_QtGui_FormatOptions_FormatOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QSurfaceFormat.FormatOptions" and flag class "QSurfaceFormat.FormatOption" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QSurfaceFormat.FormatOption +MultiFlagClass = QtGui.QSurfaceFormat.FormatOptions + +oneFlagRefValue1 = QtGui.QSurfaceFormat.FormatOption.StereoBuffers +oneFlagRefValue2 = QtGui.QSurfaceFormat.FormatOption.DebugContext + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_GlyphRunFlags_GlyphRunFlag.py b/tests/qflags/test_QtGui_GlyphRunFlags_GlyphRunFlag.py new file mode 100644 index 00000000..bfa93edd --- /dev/null +++ b/tests/qflags/test_QtGui_GlyphRunFlags_GlyphRunFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGlyphRun.GlyphRunFlags" and flag class "QGlyphRun.GlyphRunFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QGlyphRun.GlyphRunFlag +MultiFlagClass = QtGui.QGlyphRun.GlyphRunFlags + +oneFlagRefValue1 = QtGui.QGlyphRun.GlyphRunFlag.Overline +oneFlagRefValue2 = QtGui.QGlyphRun.GlyphRunFlag.Underline + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_InfoFlags_InfoFlag.py b/tests/qflags/test_QtGui_InfoFlags_InfoFlag.py new file mode 100644 index 00000000..7c47abbc --- /dev/null +++ b/tests/qflags/test_QtGui_InfoFlags_InfoFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTouchEvent.TouchPoint.InfoFlags" and flag class "QTouchEvent.TouchPoint.InfoFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QTouchEvent.TouchPoint.InfoFlag +MultiFlagClass = QtGui.QTouchEvent.TouchPoint.InfoFlags + +oneFlagRefValue1 = QtGui.QTouchEvent.TouchPoint.InfoFlag.Pen +oneFlagRefValue2 = QtGui.QTouchEvent.TouchPoint.InfoFlag.Token + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[True] = True +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_LayoutFlags_LayoutFlag.py b/tests/qflags/test_QtGui_LayoutFlags_LayoutFlag.py new file mode 100644 index 00000000..042f9f26 --- /dev/null +++ b/tests/qflags/test_QtGui_LayoutFlags_LayoutFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QRawFont.LayoutFlags" and flag class "QRawFont.LayoutFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QRawFont.LayoutFlag +MultiFlagClass = QtGui.QRawFont.LayoutFlags + +oneFlagRefValue1 = QtGui.QRawFont.LayoutFlag.SeparateAdvances +oneFlagRefValue2 = QtGui.QRawFont.LayoutFlag.KernedAdvances + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_MarkdownFeatures_MarkdownFeature.py b/tests/qflags/test_QtGui_MarkdownFeatures_MarkdownFeature.py new file mode 100644 index 00000000..0610c8f9 --- /dev/null +++ b/tests/qflags/test_QtGui_MarkdownFeatures_MarkdownFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextDocument.MarkdownFeatures" and flag class "QTextDocument.MarkdownFeature" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QTextDocument.MarkdownFeature +MultiFlagClass = QtGui.QTextDocument.MarkdownFeatures + +oneFlagRefValue1 = QtGui.QTextDocument.MarkdownFeature.MarkdownNoHTML +oneFlagRefValue2 = QtGui.QTextDocument.MarkdownFeature.MarkdownDialectCommonMark + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_PageBreakFlags_PageBreakFlag.py b/tests/qflags/test_QtGui_PageBreakFlags_PageBreakFlag.py new file mode 100644 index 00000000..25284e63 --- /dev/null +++ b/tests/qflags/test_QtGui_PageBreakFlags_PageBreakFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextFormat.PageBreakFlags" and flag class "QTextFormat.PageBreakFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QTextFormat.PageBreakFlag +MultiFlagClass = QtGui.QTextFormat.PageBreakFlags + +oneFlagRefValue1 = QtGui.QTextFormat.PageBreakFlag.PageBreak_Auto +oneFlagRefValue2 = QtGui.QTextFormat.PageBreakFlag.PageBreak_AlwaysBefore + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_PaintEngineFeatures_PaintEngineFeature.py b/tests/qflags/test_QtGui_PaintEngineFeatures_PaintEngineFeature.py new file mode 100644 index 00000000..f0a6010c --- /dev/null +++ b/tests/qflags/test_QtGui_PaintEngineFeatures_PaintEngineFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QPaintEngine.PaintEngineFeatures" and flag class "QPaintEngine.PaintEngineFeature" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QPaintEngine.PaintEngineFeature +MultiFlagClass = QtGui.QPaintEngine.PaintEngineFeatures + +oneFlagRefValue1 = QtGui.QPaintEngine.PaintEngineFeature.PrimitiveTransform +oneFlagRefValue2 = QtGui.QPaintEngine.PaintEngineFeature.PatternTransform + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_PixmapFragmentHints_PixmapFragmentHint.py b/tests/qflags/test_QtGui_PixmapFragmentHints_PixmapFragmentHint.py new file mode 100644 index 00000000..61513f18 --- /dev/null +++ b/tests/qflags/test_QtGui_PixmapFragmentHints_PixmapFragmentHint.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QPainter.PixmapFragmentHints" and flag class "QPainter.PixmapFragmentHint" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QPainter.PixmapFragmentHint +MultiFlagClass = QtGui.QPainter.PixmapFragmentHints + +oneFlagRefValue1 = QtGui.QPainter.PixmapFragmentHint.OpaqueHint +oneFlagRefValue2 = QtGui.QPainter.PixmapFragmentHint.OpaqueHint + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_RangeAccessFlags_RangeAccessFlag.py b/tests/qflags/test_QtGui_RangeAccessFlags_RangeAccessFlag.py new file mode 100644 index 00000000..43a3f008 --- /dev/null +++ b/tests/qflags/test_QtGui_RangeAccessFlags_RangeAccessFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QOpenGLBuffer.RangeAccessFlags" and flag class "QOpenGLBuffer.RangeAccessFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QOpenGLBuffer.RangeAccessFlag +MultiFlagClass = QtGui.QOpenGLBuffer.RangeAccessFlags + +oneFlagRefValue1 = QtGui.QOpenGLBuffer.RangeAccessFlag.RangeRead +oneFlagRefValue2 = QtGui.QOpenGLBuffer.RangeAccessFlag.RangeWrite + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_RenderFlags_RenderFlag.py b/tests/qflags/test_QtGui_RenderFlags_RenderFlag.py new file mode 100644 index 00000000..c6df42be --- /dev/null +++ b/tests/qflags/test_QtGui_RenderFlags_RenderFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextItem.RenderFlags" and flag class "QTextItem.RenderFlag" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QTextItem.RenderFlag +MultiFlagClass = QtGui.QTextItem.RenderFlags + +oneFlagRefValue1 = QtGui.QTextItem.RenderFlag.RightToLeft +oneFlagRefValue2 = QtGui.QTextItem.RenderFlag.Overline + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_RenderHints_RenderHint.py b/tests/qflags/test_QtGui_RenderHints_RenderHint.py new file mode 100644 index 00000000..1c058bc7 --- /dev/null +++ b/tests/qflags/test_QtGui_RenderHints_RenderHint.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QPainter.RenderHints" and flag class "QPainter.RenderHint" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QPainter.RenderHint +MultiFlagClass = QtGui.QPainter.RenderHints + +oneFlagRefValue1 = QtGui.QPainter.RenderHint.Antialiasing +oneFlagRefValue2 = QtGui.QPainter.RenderHint.TextAntialiasing + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_Severities_Severity.py b/tests/qflags/test_QtGui_Severities_Severity.py new file mode 100644 index 00000000..f0d57d58 --- /dev/null +++ b/tests/qflags/test_QtGui_Severities_Severity.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QOpenGLDebugMessage.Severities" and flag class "QOpenGLDebugMessage.Severity" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QOpenGLDebugMessage.Severity +MultiFlagClass = QtGui.QOpenGLDebugMessage.Severities + +oneFlagRefValue1 = QtGui.QOpenGLDebugMessage.Severity.InvalidSeverity +oneFlagRefValue2 = QtGui.QOpenGLDebugMessage.Severity.HighSeverity + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_ShaderType_ShaderTypeBit.py b/tests/qflags/test_QtGui_ShaderType_ShaderTypeBit.py new file mode 100644 index 00000000..0b884ce1 --- /dev/null +++ b/tests/qflags/test_QtGui_ShaderType_ShaderTypeBit.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QOpenGLShader.ShaderType" and flag class "QOpenGLShader.ShaderTypeBit" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QOpenGLShader.ShaderTypeBit +MultiFlagClass = QtGui.QOpenGLShader.ShaderType + +oneFlagRefValue1 = QtGui.QOpenGLShader.ShaderTypeBit.Vertex +oneFlagRefValue2 = QtGui.QOpenGLShader.ShaderTypeBit.Fragment + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_Sources_Source.py b/tests/qflags/test_QtGui_Sources_Source.py new file mode 100644 index 00000000..9e324026 --- /dev/null +++ b/tests/qflags/test_QtGui_Sources_Source.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QOpenGLDebugMessage.Sources" and flag class "QOpenGLDebugMessage.Source" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QOpenGLDebugMessage.Source +MultiFlagClass = QtGui.QOpenGLDebugMessage.Sources + +oneFlagRefValue1 = QtGui.QOpenGLDebugMessage.Source.InvalidSource +oneFlagRefValue2 = QtGui.QOpenGLDebugMessage.Source.APISource + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_Transformations_Transformation.py b/tests/qflags/test_QtGui_Transformations_Transformation.py new file mode 100644 index 00000000..68b403a1 --- /dev/null +++ b/tests/qflags/test_QtGui_Transformations_Transformation.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QImageIOHandler.Transformations" and flag class "QImageIOHandler.Transformation" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QImageIOHandler.Transformation +MultiFlagClass = QtGui.QImageIOHandler.Transformations + +oneFlagRefValue1 = QtGui.QImageIOHandler.Transformation.TransformationNone +oneFlagRefValue2 = QtGui.QImageIOHandler.Transformation.TransformationMirror + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtGui_Types_Type.py b/tests/qflags/test_QtGui_Types_Type.py new file mode 100644 index 00000000..0e7a3b19 --- /dev/null +++ b/tests/qflags/test_QtGui_Types_Type.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QOpenGLDebugMessage.Types" and flag class "QOpenGLDebugMessage.Type" +from PyQt5 import QtGui + +OneFlagClass = QtGui.QOpenGLDebugMessage.Type +MultiFlagClass = QtGui.QOpenGLDebugMessage.Types + +oneFlagRefValue1 = QtGui.QOpenGLDebugMessage.Type.InvalidType +oneFlagRefValue2 = QtGui.QOpenGLDebugMessage.Type.ErrorType + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_BindMode_BindFlag.py b/tests/qflags/test_QtNetwork_BindMode_BindFlag.py new file mode 100644 index 00000000..fce29fac --- /dev/null +++ b/tests/qflags/test_QtNetwork_BindMode_BindFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QAbstractSocket.BindMode" and flag class "QAbstractSocket.BindFlag" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QAbstractSocket.BindFlag +MultiFlagClass = QtNetwork.QAbstractSocket.BindMode + +oneFlagRefValue1 = QtNetwork.QAbstractSocket.BindFlag.DefaultForPlatform +oneFlagRefValue2 = QtNetwork.QAbstractSocket.BindFlag.ShareAddress + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_Capabilities_Capability.py b/tests/qflags/test_QtNetwork_Capabilities_Capability.py new file mode 100644 index 00000000..150a8949 --- /dev/null +++ b/tests/qflags/test_QtNetwork_Capabilities_Capability.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QNetworkProxy.Capabilities" and flag class "QNetworkProxy.Capability" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QNetworkProxy.Capability +MultiFlagClass = QtNetwork.QNetworkProxy.Capabilities + +oneFlagRefValue1 = QtNetwork.QNetworkProxy.Capability.TunnelingCapability +oneFlagRefValue2 = QtNetwork.QNetworkProxy.Capability.ListeningCapability + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_ConversionMode_ConversionModeFlag.py b/tests/qflags/test_QtNetwork_ConversionMode_ConversionModeFlag.py new file mode 100644 index 00000000..ae275d5d --- /dev/null +++ b/tests/qflags/test_QtNetwork_ConversionMode_ConversionModeFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QHostAddress.ConversionMode" and flag class "QHostAddress.ConversionModeFlag" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QHostAddress.ConversionModeFlag +MultiFlagClass = QtNetwork.QHostAddress.ConversionMode + +oneFlagRefValue1 = QtNetwork.QHostAddress.ConversionModeFlag.ConvertV4MappedToIPv4 +oneFlagRefValue2 = QtNetwork.QHostAddress.ConversionModeFlag.ConvertV4CompatToIPv4 + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_InterfaceFlags_InterfaceFlag.py b/tests/qflags/test_QtNetwork_InterfaceFlags_InterfaceFlag.py new file mode 100644 index 00000000..4ab0e7c8 --- /dev/null +++ b/tests/qflags/test_QtNetwork_InterfaceFlags_InterfaceFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QNetworkInterface.InterfaceFlags" and flag class "QNetworkInterface.InterfaceFlag" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QNetworkInterface.InterfaceFlag +MultiFlagClass = QtNetwork.QNetworkInterface.InterfaceFlags + +oneFlagRefValue1 = QtNetwork.QNetworkInterface.InterfaceFlag.IsUp +oneFlagRefValue2 = QtNetwork.QNetworkInterface.InterfaceFlag.IsRunning + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_PauseModes_PauseMode.py b/tests/qflags/test_QtNetwork_PauseModes_PauseMode.py new file mode 100644 index 00000000..724aa9fb --- /dev/null +++ b/tests/qflags/test_QtNetwork_PauseModes_PauseMode.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QAbstractSocket.PauseModes" and flag class "QAbstractSocket.PauseMode" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QAbstractSocket.PauseMode +MultiFlagClass = QtNetwork.QAbstractSocket.PauseModes + +oneFlagRefValue1 = QtNetwork.QAbstractSocket.PauseMode.PauseNever +oneFlagRefValue2 = QtNetwork.QAbstractSocket.PauseMode.PauseOnSslErrors + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_PolicyFlags_PolicyFlag.py b/tests/qflags/test_QtNetwork_PolicyFlags_PolicyFlag.py new file mode 100644 index 00000000..35edd3ec --- /dev/null +++ b/tests/qflags/test_QtNetwork_PolicyFlags_PolicyFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QHstsPolicy.PolicyFlags" and flag class "QHstsPolicy.PolicyFlag" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QHstsPolicy.PolicyFlag +MultiFlagClass = QtNetwork.QHstsPolicy.PolicyFlags + +oneFlagRefValue1 = QtNetwork.QHstsPolicy.PolicyFlag.IncludeSubDomains +oneFlagRefValue2 = QtNetwork.QHstsPolicy.PolicyFlag.IncludeSubDomains + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_SocketOptions_SocketOption.py b/tests/qflags/test_QtNetwork_SocketOptions_SocketOption.py new file mode 100644 index 00000000..c117e1c6 --- /dev/null +++ b/tests/qflags/test_QtNetwork_SocketOptions_SocketOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QLocalServer.SocketOptions" and flag class "QLocalServer.SocketOption" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QLocalServer.SocketOption +MultiFlagClass = QtNetwork.QLocalServer.SocketOptions + +oneFlagRefValue1 = QtNetwork.QLocalServer.SocketOption.UserAccessOption +oneFlagRefValue2 = QtNetwork.QLocalServer.SocketOption.GroupAccessOption + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_SslOptions_SslOption.py b/tests/qflags/test_QtNetwork_SslOptions_SslOption.py new file mode 100644 index 00000000..6b801072 --- /dev/null +++ b/tests/qflags/test_QtNetwork_SslOptions_SslOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QSsl.SslOptions" and flag class "QSsl.SslOption" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QSsl.SslOption +MultiFlagClass = QtNetwork.QSsl.SslOptions + +oneFlagRefValue1 = QtNetwork.QSsl.SslOption.SslOptionDisableEmptyFragments +oneFlagRefValue2 = QtNetwork.QSsl.SslOption.SslOptionDisableSessionTickets + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_StateFlags_StateFlag.py b/tests/qflags/test_QtNetwork_StateFlags_StateFlag.py new file mode 100644 index 00000000..79e175d3 --- /dev/null +++ b/tests/qflags/test_QtNetwork_StateFlags_StateFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QNetworkConfiguration.StateFlags" and flag class "QNetworkConfiguration.StateFlag" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QNetworkConfiguration.StateFlag +MultiFlagClass = QtNetwork.QNetworkConfiguration.StateFlags + +oneFlagRefValue1 = QtNetwork.QNetworkConfiguration.StateFlag.Undefined +oneFlagRefValue2 = QtNetwork.QNetworkConfiguration.StateFlag.Defined + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtNetwork_UsagePolicies_UsagePolicy.py b/tests/qflags/test_QtNetwork_UsagePolicies_UsagePolicy.py new file mode 100644 index 00000000..bf2f4034 --- /dev/null +++ b/tests/qflags/test_QtNetwork_UsagePolicies_UsagePolicy.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QNetworkSession.UsagePolicies" and flag class "QNetworkSession.UsagePolicy" +from PyQt5 import QtNetwork + +OneFlagClass = QtNetwork.QNetworkSession.UsagePolicy +MultiFlagClass = QtNetwork.QNetworkSession.UsagePolicies + +oneFlagRefValue1 = QtNetwork.QNetworkSession.UsagePolicy.NoPolicy +oneFlagRefValue2 = QtNetwork.QNetworkSession.UsagePolicy.NoBackgroundTrafficPolicy + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtOpenGL_BindOptions_BindOption.py b/tests/qflags/test_QtOpenGL_BindOptions_BindOption.py new file mode 100644 index 00000000..6d5753cd --- /dev/null +++ b/tests/qflags/test_QtOpenGL_BindOptions_BindOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGLContext.BindOptions" and flag class "QGLContext.BindOption" +from PyQt5 import QtOpenGL + +OneFlagClass = QtOpenGL.QGLContext.BindOption +MultiFlagClass = QtOpenGL.QGLContext.BindOptions + +oneFlagRefValue1 = QtOpenGL.QGLContext.BindOption.NoBindOption +oneFlagRefValue2 = QtOpenGL.QGLContext.BindOption.InvertedYBindOption + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtOpenGL_FormatOptions_FormatOption.py b/tests/qflags/test_QtOpenGL_FormatOptions_FormatOption.py new file mode 100644 index 00000000..3039902f --- /dev/null +++ b/tests/qflags/test_QtOpenGL_FormatOptions_FormatOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGL.FormatOptions" and flag class "QGL.FormatOption" +from PyQt5 import QtOpenGL + +OneFlagClass = QtOpenGL.QGL.FormatOption +MultiFlagClass = QtOpenGL.QGL.FormatOptions + +oneFlagRefValue1 = QtOpenGL.QGL.FormatOption.DoubleBuffer +oneFlagRefValue2 = QtOpenGL.QGL.FormatOption.DepthBuffer + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtOpenGL_OpenGLVersionFlags_OpenGLVersionFlag.py b/tests/qflags/test_QtOpenGL_OpenGLVersionFlags_OpenGLVersionFlag.py new file mode 100644 index 00000000..25400de5 --- /dev/null +++ b/tests/qflags/test_QtOpenGL_OpenGLVersionFlags_OpenGLVersionFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGLFormat.OpenGLVersionFlags" and flag class "QGLFormat.OpenGLVersionFlag" +from PyQt5 import QtOpenGL + +OneFlagClass = QtOpenGL.QGLFormat.OpenGLVersionFlag +MultiFlagClass = QtOpenGL.QGLFormat.OpenGLVersionFlags + +oneFlagRefValue1 = QtOpenGL.QGLFormat.OpenGLVersionFlag.OpenGL_Version_None +oneFlagRefValue2 = QtOpenGL.QGLFormat.OpenGLVersionFlag.OpenGL_Version_1_1 + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtPrintSupport_PrintDialogOptions_PrintDialogOption.py b/tests/qflags/test_QtPrintSupport_PrintDialogOptions_PrintDialogOption.py new file mode 100644 index 00000000..7cc178b1 --- /dev/null +++ b/tests/qflags/test_QtPrintSupport_PrintDialogOptions_PrintDialogOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QAbstractPrintDialog.PrintDialogOptions" and flag class "QAbstractPrintDialog.PrintDialogOption" +from PyQt5 import QtPrintSupport + +OneFlagClass = QtPrintSupport.QAbstractPrintDialog.PrintDialogOption +MultiFlagClass = QtPrintSupport.QAbstractPrintDialog.PrintDialogOptions + +oneFlagRefValue1 = QtPrintSupport.QAbstractPrintDialog.PrintDialogOption.None_ +oneFlagRefValue2 = QtPrintSupport.QAbstractPrintDialog.PrintDialogOption.PrintToFile + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtSql_ParamType_ParamTypeFlag.py b/tests/qflags/test_QtSql_ParamType_ParamTypeFlag.py new file mode 100644 index 00000000..f3fbc3a2 --- /dev/null +++ b/tests/qflags/test_QtSql_ParamType_ParamTypeFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QSql.ParamType" and flag class "QSql.ParamTypeFlag" +from PyQt5 import QtSql + +OneFlagClass = QtSql.QSql.ParamTypeFlag +MultiFlagClass = QtSql.QSql.ParamType + +oneFlagRefValue1 = QtSql.QSql.ParamTypeFlag.In +oneFlagRefValue2 = QtSql.QSql.ParamTypeFlag.Out + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_AreaOptions_AreaOption.py b/tests/qflags/test_QtWidgets_AreaOptions_AreaOption.py new file mode 100644 index 00000000..aaade60b --- /dev/null +++ b/tests/qflags/test_QtWidgets_AreaOptions_AreaOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QMdiArea.AreaOptions" and flag class "QMdiArea.AreaOption" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QMdiArea.AreaOption +MultiFlagClass = QtWidgets.QMdiArea.AreaOptions + +oneFlagRefValue1 = QtWidgets.QMdiArea.AreaOption.DontMaximizeSubWindowOnActivation +oneFlagRefValue2 = QtWidgets.QMdiArea.AreaOption.DontMaximizeSubWindowOnActivation + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_AutoFormatting_AutoFormattingFlag.py b/tests/qflags/test_QtWidgets_AutoFormatting_AutoFormattingFlag.py new file mode 100644 index 00000000..c089771c --- /dev/null +++ b/tests/qflags/test_QtWidgets_AutoFormatting_AutoFormattingFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTextEdit.AutoFormatting" and flag class "QTextEdit.AutoFormattingFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QTextEdit.AutoFormattingFlag +MultiFlagClass = QtWidgets.QTextEdit.AutoFormatting + +oneFlagRefValue1 = QtWidgets.QTextEdit.AutoFormattingFlag.AutoNone +oneFlagRefValue2 = QtWidgets.QTextEdit.AutoFormattingFlag.AutoBulletList + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_BlurHints_BlurHint.py b/tests/qflags/test_QtWidgets_BlurHints_BlurHint.py new file mode 100644 index 00000000..55b225fd --- /dev/null +++ b/tests/qflags/test_QtWidgets_BlurHints_BlurHint.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGraphicsBlurEffect.BlurHints" and flag class "QGraphicsBlurEffect.BlurHint" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QGraphicsBlurEffect.BlurHint +MultiFlagClass = QtWidgets.QGraphicsBlurEffect.BlurHints + +oneFlagRefValue1 = QtWidgets.QGraphicsBlurEffect.BlurHint.PerformanceHint +oneFlagRefValue2 = QtWidgets.QGraphicsBlurEffect.BlurHint.QualityHint + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_ButtonFeatures_ButtonFeature.py b/tests/qflags/test_QtWidgets_ButtonFeatures_ButtonFeature.py new file mode 100644 index 00000000..7a47e537 --- /dev/null +++ b/tests/qflags/test_QtWidgets_ButtonFeatures_ButtonFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyleOptionButton.ButtonFeatures" and flag class "QStyleOptionButton.ButtonFeature" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyleOptionButton.ButtonFeature +MultiFlagClass = QtWidgets.QStyleOptionButton.ButtonFeatures + +oneFlagRefValue1 = QtWidgets.QStyleOptionButton.ButtonFeature.None_ +oneFlagRefValue2 = QtWidgets.QStyleOptionButton.ButtonFeature.Flat + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_CacheMode_CacheModeFlag.py b/tests/qflags/test_QtWidgets_CacheMode_CacheModeFlag.py new file mode 100644 index 00000000..e9c3d889 --- /dev/null +++ b/tests/qflags/test_QtWidgets_CacheMode_CacheModeFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGraphicsView.CacheMode" and flag class "QGraphicsView.CacheModeFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QGraphicsView.CacheModeFlag +MultiFlagClass = QtWidgets.QGraphicsView.CacheMode + +oneFlagRefValue1 = QtWidgets.QGraphicsView.CacheModeFlag.CacheNone +oneFlagRefValue2 = QtWidgets.QGraphicsView.CacheModeFlag.CacheBackground + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_ChangeFlags_ChangeFlag.py b/tests/qflags/test_QtWidgets_ChangeFlags_ChangeFlag.py new file mode 100644 index 00000000..f62e8683 --- /dev/null +++ b/tests/qflags/test_QtWidgets_ChangeFlags_ChangeFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGraphicsEffect.ChangeFlags" and flag class "QGraphicsEffect.ChangeFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QGraphicsEffect.ChangeFlag +MultiFlagClass = QtWidgets.QGraphicsEffect.ChangeFlags + +oneFlagRefValue1 = QtWidgets.QGraphicsEffect.ChangeFlag.SourceAttached +oneFlagRefValue2 = QtWidgets.QGraphicsEffect.ChangeFlag.SourceDetached + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_ColorDialogOptions_ColorDialogOption.py b/tests/qflags/test_QtWidgets_ColorDialogOptions_ColorDialogOption.py new file mode 100644 index 00000000..aa4227dd --- /dev/null +++ b/tests/qflags/test_QtWidgets_ColorDialogOptions_ColorDialogOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QColorDialog.ColorDialogOptions" and flag class "QColorDialog.ColorDialogOption" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QColorDialog.ColorDialogOption +MultiFlagClass = QtWidgets.QColorDialog.ColorDialogOptions + +oneFlagRefValue1 = QtWidgets.QColorDialog.ColorDialogOption.ShowAlphaChannel +oneFlagRefValue2 = QtWidgets.QColorDialog.ColorDialogOption.NoButtons + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_ControlTypes_ControlType.py b/tests/qflags/test_QtWidgets_ControlTypes_ControlType.py new file mode 100644 index 00000000..d649c98a --- /dev/null +++ b/tests/qflags/test_QtWidgets_ControlTypes_ControlType.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QSizePolicy.ControlTypes" and flag class "QSizePolicy.ControlType" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QSizePolicy.ControlType +MultiFlagClass = QtWidgets.QSizePolicy.ControlTypes + +oneFlagRefValue1 = QtWidgets.QSizePolicy.ControlType.DefaultType +oneFlagRefValue2 = QtWidgets.QSizePolicy.ControlType.ButtonBox + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_CornerWidgets_CornerWidget.py b/tests/qflags/test_QtWidgets_CornerWidgets_CornerWidget.py new file mode 100644 index 00000000..731b71e7 --- /dev/null +++ b/tests/qflags/test_QtWidgets_CornerWidgets_CornerWidget.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyleOptionTab.CornerWidgets" and flag class "QStyleOptionTab.CornerWidget" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyleOptionTab.CornerWidget +MultiFlagClass = QtWidgets.QStyleOptionTab.CornerWidgets + +oneFlagRefValue1 = QtWidgets.QStyleOptionTab.CornerWidget.NoCornerWidgets +oneFlagRefValue2 = QtWidgets.QStyleOptionTab.CornerWidget.LeftCornerWidget + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_DockOptions_DockOption.py b/tests/qflags/test_QtWidgets_DockOptions_DockOption.py new file mode 100644 index 00000000..2688ed8a --- /dev/null +++ b/tests/qflags/test_QtWidgets_DockOptions_DockOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QMainWindow.DockOptions" and flag class "QMainWindow.DockOption" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QMainWindow.DockOption +MultiFlagClass = QtWidgets.QMainWindow.DockOptions + +oneFlagRefValue1 = QtWidgets.QMainWindow.DockOption.AnimatedDocks +oneFlagRefValue2 = QtWidgets.QMainWindow.DockOption.AllowNestedDocks + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_DockWidgetFeatures_DockWidgetFeature.py b/tests/qflags/test_QtWidgets_DockWidgetFeatures_DockWidgetFeature.py new file mode 100644 index 00000000..a8b45ed1 --- /dev/null +++ b/tests/qflags/test_QtWidgets_DockWidgetFeatures_DockWidgetFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QDockWidget.DockWidgetFeatures" and flag class "QDockWidget.DockWidgetFeature" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QDockWidget.DockWidgetFeature +MultiFlagClass = QtWidgets.QDockWidget.DockWidgetFeatures + +oneFlagRefValue1 = QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetClosable +oneFlagRefValue2 = QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_EditTriggers_EditTrigger.py b/tests/qflags/test_QtWidgets_EditTriggers_EditTrigger.py new file mode 100644 index 00000000..a0a259c2 --- /dev/null +++ b/tests/qflags/test_QtWidgets_EditTriggers_EditTrigger.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QAbstractItemView.EditTriggers" and flag class "QAbstractItemView.EditTrigger" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QAbstractItemView.EditTrigger +MultiFlagClass = QtWidgets.QAbstractItemView.EditTriggers + +oneFlagRefValue1 = QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers +oneFlagRefValue2 = QtWidgets.QAbstractItemView.EditTrigger.CurrentChanged + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_FontDialogOptions_FontDialogOption.py b/tests/qflags/test_QtWidgets_FontDialogOptions_FontDialogOption.py new file mode 100644 index 00000000..e917b5e0 --- /dev/null +++ b/tests/qflags/test_QtWidgets_FontDialogOptions_FontDialogOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QFontDialog.FontDialogOptions" and flag class "QFontDialog.FontDialogOption" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QFontDialog.FontDialogOption +MultiFlagClass = QtWidgets.QFontDialog.FontDialogOptions + +oneFlagRefValue1 = QtWidgets.QFontDialog.FontDialogOption.NoButtons +oneFlagRefValue2 = QtWidgets.QFontDialog.FontDialogOption.DontUseNativeDialog + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_FontFilters_FontFilter.py b/tests/qflags/test_QtWidgets_FontFilters_FontFilter.py new file mode 100644 index 00000000..5d567d86 --- /dev/null +++ b/tests/qflags/test_QtWidgets_FontFilters_FontFilter.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QFontComboBox.FontFilters" and flag class "QFontComboBox.FontFilter" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QFontComboBox.FontFilter +MultiFlagClass = QtWidgets.QFontComboBox.FontFilters + +oneFlagRefValue1 = QtWidgets.QFontComboBox.FontFilter.AllFonts +oneFlagRefValue2 = QtWidgets.QFontComboBox.FontFilter.ScalableFonts + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_FrameFeatures_FrameFeature.py b/tests/qflags/test_QtWidgets_FrameFeatures_FrameFeature.py new file mode 100644 index 00000000..1c6014c9 --- /dev/null +++ b/tests/qflags/test_QtWidgets_FrameFeatures_FrameFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyleOptionFrame.FrameFeatures" and flag class "QStyleOptionFrame.FrameFeature" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyleOptionFrame.FrameFeature +MultiFlagClass = QtWidgets.QStyleOptionFrame.FrameFeatures + +oneFlagRefValue1 = QtWidgets.QStyleOptionFrame.FrameFeature.None_ +oneFlagRefValue2 = QtWidgets.QStyleOptionFrame.FrameFeature.Flat + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_GraphicsItemFlags_GraphicsItemFlag.py b/tests/qflags/test_QtWidgets_GraphicsItemFlags_GraphicsItemFlag.py new file mode 100644 index 00000000..179f956b --- /dev/null +++ b/tests/qflags/test_QtWidgets_GraphicsItemFlags_GraphicsItemFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGraphicsItem.GraphicsItemFlags" and flag class "QGraphicsItem.GraphicsItemFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QGraphicsItem.GraphicsItemFlag +MultiFlagClass = QtWidgets.QGraphicsItem.GraphicsItemFlags + +oneFlagRefValue1 = QtWidgets.QGraphicsItem.GraphicsItemFlag.ItemIsMovable +oneFlagRefValue2 = QtWidgets.QGraphicsItem.GraphicsItemFlag.ItemIsSelectable + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_InputDialogOptions_InputDialogOption.py b/tests/qflags/test_QtWidgets_InputDialogOptions_InputDialogOption.py new file mode 100644 index 00000000..29819c40 --- /dev/null +++ b/tests/qflags/test_QtWidgets_InputDialogOptions_InputDialogOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QInputDialog.InputDialogOptions" and flag class "QInputDialog.InputDialogOption" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QInputDialog.InputDialogOption +MultiFlagClass = QtWidgets.QInputDialog.InputDialogOptions + +oneFlagRefValue1 = QtWidgets.QInputDialog.InputDialogOption.NoButtons +oneFlagRefValue2 = QtWidgets.QInputDialog.InputDialogOption.UseListViewForComboBoxItems + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_IteratorFlags_IteratorFlag.py b/tests/qflags/test_QtWidgets_IteratorFlags_IteratorFlag.py new file mode 100644 index 00000000..02f40eae --- /dev/null +++ b/tests/qflags/test_QtWidgets_IteratorFlags_IteratorFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QTreeWidgetItemIterator.IteratorFlags" and flag class "QTreeWidgetItemIterator.IteratorFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QTreeWidgetItemIterator.IteratorFlag +MultiFlagClass = QtWidgets.QTreeWidgetItemIterator.IteratorFlags + +oneFlagRefValue1 = QtWidgets.QTreeWidgetItemIterator.IteratorFlag.All +oneFlagRefValue2 = QtWidgets.QTreeWidgetItemIterator.IteratorFlag.Hidden + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_OptimizationFlags_OptimizationFlag.py b/tests/qflags/test_QtWidgets_OptimizationFlags_OptimizationFlag.py new file mode 100644 index 00000000..735eef27 --- /dev/null +++ b/tests/qflags/test_QtWidgets_OptimizationFlags_OptimizationFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGraphicsView.OptimizationFlags" and flag class "QGraphicsView.OptimizationFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QGraphicsView.OptimizationFlag +MultiFlagClass = QtWidgets.QGraphicsView.OptimizationFlags + +oneFlagRefValue1 = QtWidgets.QGraphicsView.OptimizationFlag.DontClipPainter +oneFlagRefValue2 = QtWidgets.QGraphicsView.OptimizationFlag.DontSavePainterState + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_Options_Option.py b/tests/qflags/test_QtWidgets_Options_Option.py new file mode 100644 index 00000000..6731b740 --- /dev/null +++ b/tests/qflags/test_QtWidgets_Options_Option.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QFileSystemModel.Options" and flag class "QFileSystemModel.Option" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QFileSystemModel.Option +MultiFlagClass = QtWidgets.QFileSystemModel.Options + +oneFlagRefValue1 = QtWidgets.QFileSystemModel.Option.DontWatchForChanges +oneFlagRefValue2 = QtWidgets.QFileSystemModel.Option.DontResolveSymlinks + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_RenderFlags_RenderFlag.py b/tests/qflags/test_QtWidgets_RenderFlags_RenderFlag.py new file mode 100644 index 00000000..fa7a1921 --- /dev/null +++ b/tests/qflags/test_QtWidgets_RenderFlags_RenderFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QWidget.RenderFlags" and flag class "QWidget.RenderFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QWidget.RenderFlag +MultiFlagClass = QtWidgets.QWidget.RenderFlags + +oneFlagRefValue1 = QtWidgets.QWidget.RenderFlag.DrawWindowBackground +oneFlagRefValue2 = QtWidgets.QWidget.RenderFlag.DrawChildren + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_Result_ResultFlag.py b/tests/qflags/test_QtWidgets_Result_ResultFlag.py new file mode 100644 index 00000000..2ec56fb3 --- /dev/null +++ b/tests/qflags/test_QtWidgets_Result_ResultFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGestureRecognizer.Result" and flag class "QGestureRecognizer.ResultFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QGestureRecognizer.ResultFlag +MultiFlagClass = QtWidgets.QGestureRecognizer.Result + +oneFlagRefValue1 = QtWidgets.QGestureRecognizer.ResultFlag.Ignore +oneFlagRefValue2 = QtWidgets.QGestureRecognizer.ResultFlag.MayBeGesture + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_SceneLayers_SceneLayer.py b/tests/qflags/test_QtWidgets_SceneLayers_SceneLayer.py new file mode 100644 index 00000000..ad70e282 --- /dev/null +++ b/tests/qflags/test_QtWidgets_SceneLayers_SceneLayer.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QGraphicsScene.SceneLayers" and flag class "QGraphicsScene.SceneLayer" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QGraphicsScene.SceneLayer +MultiFlagClass = QtWidgets.QGraphicsScene.SceneLayers + +oneFlagRefValue1 = QtWidgets.QGraphicsScene.SceneLayer.ItemLayer +oneFlagRefValue2 = QtWidgets.QGraphicsScene.SceneLayer.BackgroundLayer + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_Sections_Section.py b/tests/qflags/test_QtWidgets_Sections_Section.py new file mode 100644 index 00000000..07addbb6 --- /dev/null +++ b/tests/qflags/test_QtWidgets_Sections_Section.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QDateTimeEdit.Sections" and flag class "QDateTimeEdit.Section" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QDateTimeEdit.Section +MultiFlagClass = QtWidgets.QDateTimeEdit.Sections + +oneFlagRefValue1 = QtWidgets.QDateTimeEdit.Section.NoSection +oneFlagRefValue2 = QtWidgets.QDateTimeEdit.Section.AmPmSection + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_StandardButtons_StandardButton.py b/tests/qflags/test_QtWidgets_StandardButtons_StandardButton.py new file mode 100644 index 00000000..6ef52b8b --- /dev/null +++ b/tests/qflags/test_QtWidgets_StandardButtons_StandardButton.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QMessageBox.StandardButtons" and flag class "QMessageBox.StandardButton" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QMessageBox.StandardButton +MultiFlagClass = QtWidgets.QMessageBox.StandardButtons + +oneFlagRefValue1 = QtWidgets.QMessageBox.StandardButton.NoButton +oneFlagRefValue2 = QtWidgets.QMessageBox.StandardButton.Ok + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_State_StateFlag.py b/tests/qflags/test_QtWidgets_State_StateFlag.py new file mode 100644 index 00000000..fda1de44 --- /dev/null +++ b/tests/qflags/test_QtWidgets_State_StateFlag.py @@ -0,0 +1,253 @@ +# mypy: no-warn-unreachable + +from typing import Union, TypeVar, Type +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyle.State" and flag class "QStyle.StateFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyle.StateFlag +MultiFlagClass = QtWidgets.QStyle.State + +oneFlagRefValue1 = QtWidgets.QStyle.StateFlag.State_None +oneFlagRefValue2 = QtWidgets.QStyle.StateFlag.State_Enabled + +OR_CONVERTS_TO_MULTI = True +OR_INT_CONVERTS_TO_MULTI = False +INT_OR_CONVERTS_TO_MULTI = True +### End of specific part + +T = TypeVar('T') +def assert_type_of_value(expected_type: Type[T], value: T) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == expected_type + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + assert_type_of_value(OneFlagClass, oneFlagValue1) + assert_type_of_value(OneFlagClass, oneFlagValue2) + assert_type_of_value(OneFlagClass, oneFlagValueTest) + assert_type_of_value(int, intValue) + + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 33 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(33) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value(MultiFlagClass, oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value(int, oneFlagValue1 | oneFlagValue2) + + assert_type_of_value(int, ~oneFlagValue1) + assert_type_of_value(int, oneFlagValue1 & oneFlagValue2) + assert_type_of_value(int, oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value(MultiFlagClass, oneFlagValue1 | 33) + else: + assert_type_of_value(int, oneFlagValue1 | 33) + assert_type_of_value(int, oneFlagValue1 & 33) + assert_type_of_value(int, oneFlagValue1 ^ 33) + assert_type_of_value(int, oneFlagValue1 + 33) + assert_type_of_value(int, oneFlagValue1 - 33) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value(MultiFlagClass, 33 | oneFlagValue1) + else: + assert_type_of_value(int, 33 | oneFlagValue1) + assert_type_of_value(int, 33 & oneFlagValue1) + assert_type_of_value(int, 33 ^ oneFlagValue1) + assert_type_of_value(int, 33 + oneFlagValue1) + assert_type_of_value(int, 33 - oneFlagValue1) + + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value(OneFlagClass, oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + if OR_CONVERTS_TO_MULTI: + assert_type_of_value(MultiFlagClass, oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + assert_type_of_value(int, oneOrMultiFlagValueTest) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value(OneFlagClass, oneFlagOrIntValue) + oneFlagOrIntValue |= 33 + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value(MultiFlagClass, oneFlagOrIntValue) + else: + assert_type_of_value(int, oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value(OneFlagClass, oneFlagOrIntValue) + oneFlagOrIntValue &= 33 + assert_type_of_value(int, oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value(OneFlagClass, oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value(int, oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value(OneFlagClass, oneFlagOrIntValue) + oneFlagOrIntValue ^= 33 + assert_type_of_value(int, oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value(OneFlagClass, oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value(int, oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value(OneFlagClass, oneFlagValue1) + assert_type_of_value(MultiFlagClass, multiFlagValue1) + assert_type_of_value(MultiFlagClass, multiFlagValue2) + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + assert_type_of_value(int, intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value(MultiFlagClass, ~multiFlagValue1 ) + assert_type_of_value(MultiFlagClass, multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value(MultiFlagClass, multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value(MultiFlagClass, multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value(MultiFlagClass, multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value(MultiFlagClass, multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value(MultiFlagClass, multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value(MultiFlagClass, oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value(MultiFlagClass, oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value(MultiFlagClass, oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value(MultiFlagClass, multiFlagValue1 | 33) + assert_type_of_value(MultiFlagClass, multiFlagValue1 & 33) + assert_type_of_value(MultiFlagClass, multiFlagValue1 ^ 33) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value(int, intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 33 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(33) + + # assignments operations with OneFlagClass + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + + # assignments operations with int + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + multiFlagValueTest |= 33 + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + multiFlagValueTest &= 33 + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + multiFlagValueTest ^= 33 + assert_type_of_value(MultiFlagClass, multiFlagValueTest) + + #########################################################3 + # + # Exploring errors + # + #########################################################3 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 33 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 33 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 33 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 33) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 33) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 33 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 33 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 33 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 33 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_StepEnabled_StepEnabledFlag.py b/tests/qflags/test_QtWidgets_StepEnabled_StepEnabledFlag.py new file mode 100644 index 00000000..2bf3f0ad --- /dev/null +++ b/tests/qflags/test_QtWidgets_StepEnabled_StepEnabledFlag.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QAbstractSpinBox.StepEnabled" and flag class "QAbstractSpinBox.StepEnabledFlag" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QAbstractSpinBox.StepEnabledFlag +MultiFlagClass = QtWidgets.QAbstractSpinBox.StepEnabled + +oneFlagRefValue1 = QtWidgets.QAbstractSpinBox.StepEnabledFlag.StepNone +oneFlagRefValue2 = QtWidgets.QAbstractSpinBox.StepEnabledFlag.StepUpEnabled + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_SubControls_SubControl.py b/tests/qflags/test_QtWidgets_SubControls_SubControl.py new file mode 100644 index 00000000..68c62de3 --- /dev/null +++ b/tests/qflags/test_QtWidgets_SubControls_SubControl.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyle.SubControls" and flag class "QStyle.SubControl" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyle.SubControl +MultiFlagClass = QtWidgets.QStyle.SubControls + +oneFlagRefValue1 = QtWidgets.QStyle.SubControl.SC_None +oneFlagRefValue2 = QtWidgets.QStyle.SubControl.SC_ScrollBarAddLine + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_SubWindowOptions_SubWindowOption.py b/tests/qflags/test_QtWidgets_SubWindowOptions_SubWindowOption.py new file mode 100644 index 00000000..becbe72c --- /dev/null +++ b/tests/qflags/test_QtWidgets_SubWindowOptions_SubWindowOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QMdiSubWindow.SubWindowOptions" and flag class "QMdiSubWindow.SubWindowOption" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QMdiSubWindow.SubWindowOption +MultiFlagClass = QtWidgets.QMdiSubWindow.SubWindowOptions + +oneFlagRefValue1 = QtWidgets.QMdiSubWindow.SubWindowOption.RubberBandResize +oneFlagRefValue2 = QtWidgets.QMdiSubWindow.SubWindowOption.RubberBandMove + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_TabFeatures_TabFeature.py b/tests/qflags/test_QtWidgets_TabFeatures_TabFeature.py new file mode 100644 index 00000000..9a206982 --- /dev/null +++ b/tests/qflags/test_QtWidgets_TabFeatures_TabFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyleOptionTab.TabFeatures" and flag class "QStyleOptionTab.TabFeature" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyleOptionTab.TabFeature +MultiFlagClass = QtWidgets.QStyleOptionTab.TabFeatures + +oneFlagRefValue1 = QtWidgets.QStyleOptionTab.TabFeature.None_ +oneFlagRefValue2 = QtWidgets.QStyleOptionTab.TabFeature.HasFrame + +OR_CONVERTS_TO_MULTI: Literal[False] = False +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[False] = False +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_ToolBarFeatures_ToolBarFeature.py b/tests/qflags/test_QtWidgets_ToolBarFeatures_ToolBarFeature.py new file mode 100644 index 00000000..8e4b86c2 --- /dev/null +++ b/tests/qflags/test_QtWidgets_ToolBarFeatures_ToolBarFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyleOptionToolBar.ToolBarFeatures" and flag class "QStyleOptionToolBar.ToolBarFeature" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyleOptionToolBar.ToolBarFeature +MultiFlagClass = QtWidgets.QStyleOptionToolBar.ToolBarFeatures + +oneFlagRefValue1 = QtWidgets.QStyleOptionToolBar.ToolBarFeature.None_ +oneFlagRefValue2 = QtWidgets.QStyleOptionToolBar.ToolBarFeature.Movable + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_ToolButtonFeatures_ToolButtonFeature.py b/tests/qflags/test_QtWidgets_ToolButtonFeatures_ToolButtonFeature.py new file mode 100644 index 00000000..62aa5042 --- /dev/null +++ b/tests/qflags/test_QtWidgets_ToolButtonFeatures_ToolButtonFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyleOptionToolButton.ToolButtonFeatures" and flag class "QStyleOptionToolButton.ToolButtonFeature" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyleOptionToolButton.ToolButtonFeature +MultiFlagClass = QtWidgets.QStyleOptionToolButton.ToolButtonFeatures + +oneFlagRefValue1 = QtWidgets.QStyleOptionToolButton.ToolButtonFeature.None_ +oneFlagRefValue2 = QtWidgets.QStyleOptionToolButton.ToolButtonFeature.Arrow + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_ViewItemFeatures_ViewItemFeature.py b/tests/qflags/test_QtWidgets_ViewItemFeatures_ViewItemFeature.py new file mode 100644 index 00000000..ccf34743 --- /dev/null +++ b/tests/qflags/test_QtWidgets_ViewItemFeatures_ViewItemFeature.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QStyleOptionViewItem.ViewItemFeatures" and flag class "QStyleOptionViewItem.ViewItemFeature" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QStyleOptionViewItem.ViewItemFeature +MultiFlagClass = QtWidgets.QStyleOptionViewItem.ViewItemFeatures + +oneFlagRefValue1 = QtWidgets.QStyleOptionViewItem.ViewItemFeature.None_ +oneFlagRefValue2 = QtWidgets.QStyleOptionViewItem.ViewItemFeature.WrapText + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/qflags/test_QtWidgets_WizardOptions_WizardOption.py b/tests/qflags/test_QtWidgets_WizardOptions_WizardOption.py new file mode 100644 index 00000000..a169178f --- /dev/null +++ b/tests/qflags/test_QtWidgets_WizardOptions_WizardOption.py @@ -0,0 +1,266 @@ +# mypy: no-warn-unreachable + +import sys +from typing import Union, TypeVar, Type +if sys.version_info[:2] >= (3,8): + from typing import Literal +else: + from typing_extensions import Literal +import pytest + +### Specific part +# file generated from qflags_test_template.py for QFlags class "QWizard.WizardOptions" and flag class "QWizard.WizardOption" +from PyQt5 import QtWidgets + +OneFlagClass = QtWidgets.QWizard.WizardOption +MultiFlagClass = QtWidgets.QWizard.WizardOptions + +oneFlagRefValue1 = QtWidgets.QWizard.WizardOption.IndependentPages +oneFlagRefValue2 = QtWidgets.QWizard.WizardOption.IgnoreSubTitles + +OR_CONVERTS_TO_MULTI: Literal[True] = True +OR_INT_CONVERTS_TO_MULTI: Literal[False] = False +INT_OR_CONVERTS_TO_MULTI: Literal[True] = True +### End of specific part + +def assert_type_of_value_int(value: int) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert isinstance(value, int) + +def assert_type_of_value_oneFlag(value: OneFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == OneFlagClass + +def assert_type_of_value_multiFlag(value: MultiFlagClass) -> None: + '''Raise an exception if the value is not of type expected_type''' + assert type(value) == MultiFlagClass + + + +def test_on_one_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + oneFlagValue2 = oneFlagRefValue2 + oneFlagValueTest = oneFlagValue1 # type: OneFlagClass + intValue = 0 # type: int + oneOrMultiFlagValueTest = oneFlagValue1 # type: Union[OneFlagClass, MultiFlagClass] + oneFlagOrIntValue = oneFlagValue1 # type: Union[int, OneFlagClass] + + # upcast from OneFlagClass to int + intValue = oneFlagValue1 + + # conversion also accepted + intValue = int(oneFlagValue1) + + # this is not supported type-safely for a good reason + oneFlagValueTest = 1 # type: ignore + + # correct way to do it + oneFlagValueTest = OneFlagClass(1) + oneFlagValueTest = OneFlagClass(oneFlagValue1) + + # The rules of OneFlagClass conversion defined in PyQt5 are: + # 1. | ~= with OneFlagClass return a MultiFlagClass (which is not compatible to int) + # Note that this breaks Liskov principle + # 2. everything else returns int: & ^ &= ^= + # 3. operations with int return int. + + if OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | oneFlagValue2) + else: + assert_type_of_value_int(oneFlagValue1 | oneFlagValue2) + + assert_type_of_value_int(~oneFlagValue1) + assert_type_of_value_int(oneFlagValue1 & oneFlagValue2) + assert_type_of_value_int(oneFlagValue1 ^ oneFlagValue2) + + # right operand + if OR_INT_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(oneFlagValue1 | 1) + else: + assert_type_of_value_int(oneFlagValue1 | 1) + assert_type_of_value_int(oneFlagValue1 & 1) + assert_type_of_value_int(oneFlagValue1 ^ 1) + assert_type_of_value_int(oneFlagValue1 + 1) + assert_type_of_value_int(oneFlagValue1 - 1) + + # left operand + if INT_OR_CONVERTS_TO_MULTI: + assert_type_of_value_multiFlag(1 | oneFlagValue1) + else: + assert_type_of_value_int(1 | oneFlagValue1) + assert_type_of_value_int(1 & oneFlagValue1) + assert_type_of_value_int(1 ^ oneFlagValue1) + assert_type_of_value_int(1 + oneFlagValue1) + assert_type_of_value_int(1 - oneFlagValue1) + + if OR_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= oneFlagValue2 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) # nice violation of Liskov principle here + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + if OR_INT_CONVERTS_TO_MULTI: + oneOrMultiFlagValueTest = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneOrMultiFlagValueTest) + oneOrMultiFlagValueTest |= 1 + assert_type_of_value_multiFlag(oneOrMultiFlagValueTest) + else: + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue |= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue &= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= 1 + assert_type_of_value_int(oneFlagOrIntValue) + + oneFlagOrIntValue = oneFlagValue1 # reset type and value + assert_type_of_value_oneFlag(oneFlagOrIntValue) + oneFlagOrIntValue ^= oneFlagValue2 + assert_type_of_value_int(oneFlagOrIntValue) + + + +def test_on_multi_flag_class() -> None: + oneFlagValue1 = oneFlagRefValue1 + multiFlagValue1 = MultiFlagClass() + multiFlagValue2 = MultiFlagClass() + multiFlagValueTest = multiFlagValue1 # type: MultiFlagClass + intValue = 0 + + assert_type_of_value_oneFlag(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue1) + assert_type_of_value_multiFlag(multiFlagValue2) + assert_type_of_value_multiFlag(multiFlagValueTest) + assert_type_of_value_int(intValue) + + + # MultiFlagClass may be created by combining MultiFlagClass together + assert_type_of_value_multiFlag( ~multiFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 | multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 & multiFlagValue2 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ multiFlagValue2 ) + + + # MultiFlagClass may be created by combining MultiFlagClass and OneFlagClass, left or right + assert_type_of_value_multiFlag( multiFlagValue1 | oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 & oneFlagValue1 ) + assert_type_of_value_multiFlag( multiFlagValue1 ^ oneFlagValue1 ) + + assert_type_of_value_multiFlag( oneFlagValue1 | multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 & multiFlagValue1 ) + assert_type_of_value_multiFlag( oneFlagValue1 ^ multiFlagValue1 ) + + + # MultClassFlag may be created by combining MultiFlagClass and int, right only + assert_type_of_value_multiFlag(multiFlagValue1 | 1) + assert_type_of_value_multiFlag(multiFlagValue1 & 1) + assert_type_of_value_multiFlag(multiFlagValue1 ^ 1) + + + # this is rejected by mypy and is slightly annoying: you can not pass a OneFlagClass variable to a method expecting a MultiFlagClass + # explicit typing must be used on those methods to accept both OneFlagClass and MultiFlagClass + multiFlagValueTest = oneFlagValue1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(oneFlagValue1) + assert_type_of_value_multiFlag(multiFlagValueTest) + + # this is rejected for the same reason as for OneFlagClass. + intValue = multiFlagValueTest # type: ignore + + # correct way to do it + intValue = int(multiFlagValueTest) + assert_type_of_value_int(intValue) + + # rejected by mypy rightfully + multiFlagValueTest = 1 # type: ignore + + # correct way to do it + multiFlagValueTest = MultiFlagClass(1) + + # assignments operations with OneFlagClass + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= oneFlagValue1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + # assignments operations with int + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest |= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest &= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + assert_type_of_value_multiFlag(multiFlagValueTest) + multiFlagValueTest ^= 1 + assert_type_of_value_multiFlag(multiFlagValueTest) + + #########################################################1 + # + # Exploring errors + # + #########################################################1 + + # This checks the following: + # + and - operations are not supported on MultiFlagClass + # combining int with MultiFlagClass does not work + + pytest.raises(TypeError, lambda: 1 | multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 & multiFlagValue1 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 ^ multiFlagValue1 ) # type: ignore[operator] + + pytest.raises(TypeError, lambda: multiFlagValue1 + multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - multiFlagValue2 ) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - oneFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 + 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: multiFlagValue1 - 1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: oneFlagValue1 - multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 + multiFlagValue1) # type: ignore[operator] + pytest.raises(TypeError, lambda: 1 - multiFlagValue1) # type: ignore[operator] + + def f1() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += oneFlagValue1 # type: ignore[assignment, operator] + def f2() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest += 1 # type: ignore[assignment, operator] + def f3() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= oneFlagValue1 # type: ignore[assignment, operator] + def f4() -> None: + multiFlagValueTest = MultiFlagClass() + multiFlagValueTest -= 1 # type: ignore[assignment, operator] + + pytest.raises(TypeError, f1) + pytest.raises(TypeError, f2) + pytest.raises(TypeError, f3) + pytest.raises(TypeError, f4) + diff --git a/tests/test_stubs.py b/tests/test_stubs.py index b56bf85b..20c0f4a4 100644 --- a/tests/test_stubs.py +++ b/tests/test_stubs.py @@ -1,34 +1,59 @@ -import os.path +import os +from pathlib import Path import pytest from mypy import api -TESTS_DIR = os.path.dirname(__file__) +TESTS_DIR = Path(__file__).parent def gen_tests(): - for filename in os.listdir(TESTS_DIR): - if filename.endswith('.py') and not filename.startswith('test_'): - yield filename + """List of all tests files included in the directory tests""" + for path in TESTS_DIR.glob('*.py'): + if not path.name.startswith('test_'): + yield path +def gen_abs_qflags_tests(): + """List of all tests included in the directory qflags""" + yield from TESTS_DIR.joinpath('qflags').glob('test_*.py') -@pytest.mark.parametrize('filename', list(gen_tests())) -def test_stubs(filename): + +@pytest.mark.parametrize('filepath', + list(gen_tests()), + ids=[v.relative_to(TESTS_DIR).as_posix() for v in gen_tests()] + ) +def test_stubs(filepath: Path) -> None: """Run mypy over example files.""" - path = os.path.join(TESTS_DIR, filename) - stdout, stderr, exitcode = api.run([path]) + stdout, stderr, exitcode = api.run([os.fspath(filepath)]) + if stdout: + print(stdout) + if stderr: + print(stderr) + + assert stdout.startswith("Success: no issues found") + assert not stderr + assert exitcode == 0 + + +def test_stubs_qflags() -> None: + """Run mypy over qflags files.""" + stdout, stderr, exitcode = api.run([os.fspath(path) for path in gen_abs_qflags_tests()]) if stdout: print(stdout) + if stderr: + print(stderr) assert stdout.startswith("Success: no issues found") assert not stderr assert exitcode == 0 +# note: no need to run explicitly pytest over qflags, because pytest finds them automatically -@pytest.mark.parametrize('filename', list(gen_tests())) -def test_files(filename): +@pytest.mark.parametrize('filepath', + list(gen_tests()), + ids=[v.parts[-1] for v in gen_tests()] + ) +def test_files(filepath): """Run the test files to make sure they work properly.""" - path = os.path.join(TESTS_DIR, filename) - with open(path, 'r') as f: - code = f.read() - exec(compile(code, filename, 'exec'), {}) + code = filepath.read_text(encoding='utf-8') + exec(compile(code, filepath, 'exec'), {})