urwid 2.5.0__cp312-cp312-win32.whl → 2.5.1__cp312-cp312-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of urwid might be problematic. Click here for more details.

urwid/canvas.py CHANGED
@@ -294,7 +294,7 @@ class Canvas:
294
294
  cols: int | None = None,
295
295
  rows: int | None = None,
296
296
  attr=None,
297
- ):
297
+ ) -> Iterable[list[tuple[object, object, bytes]]]:
298
298
  raise NotImplementedError()
299
299
 
300
300
  def cols(self):
@@ -489,10 +489,10 @@ class TextCanvas(Canvas):
489
489
  self,
490
490
  trim_left: int = 0,
491
491
  trim_top: int = 0,
492
- cols: int = 0,
493
- rows: int = 0,
494
- attr_map=None,
495
- ):
492
+ cols: int | None = 0,
493
+ rows: int | None = 0,
494
+ attr=None,
495
+ ) -> Iterable[tuple[object, object, bytes]]:
496
496
  """
497
497
  Return the canvas content as a list of rows where each row
498
498
  is a list of (attr, cs, text) tuples.
@@ -534,8 +534,8 @@ class TextCanvas(Canvas):
534
534
  i = 0
535
535
  row = []
536
536
  for (a, cs), run in attr_cs:
537
- if attr_map and a in attr_map:
538
- a = attr_map[a] # noqa: PLW2901
537
+ if attr and a in attr:
538
+ a = attr[a] # noqa: PLW2901
539
539
  row.append((a, cs, text[i : i + run]))
540
540
  i += run
541
541
  yield row
@@ -566,10 +566,10 @@ class BlankCanvas(Canvas):
566
566
  self,
567
567
  trim_left: int = 0,
568
568
  trim_top: int = 0,
569
- cols: int = 0,
570
- rows: int = 0,
569
+ cols: int | None = 0,
570
+ rows: int | None = 0,
571
571
  attr=None,
572
- ):
572
+ ) -> Iterable[list[tuple[object, object, bytes]]]:
573
573
  """
574
574
  return (cols, rows) of spaces with default attributes.
575
575
  """
@@ -621,7 +621,7 @@ class SolidCanvas(Canvas):
621
621
  cols: int | None = None,
622
622
  rows: int | None = None,
623
623
  attr=None,
624
- ):
624
+ ) -> Iterable[list[tuple[object, object, bytes]]]:
625
625
  if cols is None:
626
626
  cols = self.size[0]
627
627
  if rows is None:
@@ -717,7 +717,14 @@ class CompositeCanvas(Canvas):
717
717
  raise TypeError(cols)
718
718
  return cols
719
719
 
720
- def content(self):
720
+ def content(
721
+ self,
722
+ trim_left: int = 0,
723
+ trim_top: int = 0,
724
+ cols: int | None = None,
725
+ rows: int | None = None,
726
+ attr=None,
727
+ ) -> Iterable[list[tuple[object, object, bytes]]]:
721
728
  """
722
729
  Return the canvas content as a list of rows where each row
723
730
  is a list of (attr, cs, text) tuples.
urwid/command_map.py CHANGED
@@ -39,6 +39,8 @@ class Command(str, enum.Enum):
39
39
  MAX_RIGHT = "cursor max right"
40
40
  ACTIVATE = "activate"
41
41
  MENU = "menu"
42
+ SELECT_NEXT = "next selectable"
43
+ SELECT_PREVIOUS = "prev selectable"
42
44
 
43
45
 
44
46
  REDRAW_SCREEN = Command.REDRAW_SCREEN
@@ -84,10 +86,10 @@ class CommandMap(typing.Mapping[str, typing.Union[str, Command, None]]):
84
86
  return len(self._command)
85
87
 
