Skip to content

Commit

Permalink
Typing: Extend wimp typing annotations
Browse files Browse the repository at this point in the history
Add overload info for constructors of:
* `CheckBox`
* `RadioButton`
* `Button`

Fix info for `Columns` constructor (`GIVEN` size)
Fix info for `Pile` constructor
  • Loading branch information
Aleksei Stepanov committed Sep 22, 2023
1 parent 9f94979 commit db7d55a
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 15 deletions.
2 changes: 1 addition & 1 deletion urwid/widget/columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(
self,
widget_list: Iterable[
Widget
| tuple[Literal["pack", WHSettings.PACK], Widget]
| tuple[Literal["pack", WHSettings.PACK] | int, Widget]
| tuple[Literal["weight", WHSettings.WEIGHT], int, Widget]
],
dividechars: int = 0,
Expand Down
10 changes: 9 additions & 1 deletion urwid/widget/pile.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ class Pile(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):

_sizing = frozenset([Sizing.FLOW, Sizing.BOX])

def __init__(self, widget_list: Iterable[Widget], focus_item: Widget | int | None = None) -> None:
def __init__(
self,
widget_list: Iterable[
Widget
| tuple[Literal["pack", WHSettings.PACK] | int, Widget]
| tuple[Literal["weight", WHSettings.WEIGHT], int, Widget]
],
focus_item: Widget | int | None = None,
) -> None:
"""
:param widget_list: child widgets
:type widget_list: iterable
Expand Down
124 changes: 111 additions & 13 deletions urwid/widget/wimp.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def __init__(
super().__init__(text, align=align, wrap=wrap, layout=layout)
self._cursor_position = cursor_position

def render(self, size: tuple[int], focus: bool = False) -> TextCanvas | CompositeCanvas:
def render(self, size: tuple[int], focus: bool = False) -> TextCanvas | CompositeCanvas: # type: ignore[override]
"""
Render the text content of this widget with a cursor when
in focus.
Expand All @@ -91,7 +91,7 @@ def render(self, size: tuple[int], focus: bool = False) -> TextCanvas | Composit
>>> si.render((2,), focus=True).cursor
(0, 1)
"""
c = super().render(size, focus)
c: TextCanvas | CompositeCanvas = super().render(size, focus)
if focus:
# create a new canvas so we can add a cursor
c = CompositeCanvas(c)
Expand Down Expand Up @@ -142,12 +142,66 @@ def sizing(self):
# (this variable is picked up by the MetaSignals metaclass)
signals: typing.ClassVar[list[str]] = ["change", "postchange"]

@typing.overload
def __init__(
self,
label,
state: bool = False,
has_mixed: typing.Literal[False] = False,
on_state_change: Callable[[Self, bool, _T], typing.Any] | None = None,
user_data: _T = ...,
checked_symbol: str | None = ...,
) -> None:
...

@typing.overload
def __init__(
self,
label,
state: bool = False,
has_mixed: typing.Literal[False] = False,
on_state_change: Callable[[Self, bool], typing.Any] | None = None,
user_data: None = None,
checked_symbol: str | None = ...,
) -> None:
...

@typing.overload
def __init__(
self,
label: str,
state: typing.Literal["mixed"] | bool = False,
has_mixed: typing.Literal[True] = True,
on_state_change: Callable[[Self, bool | typing.Literal["mixed"], _T], typing.Any] | None = None,
user_data: _T = ...,
checked_symbol: str | None = ...,
) -> None:
...

@typing.overload
def __init__(
self,
label: str,
state: typing.Literal["mixed"] | bool = False,
has_mixed: typing.Literal[True] = True,
on_state_change: Callable[[Self, bool | typing.Literal["mixed"]], typing.Any] | None = None,
user_data: None = None,
checked_symbol: str | None = ...,
) -> None:
...

def __init__(
self,
label,
state: bool | Literal["mixed"] = False,
has_mixed: bool = False,
on_state_change: Callable[[Self, bool, _T], typing.Any] | Callable[[Self, bool], typing.Any] | None = None,
has_mixed: typing.Literal[False, True] = False, # MyPy issue: Literal[True, False] is not equal `bool`
on_state_change: (
Callable[[Self, bool, _T], typing.Any]
| Callable[[Self, bool], typing.Any]
| Callable[[Self, bool | typing.Literal["mixed"], _T], typing.Any]
| Callable[[Self, bool | typing.Literal["mixed"]], typing.Any]
| None
) = None,
user_data: _T | None = None,
checked_symbol: str | None = None,
):
Expand Down Expand Up @@ -201,7 +255,7 @@ def __init__(
# Initial create expect no callbacks call, create explicit
super().__init__(
Columns(
[(Sizing.FIXED, self.reserve_columns, self.states[state]), self._label],
[(self.reserve_columns, self.states[state]), self._label],
focus_column=0,
),
)
Expand Down Expand Up @@ -294,7 +348,7 @@ def set_state(
self._emit("change", state)
self._state = state
# rebuild the display widget with the new state
self._w = Columns([(Sizing.FIXED, self.reserve_columns, self.states[state]), self._label], focus_column=0)
self._w = Columns([(self.reserve_columns, self.states[state]), self._label], focus_column=0)
if do_callback:
self._emit("postchange", old_state)

Expand Down Expand Up @@ -381,11 +435,33 @@ class RadioButton(CheckBox):
}
reserve_columns = 4

@typing.overload
def __init__(
self,
group: MutableSequence[CheckBox],
label,
state: bool | Literal["mixed", "first True"] = "first True",
state: bool | Literal["first True"] = ...,
on_state_change: Callable[[Self, bool, _T], typing.Any] | None = None,
user_data: _T = ...,
) -> None:
...

@typing.overload
def __init__(
self,
group: MutableSequence[CheckBox],
label,
state: bool | Literal["first True"] = ...,
on_state_change: Callable[[Self, bool], typing.Any] | None = None,
user_data: None = None,
) -> None:
...

def __init__(
self,
group: MutableSequence[CheckBox],
label,
state: bool | Literal["first True"] = "first True",
on_state_change: Callable[[Self, bool, _T], typing.Any] | Callable[[Self, bool], typing.Any] | None = None,
user_data: _T | None = None,
) -> None:
Expand Down Expand Up @@ -427,7 +503,7 @@ def __init__(
state = not group

self.group = group
super().__init__(label, state, False, on_state_change, user_data)
super().__init__(label, state, False, on_state_change, user_data) # type: ignore[call-overload]
group.append(self)

def set_state(self, state: bool | Literal["mixed"], do_callback: bool = True) -> None:
Expand Down Expand Up @@ -504,6 +580,32 @@ def sizing(self):

signals: typing.ClassVar[list[str]] = ["click"]

@typing.overload
def __init__(
self,
label,
on_press: Callable[[Self, _T], typing.Any] | None = None,
user_data: _T = ...,
*,
align: Literal["left", "center", "right"] | Align = ...,
wrap: Literal["space", "any", "clip", "ellipsis"] | WrapMode = ...,
layout: TextLayout | None = ...,
) -> None:
...

@typing.overload
def __init__(
self,
label,
on_press: Callable[[Self], typing.Any] | None = None,
user_data: None = None,
*,
align: Literal["left", "center", "right"] | Align = ...,
wrap: Literal["space", "any", "clip", "ellipsis"] | WrapMode = ...,
layout: TextLayout | None = ...,
) -> None:
...

def __init__(
self,
label,
Expand Down Expand Up @@ -551,11 +653,7 @@ def __init__(
"""
self._label = SelectableIcon(label, 0, align=align, wrap=wrap, layout=layout)
cols = Columns(
[
(Sizing.FIXED, 1, self.button_left),
self._label,
(Sizing.FIXED, 1, self.button_right),
],
[(1, self.button_left), self._label, (1, self.button_right)],
dividechars=1,
)
super().__init__(cols)
Expand Down

0 comments on commit db7d55a

Please sign in to comment.