86
88
  _command_defaults: typing.ClassVar[dict[str, str | Command]] = {
87
- "tab": "next selectable",
88
- "ctrl n": "next selectable",
89
- "shift tab": "prev selectable",
90
- "ctrl p": "prev selectable",
89
+ "tab": Command.SELECT_NEXT,
90
+ "ctrl n": Command.SELECT_NEXT,
91
+ "shift tab": Command.SELECT_PREVIOUS,
92
+ "ctrl p": Command.SELECT_PREVIOUS,
91
93
  "ctrl l": Command.REDRAW_SCREEN,
92
94
  "esc": Command.MENU,
93
95
  "up": Command.UP,
@@ -28,6 +28,7 @@ import contextlib
28
28
  import fcntl
29
29
  import functools
30
30
  import os
31
+ import selectors
31
32
  import signal
32
33
  import struct
33
34
  import sys
@@ -289,14 +290,24 @@ class Screen(_raw_display_base.Screen):
289
290
  raise
290
291
  return codes
291
292
 
292
- def _getch(self, timeout: int) -> int:
293
+ def _read_raw_input(self, timeout: int) -> bytearray:
293
294
  ready = self._wait_for_input_ready(timeout)
294
295
  if self.gpm_mev is not None and self.gpm_mev.stdout.fileno() in ready:
295
296
  self.gpm_event_pending = True
296
297
  fd = self._input_fileno()
297
- if fd is not None and fd in ready:
298
- return ord(os.read(fd, 1))
299
- return -1
298
+ chars = bytearray()
299
+
300
+ if fd is None or fd not in ready:
301
+ return chars
302
+
303
+ with selectors.DefaultSelector() as selector:
304
+ selector.register(fd, selectors.EVENT_READ)
305
+ input_ready = selector.select(0)
306
+ while input_ready:
307
+ chars.extend(os.read(fd, 1024))
308
+ input_ready = selector.select(0)
309
+
310
+ return chars
300
311
 
301
312
  def _encode_gpm_event(self) -> list[int]:
302
313
  self.gpm_event_pending = False
@@ -28,6 +28,7 @@ import abc
28
28
  import contextlib
29
29
  import functools
30
30
  import os
31
+ import platform
31
32
  import selectors
32
33
  import signal
33
34
  import socket
@@ -41,7 +42,7 @@ from .common import UNPRINTABLE_TRANS_TABLE, UPDATE_PALETTE_ENTRY, AttrSpec, Bas
41
42
 
42
43
  if typing.TYPE_CHECKING:
43
44
  import io
44
- from collections.abc import Callable
45
+ from collections.abc import Callable, Iterable
45
46
  from types import FrameType
46
47
 
47
48
  from typing_extensions import Literal
@@ -49,6 +50,7 @@ if typing.TYPE_CHECKING:
49
50
  from urwid import Canvas, EventLoop
50
51
 
51
52
  IS_WINDOWS = sys.platform == "win32"
53
+ IS_WSL = (sys.platform == "linux") and ("wsl" in platform.platform().lower())
52
54
 
53
55
 
54
56
  class Screen(BaseScreen, RealTerminal):
@@ -371,7 +373,7 @@ class Screen(BaseScreen, RealTerminal):
371
373
  return wrapper
372
374
 
373
375
  def _get_input_codes(self) -> list[int]:
374
- return self._get_keyboard_codes()
376
+ return list(self._get_keyboard_codes())
375
377
 
376
378
  def get_available_raw_input(self) -> list[int]:
377
379
  """
@@ -491,15 +493,6 @@ class Screen(BaseScreen, RealTerminal):
491
493
  # For get_input
492
494
  return decoded_codes, raw_codes
493
495
 
494
- def _get_keyboard_codes(self) -> list[int]:
495
- codes = []
496
- while True:
497
- code = self._getch_nodelay()
498
- if code < 0:
499
- break
500
- codes.append(code)
501
- return codes
502
-
503
496
  def _wait_for_input_ready(self, timeout: float | None) -> list[int]:
504
497
  logger = self.logger.getChild("wait_for_input_ready")
505
498
  fd_list = self.get_input_descriptors()
@@ -516,10 +509,10 @@ class Screen(BaseScreen, RealTerminal):
516
509
  return [event.fd for event, _ in ready]
517
510
 
518
511
  @abc.abstractmethod
519
- def _getch(self, timeout: int) -> int: ...
512
+ def _read_raw_input(self, timeout: int) -> Iterable[int]: ...
520
513
 
521
- def _getch_nodelay(self) -> int:
522
- return self._getch(0)
514
+ def _get_keyboard_codes(self) -> Iterable[int]:
515
+ return self._read_raw_input(0)
523
516
 
524
517
  def _setup_G1(self) -> None:
525
518
  """
@@ -603,10 +596,10 @@ class Screen(BaseScreen, RealTerminal):
603
596
  if isinstance(a, AttrSpec):
604
597
  return self._attrspec_to_escape(a)
605
598
  # undefined attributes use default/default
606
- # TODO: track and report these
599
+ self.logger.debug(f"Undefined attribute: {a!r}")
607
600
  return self._attrspec_to_escape(AttrSpec("default", "default"))
608
601
 
609
- def using_standout_or_underline(a):
602
+ def using_standout_or_underline(a: AttrSpec | str) -> bool:
610
603
  a = self._pal_attrspec.get(a, a)
611
604
  return isinstance(a, AttrSpec) and (a.standout or a.underline)
612
605
 
@@ -649,14 +642,17 @@ class Screen(BaseScreen, RealTerminal):
649
642
  first = True
650
643
  lasta = lastcs = None
651
644
  for a, cs, run in row:
652
- if not isinstance(run, bytes): # canvases should render with bytes
645
+ if not isinstance(run, bytes): # canvases render with bytes
653
646
  raise TypeError(run)
647
+
654
648
  if cs != "U":
655
649
  run = run.translate(UNPRINTABLE_TRANS_TABLE) # noqa: PLW2901
650
+
656
651
  if first or lasta != a:
657
652
  o.append(attr_to_escape(a))
658
653
  lasta = a
659
- if first or lastcs != cs:
654
+
655
+ if not (IS_WINDOWS or IS_WSL) and (first or lastcs != cs):
660
656
  if cs not in {None, "0", "U"}:
661
657
  raise ValueError(cs)
662
658
  if lastcs == "U":
@@ -669,23 +665,33 @@ class Screen(BaseScreen, RealTerminal):
669
665
  else:
670
666
  o.append(escape.SO)
671
667
  lastcs = cs
668
+
672
669
  o.append(run)
673
670
  first = False
671
+
674
672
  if ins:
675
673
  (inserta, insertcs, inserttext) = ins
676
674
  ias = attr_to_escape(inserta)
677
675
  if insertcs not in {None, "0", "U"}:
678
676
  raise ValueError(insertcs)
679
- if cs is None:
680
- icss = escape.SI
681
- elif cs == "U":
682
- icss = escape.IBMPC_ON
683
- else:
684
- icss = escape.SO
685
- o += ["\x08" * back, ias, icss, escape.INSERT_ON, inserttext, escape.INSERT_OFF]
686
677
 
687
- if cs == "U":
678
+ o.extend(("\x08" * back, ias))
679
+
680
+ if not (IS_WINDOWS or IS_WSL):
681
+ if cs is None:
682
+ icss = escape.SI
683
+ elif cs == "U":
684
+ icss = escape.IBMPC_ON
685
+ else:
686
+ icss = escape.SO
687
+
688
+ o.append(icss)
689
+
690
+ o += [escape.INSERT_ON, inserttext, escape.INSERT_OFF]
691
+
692
+ if not (IS_WINDOWS or IS_WSL) and cs == "U":
688
693
  o.append(escape.IBMPC_OFF)
694
+
689
695
  if whitespace_at_end:
690
696
  o.append(escape.ERASE_IN_LINE_RIGHT)
691
697
 
@@ -27,6 +27,7 @@ from __future__ import annotations
27
27
  import contextlib
28
28
  import functools
29
29
  import logging
30
+ import selectors
30
31
  import socket
31
32
  import sys
32
33
  import threading
@@ -177,13 +178,23 @@ class Screen(_raw_display_base.Screen):
177
178
 
178
179
  _input_thread: ReadInputThread | None = None
179
180
 
180
- def _getch(self, timeout: int) -> int:
181
+ def _read_raw_input(self, timeout: int) -> bytearray:
181
182
  ready = self._wait_for_input_ready(timeout)
182
183
 
183
184
  fd = self._input_fileno()
184
- if fd is not None and fd in ready:
185
- return ord(self._term_input_file.recv(1))
186
- return -1
185
+ chars = bytearray()
186
+
187
+ if fd is None or fd not in ready:
188
+ return chars
189
+
190
+ with selectors.DefaultSelector() as selector:
191
+ selector.register(fd, selectors.EVENT_READ)
192
+ input_ready = selector.select(0)
193
+ while input_ready:
194
+ chars.extend(self._term_input_file.recv(1024))
195
+ input_ready = selector.select(0)
196
+
197
+ return chars
187
198
 
188
199
  def get_cols_rows(self) -> tuple[int, int]:
189
200
  """Return the terminal dimensions (num columns, num rows)."""
urwid/str_util.pyd CHANGED
Binary file
urwid/version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '2.5.0'
16
- __version_tuple__ = version_tuple = (2, 5, 0)
15
+ __version__ = version = '2.5.1'
16
+ __version_tuple__ = version_tuple = (2, 5, 1)
urwid/vterm.py CHANGED
@@ -1437,11 +1437,11 @@ class TermCanvas(Canvas):
1437
1437
  def content(
1438
1438
  self,
1439
1439
  trim_left: int = 0,
1440
- trim_right: int = 0,
1440
+ trim_top: int = 0,
1441
1441
  cols: int | None = None,
1442
1442
  rows: int | None = None,
1443
1443
  attr=None,
1444
- ):
1444
+ ) -> Iterable[list[tuple[object, object, bytes]]]:
1445
1445
  if self.scrolling_up == 0:
1446
1446
  yield from self.term
1447
1447
  else:
@@ -1669,7 +1669,7 @@ class Terminal(Widget):
1669
1669
  elif hasattr(self, "old_tios"):
1670
1670
  RealTerminal().tty_signal_keys(*self.old_tios)
1671
1671
 
1672
- def render(self, size: tuple[int, int], focus: bool = False):
1672
+ def render(self, size: tuple[int, int], focus: bool = False) -> TermCanvas:
1673
1673
  if not self.terminated:
1674
1674
  self.change_focus(focus)
1675
1675
 
urwid/widget/attr_map.py CHANGED
@@ -5,22 +5,24 @@ from collections.abc import Hashable, Mapping
5
5
 
6
6
  from urwid.canvas import CompositeCanvas
7
7
 
8
- from .widget import Widget, WidgetError, delegate_to_widget_mixin
8
+ from .widget import WidgetError, delegate_to_widget_mixin
9
9
  from .widget_decoration import WidgetDecoration
10
10
 
11
+ WrappedWidget = typing.TypeVar("WrappedWidget")
12
+
11
13
 
12
14
  class AttrMapError(WidgetError):
13
15
  pass
14
16
 
15
17
 
16
- class AttrMap(delegate_to_widget_mixin("_original_widget"), WidgetDecoration):
18
+ class AttrMap(delegate_to_widget_mixin("_original_widget"), WidgetDecoration[WrappedWidget]):
17
19
  """
18
20
  AttrMap is a decoration that maps one set of attributes to another.
19
21
  This object will pass all function calls and variable references to the
20
22
  wrapped widget.
21
23
  """
22
24
 
23
- def __init__(self, w: Widget, attr_map, focus_map=None) -> None:
25
+ def __init__(self, w: WrappedWidget, attr_map, focus_map=None) -> None:
24
26
  """
25
27
  :param w: widget to wrap (stored as self.original_widget)
26
28
  :type w: widget
urwid/widget/bar_graph.py CHANGED
@@ -52,7 +52,7 @@ class BarGraph(Widget, metaclass=BarGraphMeta):
52
52
  eighths = BAR_SYMBOLS.VERTICAL[:8] # Full height is done by style
53
53
  hlines = "_⎺⎻─⎼⎽"
54
54
 
55
- def __init__(self, attlist, hatt=None, satt=None):
55
+ def __init__(self, attlist, hatt=None, satt=None) -> None:
56
56
  """
57
57
  Create a bar graph with the passed display characteristics.
58
58
  see set_segment_attributes for a description of the parameters.
@@ -134,7 +134,7 @@ class BarGraph(Widget, metaclass=BarGraphMeta):
134
134
  raise BarGraphError(f"fg ({fg}) not > bg ({bg})")
135
135
  self.satt = satt
136
136
 
137
- def set_data(self, bardata, top, hlines=None):
137
+ def set_data(self, bardata, top: float, hlines=None) -> None:
138
138
  """
139
139
  Store bar data, bargraph top and horizontal line positions.
140
140
 
@@ -428,7 +428,7 @@ class BarGraph(Widget, metaclass=BarGraphMeta):
428
428
  return canv
429
429
 
430
430
 
431
- def calculate_bargraph_display(bardata, top, bar_widths, maxrow: int):
431
+ def calculate_bargraph_display(bardata, top: float, bar_widths: list[int], maxrow: int):
432
432
  """
433
433
  Calculate a rendering of the bar graph described by data, bar_widths
434
434
  and height.
@@ -574,7 +574,7 @@ def calculate_bargraph_display(bardata, top, bar_widths, maxrow: int):
574
574
  class GraphVScale(Widget):
575
575
  _sizing = frozenset([Sizing.BOX])
576
576
 
577
- def __init__(self, labels, top):
577
+ def __init__(self, labels, top: float) -> None:
578
578
  """
579
579
  GraphVScale( [(label1 position, label1 markup),...], top )
580
580
  label position -- 0 < position < top for the y position
@@ -587,7 +587,7 @@ class GraphVScale(Widget):
587
587
  super().__init__()
588
588
  self.set_scale(labels, top)
589
589
 
590
- def set_scale(self, labels, top):
590
+ def set_scale(self, labels, top: float) -> None:
591
591
  """
592
592
  set_scale( [(label1 position, label1 markup),...], top )
593
593
  label position -- 0 < position < top for the y position
@@ -610,7 +610,7 @@ class GraphVScale(Widget):
610
610
  """
611
611
  return False
612
612
 
613
- def render(self, size: tuple[int, int], focus: bool = False):
613
+ def render(self, size: tuple[int, int], focus: bool = False) -> SolidCanvas | CompositeCanvas:
614
614
  """
615
615
  Render GraphVScale.
616
616
  """
@@ -641,7 +641,7 @@ class GraphVScale(Widget):
641
641
  return c
642
642
 
643
643
 
644
- def scale_bar_values(bar, top, maxrow: int):
644
+ def scale_bar_values(bar, top: float, maxrow: int) -> list[int]:
645
645
  """
646
646
  Return a list of bar values aliased to integer values of maxrow.
647
647
  """
@@ -8,22 +8,21 @@ from urwid.canvas import CompositeCanvas
8
8
  from .constants import Sizing
9
9
  from .widget_decoration import WidgetDecoration, WidgetError
10
10
 
11
- if typing.TYPE_CHECKING:
12
- from .widget import Widget
11
+ WrappedWidget = typing.TypeVar("WrappedWidget")
13
12
 
14
13
 
15
14
  class BoxAdapterError(WidgetError):
16
15
  pass
17
16
 
18
17
 
19
- class BoxAdapter(WidgetDecoration):
18
+ class BoxAdapter(WidgetDecoration[WrappedWidget]):
20
19
  """
21
20
  Adapter for using a box widget where a flow widget would usually go
22
21
  """
23
22
 
24
23
  no_cache: typing.ClassVar[list[str]] = ["rows"]
25
24
 
26
- def __init__(self, box_widget, height):
25
+ def __init__(self, box_widget: WrappedWidget, height: int) -> None:
27
26
  """
28
27
  Create a flow widget that contains a box widget
29
28
 
@@ -47,7 +46,7 @@ class BoxAdapter(WidgetDecoration):
47
46
 
48
47
  # originally stored as box_widget, keep for compatibility
49
48
  @property
50
- def box_widget(self) -> Widget:
49
+ def box_widget(self) -> WrappedWidget:
51
50
  warnings.warn(
52
51
  "original stored as original_widget, keep for compatibility",
53
52
  PendingDeprecationWarning,
@@ -56,7 +55,7 @@ class BoxAdapter(WidgetDecoration):
56
55
  return self.original_widget
57
56
 
58
57
  @box_widget.setter
59
- def box_widget(self, widget: Widget):
58
+ def box_widget(self, widget: WrappedWidget) -> None:
60
59
  warnings.warn(
61
60
  "original stored as original_widget, keep for compatibility",
62
61
  PendingDeprecationWarning,
@@ -104,7 +103,7 @@ class BoxAdapter(WidgetDecoration):
104
103
  def mouse_event(
105
104
  self,
106
105
  size: tuple[int],
107
- event,
106
+ event: str,
108
107
  button: int,
109
108
  col: int,
110
109
  row: int,
urwid/widget/columns.py CHANGED
@@ -6,6 +6,7 @@ from itertools import chain, repeat
6
6
 
7
7
  import urwid
8
8
  from urwid.canvas import Canvas, CanvasJoin, CompositeCanvas, SolidCanvas
9
+ from urwid.command_map import Command
9
10
  from urwid.monitored_list import MonitoredFocusList, MonitoredList
10
11
  from urwid.util import is_mouse_press
11
12
 
@@ -795,13 +796,16 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
795
796
  else:
796
797
  w_h_args[i] = (0,)
797
798
 
798
- elif Sizing.FIXED in w_sizing and (Sizing.FLOW in w_sizing or is_box):
799
- width, height = widget.pack((), focused)
799
+ elif Sizing.FLOW in w_sizing or is_box:
800
+ if Sizing.FIXED in w_sizing:
801
+ width, height = widget.pack((), focused)
802
+ else:
803
+ width = self.min_width
804
+
800
805
  weighted.setdefault(size_weight, []).append((widget, i, is_box, focused))
801
806
  weights.append(size_weight)
802
807
  weight_max_sizes.setdefault(size_weight, width)
803
808
  weight_max_sizes[size_weight] = max(weight_max_sizes[size_weight], width)
804
-
805
809
  else:
806
810
  raise ColumnsError(f"Unsupported combination of {size_kind} box={is_box!r} for {widget}")
807
811
 
@@ -819,6 +823,9 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
819
823
  else:
820
824
  box.append(i)
821
825
 
826
+ if not heights:
827
+ raise ColumnsError(f"No height information for pack {self!r} as FIXED")
828
+
822
829
  max_height = max(heights.values())
823
830
  for idx in box:
824
831
  heights[idx] = max_height
@@ -1019,7 +1026,7 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
1019
1026
  def mouse_event(
1020
1027
  self,
1021
1028
  size: tuple[()] | tuple[int] | tuple[int, int],
1022
- event,
1029
+ event: str,
1023
1030
  button: int,
1024
1031
  col: int,
1025
1032
  row: int,
@@ -1115,15 +1122,15 @@ class Columns(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin):
1115
1122
 
1116
1123
  i = self.focus_position
1117
1124
  w, _ = self.contents[i]
1118
- if self._command_map[key] not in {"cursor up", "cursor down", "cursor page up", "cursor page down"}:
1125
+ if self._command_map[key] not in {Command.UP, Command.DOWN, Command.PAGE_UP, Command.PAGE_DOWN}:
1119
1126
  self.pref_col = None
1120
1127
  if w.selectable():
1121
1128
  key = w.keypress(size_args[i], key)
1122
1129
 
1123
- if self._command_map[key] not in {"cursor left", "cursor right"}:
1130
+ if self._command_map[key] not in {Command.LEFT, Command.RIGHT}:
1124
1131
  return key
1125
1132
 
1126
- if self._command_map[key] == "cursor left":
1133
+ if self._command_map[key] == Command.LEFT:
1127
1134
  candidates = list(range(i - 1, -1, -1)) # count backwards to 0
1128
1135
  else: # key == 'right'
1129
1136
  candidates = list(range(i + 1, len(self.contents)))
urwid/widget/divider.py CHANGED
@@ -69,7 +69,7 @@ class Divider(Widget):
69
69
  self.top = top
70
70
  self.bottom = bottom
71
71
 
72
- def _repr_words(self):
72
+ def _repr_words(self) -> list[str]:
73
73
  return super()._repr_words() + [repr(self.div_char)] * (self.div_char != " ")
74
74
 
75
75
  def _repr_attrs(self) -> dict[str, typing.Any]:
@@ -92,7 +92,7 @@ class Divider(Widget):
92
92
  (_maxcol,) = size
93
93
  return self.top + 1 + self.bottom
94
94
 
95
- def render(self, size: tuple[int], focus: bool = False):
95
+ def render(self, size: tuple[int], focus: bool = False) -> CompositeCanvas:
96
96
  """
97
97
  Render the divider as a canvas and return it.
98
98
 
urwid/widget/edit.py CHANGED
@@ -550,7 +550,7 @@ class Edit(Text):
550
550
  self._invalidate()
551
551
  return True
552
552
 
553
- def mouse_event(self, size: tuple[int], event, button: int, x: int, y: int, focus: bool) -> bool | None:
553
+ def mouse_event(self, size: tuple[int], event: str, button: int, x: int, y: int, focus: bool) -> bool | None:
554
554
  """
555
555
  Move the cursor to the location clicked for button 1.
556
556
 
urwid/widget/filler.py CHANGED
@@ -22,17 +22,18 @@ from .widget_decoration import WidgetDecoration, WidgetError
22
22
  if typing.TYPE_CHECKING:
23
23
  from typing_extensions import Literal
24
24
 
25
- from .widget import Widget
25
+
26
+ WrappedWidget = typing.TypeVar("WrappedWidget")
26
27
 
27
28
 
28
29
  class FillerError(WidgetError):
29
30
  pass
30
31
 
31
32
 
32
- class Filler(WidgetDecoration):
33
+ class Filler(WidgetDecoration[WrappedWidget]):
33
34
  def __init__(
34
35
  self,
35
- body: Widget,
36
+ body: WrappedWidget,
36
37
  valign: (
37
38
  Literal["top", "middle", "bottom"] | VAlign | tuple[Literal["relative", WHSettings.RELATIVE], int]
38
39
  ) = VAlign.MIDDLE,
@@ -159,7 +160,7 @@ class Filler(WidgetDecoration):
159
160
  return remove_defaults(attrs, Filler.__init__)
160
161
 
161
162
  @property
162
- def body(self):
163
+ def body(self) -> WrappedWidget:
163
164
  """backwards compatibility, widget used to be stored as body"""
164
165
  warnings.warn(
165
166
  "backwards compatibility, widget used to be stored as body",
@@ -169,7 +170,7 @@ class Filler(WidgetDecoration):
169
170
  return self.original_widget
170
171
 
171
172
  @body.setter
172
- def body(self, new_body):
173
+ def body(self, new_body: WrappedWidget) -> None:
173
174
  warnings.warn(
174
175
  "backwards compatibility, widget used to be stored as body",
175
176
  PendingDeprecationWarning,
@@ -177,7 +178,7 @@ class Filler(WidgetDecoration):
177
178
  )
178
179
  self.original_widget = new_body
179
180
 
180
- def get_body(self):
181
+ def get_body(self) -> WrappedWidget:
181
182
  """backwards compatibility, widget used to be stored as body"""
182
183
  warnings.warn(
183
184
  "backwards compatibility, widget used to be stored as body",
@@ -186,7 +187,7 @@ class Filler(WidgetDecoration):
186
187
  )
187
188
  return self.original_widget
188
189
 
189
- def set_body(self, new_body):
190
+ def set_body(self, new_body: WrappedWidget) -> None:
190
191
  warnings.warn(
191
192
  "backwards compatibility, widget used to be stored as body",
192
193
  DeprecationWarning,
urwid/widget/frame.py CHANGED
@@ -448,7 +448,15 @@ class Frame(Widget, WidgetContainerMixin):
448
448
  return key
449
449
  return self.body.keypress((maxcol, remaining), key)
450
450
 
451
- def mouse_event(self, size: tuple[int, int], event, button: int, col: int, row: int, focus: bool) -> bool | None:
451
+ def mouse_event(
452
+ self,
453
+ size: tuple[int, int],
454
+ event: str,
455
+ button: int,
456
+ col: int,
457
+ row: int,
458
+ focus: bool,
459
+ ) -> bool | None:
452
460
  """
453
461
  Pass mouse event to appropriate part of frame.
454
462
  Focus may be changed on button 1 press.