urwid 2.6.15__py3-none-any.whl → 3.0.5__py3-none-any.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.
Files changed (62) hide show
  1. urwid/__init__.py +30 -20
  2. urwid/canvas.py +34 -53
  3. urwid/command_map.py +6 -4
  4. urwid/container.py +1 -1
  5. urwid/decoration.py +1 -1
  6. urwid/display/__init__.py +53 -48
  7. urwid/display/_posix_raw_display.py +20 -8
  8. urwid/display/_raw_display_base.py +21 -16
  9. urwid/display/_win32_raw_display.py +16 -17
  10. urwid/display/common.py +45 -74
  11. urwid/display/curses.py +3 -5
  12. urwid/display/escape.py +28 -13
  13. urwid/display/lcd.py +8 -10
  14. urwid/display/web.py +11 -16
  15. urwid/event_loop/asyncio_loop.py +35 -15
  16. urwid/event_loop/main_loop.py +18 -23
  17. urwid/event_loop/tornado_loop.py +4 -5
  18. urwid/event_loop/trio_loop.py +1 -1
  19. urwid/font.py +19 -22
  20. urwid/numedit.py +65 -65
  21. urwid/signals.py +19 -27
  22. urwid/split_repr.py +9 -3
  23. urwid/str_util.py +105 -60
  24. urwid/text_layout.py +14 -13
  25. urwid/util.py +8 -19
  26. urwid/version.py +22 -4
  27. urwid/vterm.py +20 -47
  28. urwid/widget/__init__.py +0 -6
  29. urwid/widget/attr_map.py +10 -10
  30. urwid/widget/attr_wrap.py +11 -13
  31. urwid/widget/bar_graph.py +3 -8
  32. urwid/widget/big_text.py +8 -9
  33. urwid/widget/box_adapter.py +6 -6
  34. urwid/widget/columns.py +52 -83
  35. urwid/widget/container.py +29 -75
  36. urwid/widget/divider.py +6 -6
  37. urwid/widget/edit.py +50 -50
  38. urwid/widget/filler.py +14 -14
  39. urwid/widget/frame.py +31 -40
  40. urwid/widget/grid_flow.py +25 -110
  41. urwid/widget/line_box.py +31 -18
  42. urwid/widget/listbox.py +16 -51
  43. urwid/widget/monitored_list.py +75 -49
  44. urwid/widget/overlay.py +4 -37
  45. urwid/widget/padding.py +31 -68
  46. urwid/widget/pile.py +179 -158
  47. urwid/widget/popup.py +2 -2
  48. urwid/widget/progress_bar.py +17 -18
  49. urwid/widget/scrollable.py +26 -34
  50. urwid/widget/solid_fill.py +3 -3
  51. urwid/widget/text.py +44 -30
  52. urwid/widget/treetools.py +27 -48
  53. urwid/widget/widget.py +13 -130
  54. urwid/widget/widget_decoration.py +6 -35
  55. urwid/widget/wimp.py +61 -61
  56. urwid/wimp.py +1 -1
  57. {urwid-2.6.15.dist-info → urwid-3.0.5.dist-info}/METADATA +24 -24
  58. urwid-3.0.5.dist-info/RECORD +74 -0
  59. {urwid-2.6.15.dist-info → urwid-3.0.5.dist-info}/WHEEL +1 -1
  60. urwid-2.6.15.dist-info/RECORD +0 -74
  61. {urwid-2.6.15.dist-info → urwid-3.0.5.dist-info/licenses}/COPYING +0 -0
  62. {urwid-2.6.15.dist-info → urwid-3.0.5.dist-info}/top_level.txt +0 -0
urwid/widget/grid_flow.py CHANGED
@@ -144,8 +144,9 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
144
144
  """
145
145
  warnings.warn(
146
146
  "only for backwards compatibility."
147
- "You should use the new standard container property `contents` to modify GridFlow",
148
- PendingDeprecationWarning,
147
+ "You should use the new standard container property `contents` to modify GridFlow."
148
+ "API will be removed in version 5.0.",
149
+ DeprecationWarning,
149
150
  stacklevel=2,
150
151
  )
151
152
  ml = MonitoredList(w for w, t in self.contents)
@@ -160,33 +161,16 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
160
161
  def cells(self, widgets: Sequence[Widget]):
161
162
  warnings.warn(
162
163
  "only for backwards compatibility."
163
- "You should use the new standard container property `contents` to modify GridFlow",
164
- PendingDeprecationWarning,
164
+ "You should use the new standard container property `contents` to modify GridFlow."
165
+ "API will be removed in version 5.0.",
166
+ DeprecationWarning,
165
167
  stacklevel=2,
166
168
  )
167
169
  focus_position = self.focus_position
168
170
  self.contents = [(new, (WHSettings.GIVEN, self._cell_width)) for new in widgets]
169
- if focus_position < len(widgets): # pylint: disable=consider-using-max-builtin # pylint bug
171
+ if focus_position < len(widgets):
170
172
  self.focus_position = focus_position
171
173
 
172
- def _get_cells(self):
173
- warnings.warn(
174
- "only for backwards compatibility."
175
- "You should use the new standard container property `contents` to modify GridFlow",
176
- DeprecationWarning,
177
- stacklevel=3,
178
- )
179
- return self.cells
180
-
181
- def _set_cells(self, widgets: Sequence[Widget]):
182
- warnings.warn(
183
- "only for backwards compatibility."
184
- "You should use the new standard container property `contents` to modify GridFlow",
185
- DeprecationWarning,
186
- stacklevel=3,
187
- )
188
- self.cells = widgets
189
-
190
174
  @property
191
175
  def cell_width(self) -> int:
192
176
  """
@@ -202,24 +186,6 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
202
186
  self.focus_position = focus_position
203
187
  self._cell_width = width
204
188
 
205
- def _get_cell_width(self) -> int:
206
- warnings.warn(
207
- f"Method `{self.__class__.__name__}._get_cell_width` is deprecated, "
208
- f"please use property `{self.__class__.__name__}.cell_width`",
209
- DeprecationWarning,
210
- stacklevel=3,
211
- )
212
- return self.cell_width
213
-
214
- def _set_cell_width(self, width: int) -> None:
215
- warnings.warn(
216
- f"Method `{self.__class__.__name__}._set_cell_width` is deprecated, "
217
- f"please use property `{self.__class__.__name__}.cell_width`",
218
- DeprecationWarning,
219
- stacklevel=3,
220
- )
221
- self.cell_width = width
222
-
223
189
  @property
224
190
  def contents(self) -> MonitoredFocusList[tuple[Widget, tuple[Literal[WHSettings.GIVEN], int]]]:
225
191
  """
@@ -270,8 +236,9 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
270
236
  """
271
237
  warnings.warn(
272
238
  "only for backwards compatibility."
273
- "You may also use the new standard container property `focus_position` to set the focus.",
274
- PendingDeprecationWarning,
239
+ "You may also use the new standard container property `focus_position` to set the focus."
240
+ "API will be removed in version 5.0.",
241
+ DeprecationWarning,
275
242
  stacklevel=2,
276
243
  )
277
244
  if isinstance(cell, int):
@@ -298,17 +265,6 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
298
265
  return None
299
266
  return self.contents[self.focus_position][0]
300
267
 
301
- def _get_focus(self) -> Widget | None:
302
- warnings.warn(
303
- f"method `{self.__class__.__name__}._get_focus` is deprecated, "
304
- f"please use `{self.__class__.__name__}.focus` property",
305
- DeprecationWarning,
306
- stacklevel=3,
307
- )
308
- if not self.contents:
309
- return None
310
- return self.contents[self.focus_position][0]
311
-
312
268
  def get_focus(self):
313
269
  """
314
270
  Return the widget in focus, for backwards compatibility.
@@ -318,8 +274,9 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
318
274
  """
319
275
  warnings.warn(
320
276
  "only for backwards compatibility."
321
- "You may also use the new standard container property `focus` to get the focus.",
322
- PendingDeprecationWarning,
277
+ "You may also use the new standard container property `focus` to get the focus."
278
+ "API will be removed in version 5.0.",
279
+ DeprecationWarning,
323
280
  stacklevel=2,
324
281
  )
325
282
  if not self.contents:
@@ -331,8 +288,9 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
331
288
  warnings.warn(
332
289
  "only for backwards compatibility."
333
290
  "You may also use the new standard container property"
334
- "`focus` to get the focus and `focus_position` to get/set the cell in focus by index",
335
- PendingDeprecationWarning,
291
+ "`focus` to get the focus and `focus_position` to get/set the cell in focus by index."
292
+ "API will be removed in version 5.0.",
293
+ DeprecationWarning,
336
294
  stacklevel=2,
337
295
  )
338
296
  return self.focus
@@ -342,23 +300,10 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
342
300
  warnings.warn(
343
301
  "only for backwards compatibility."
344
302
  "You may also use the new standard container property"
345
- "`focus` to get the focus and `focus_position` to get/set the cell in focus by index",
346
- PendingDeprecationWarning,
347
- stacklevel=2,
348
- )
349
- for i, (w, _options) in enumerate(self.contents):
350
- if cell == w:
351
- self.focus_position = i
352
- return
353
- raise ValueError(f"Widget not found in GridFlow contents: {cell!r}")
354
-
355
- def _set_focus_cell(self, cell: Widget) -> None:
356
- warnings.warn(
357
- "only for backwards compatibility."
358
- "You may also use the new standard container property"
359
- "`focus` to get the focus and `focus_position` to get/set the cell in focus by index",
303
+ "`focus` to get the focus and `focus_position` to get/set the cell in focus by index."
304
+ "API will be removed in version 5.0.",
360
305
  DeprecationWarning,
361
- stacklevel=3,
306
+ stacklevel=2,
362
307
  )
363
308
  for i, (w, _options) in enumerate(self.contents):
364
309
  if cell == w:
@@ -392,38 +337,6 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
392
337
  ) from exc
393
338
  self.contents.focus = position
394
339
 
395
- def _get_focus_position(self) -> int | None:
396
- warnings.warn(
397
- f"method `{self.__class__.__name__}._get_focus_position` is deprecated, "
398
- f"please use `{self.__class__.__name__}.focus_position` property",
399
- DeprecationWarning,
400
- stacklevel=3,
401
- )
402
- if not self.contents:
403
- raise IndexError("No focus_position, GridFlow is empty")
404
- return self.contents.focus
405
-
406
- def _set_focus_position(self, position: int) -> None:
407
- """
408
- Set the widget in focus.
409
-
410
- position -- index of child widget to be made focus
411
- """
412
- warnings.warn(
413
- f"method `{self.__class__.__name__}._set_focus_position` is deprecated, "
414
- f"please use `{self.__class__.__name__}.focus_position` property",
415
- DeprecationWarning,
416
- stacklevel=3,
417
- )
418
- try:
419
- if position < 0 or position >= len(self.contents):
420
- raise IndexError(f"No GridFlow child widget at position {position}")
421
- except TypeError as exc:
422
- raise IndexError(f"No GridFlow child widget at position {position}").with_traceback(
423
- exc.__traceback__
424
- ) from exc
425
- self.contents.focus = position
426
-
427
340
  def _get_maxcol(self, size: tuple[int] | tuple[()]) -> int:
428
341
  if size:
429
342
  (maxcol,) = size
@@ -540,10 +453,12 @@ class GridFlow(WidgetWrap[Pile], WidgetContainerMixin, WidgetContainerListConten
540
453
  Captures focus changes.
541
454
  """
542
455
  self.get_display_widget(size)
543
- key = super().keypress(size, key)
544
- if key is None:
545
- self._set_focus_from_display_widget()
546
- return key
456
+
457
+ if (key := super().keypress(size, key)) is not None:
458
+ return key
459
+
460
+ self._set_focus_from_display_widget()
461
+ return None
547
462
 
548
463
  def pack(
549
464
  self,
urwid/widget/line_box.py CHANGED
@@ -68,29 +68,29 @@ class LineBox(WidgetDecoration[WrappedWidget], delegate_to_widget_mixin("_wrappe
68
68
  │Some text│
69
69
  └─────────┘
70
70
  >>> print(
71
- ... LineBox(
72
- ... Text("Some text"),
73
- ... tlcorner=LineBox.Symbols.LIGHT.TOP_LEFT_ROUNDED,
74
- ... trcorner=LineBox.Symbols.LIGHT.TOP_RIGHT_ROUNDED,
75
- ... blcorner=LineBox.Symbols.LIGHT.BOTTOM_LEFT_ROUNDED,
76
- ... brcorner=LineBox.Symbols.LIGHT.BOTTOM_RIGHT_ROUNDED,
77
- ... ).render(())
71
+ ... LineBox(
72
+ ... Text("Some text"),
73
+ ... tlcorner=LineBox.Symbols.LIGHT.TOP_LEFT_ROUNDED,
74
+ ... trcorner=LineBox.Symbols.LIGHT.TOP_RIGHT_ROUNDED,
75
+ ... blcorner=LineBox.Symbols.LIGHT.BOTTOM_LEFT_ROUNDED,
76
+ ... brcorner=LineBox.Symbols.LIGHT.BOTTOM_RIGHT_ROUNDED,
77
+ ... ).render(())
78
78
  ... )
79
79
  ╭─────────╮
80
80
  │Some text│
81
81
  ╰─────────╯
82
82
  >>> print(
83
- ... LineBox(
84
- ... Text("Some text"),
85
- ... tline=LineBox.Symbols.HEAVY.HORIZONTAL,
86
- ... bline=LineBox.Symbols.HEAVY.HORIZONTAL,
87
- ... lline=LineBox.Symbols.HEAVY.VERTICAL,
88
- ... rline=LineBox.Symbols.HEAVY.VERTICAL,
89
- ... tlcorner=LineBox.Symbols.HEAVY.TOP_LEFT,
90
- ... trcorner=LineBox.Symbols.HEAVY.TOP_RIGHT,
91
- ... blcorner=LineBox.Symbols.HEAVY.BOTTOM_LEFT,
92
- ... brcorner=LineBox.Symbols.HEAVY.BOTTOM_RIGHT,
93
- ... ).render(())
83
+ ... LineBox(
84
+ ... Text("Some text"),
85
+ ... tline=LineBox.Symbols.HEAVY.HORIZONTAL,
86
+ ... bline=LineBox.Symbols.HEAVY.HORIZONTAL,
87
+ ... lline=LineBox.Symbols.HEAVY.VERTICAL,
88
+ ... rline=LineBox.Symbols.HEAVY.VERTICAL,
89
+ ... tlcorner=LineBox.Symbols.HEAVY.TOP_LEFT,
90
+ ... trcorner=LineBox.Symbols.HEAVY.TOP_RIGHT,
91
+ ... blcorner=LineBox.Symbols.HEAVY.BOTTOM_LEFT,
92
+ ... brcorner=LineBox.Symbols.HEAVY.BOTTOM_RIGHT,
93
+ ... ).render(())
94
94
  ... )
95
95
  ┏━━━━━━━━━┓
96
96
  ┃Some text┃
@@ -167,6 +167,19 @@ class LineBox(WidgetDecoration[WrappedWidget], delegate_to_widget_mixin("_wrappe
167
167
 
168
168
  super().__init__(original_widget)
169
169
 
170
+ @property
171
+ def original_widget(self) -> WrappedWidget:
172
+ return super().original_widget
173
+
174
+ @original_widget.setter
175
+ def original_widget(self, original_widget: WrappedWidget) -> None:
176
+ v_index = int(bool(self.tline_widget)) # we care only about top
177
+ h_index = 1 # constant
178
+ middle: Columns = typing.cast("Columns", self._wrapped_widget[v_index])
179
+ _old_widget, options = middle.contents[h_index]
180
+ middle.contents[h_index] = (original_widget, options)
181
+ WidgetDecoration.original_widget.fset(self, original_widget) # pylint: disable=no-member
182
+
170
183
  @property
171
184
  def _w(self) -> Pile:
172
185
  return self._wrapped_widget
urwid/widget/listbox.py CHANGED
@@ -26,8 +26,6 @@ import warnings
26
26
  from collections.abc import Iterable, Sized
27
27
  from contextlib import suppress
28
28
 
29
- from typing_extensions import Protocol, runtime_checkable
30
-
31
29
  from urwid import signals
32
30
  from urwid.canvas import CanvasCombine, SolidCanvas
33
31
 
@@ -65,8 +63,8 @@ class ListWalkerError(Exception):
65
63
  pass
66
64
 
67
65
 
68
- @runtime_checkable
69
- class ScrollSupportingBody(Protocol):
66
+ @typing.runtime_checkable
67
+ class ScrollSupportingBody(typing.Protocol):
70
68
  """Protocol for ListWalkers."""
71
69
 
72
70
  def get_focus(self) -> tuple[Widget, _K]: ...
@@ -78,8 +76,8 @@ class ScrollSupportingBody(Protocol):
78
76
  def get_prev(self, position: _K) -> tuple[Widget, _K] | tuple[None, None]: ...
79
77
 
80
78
 
81
- @runtime_checkable
82
- class EstimatedSized(Protocol):
79
+ @typing.runtime_checkable
80
+ class EstimatedSized(typing.Protocol):
83
81
  """Widget can estimate it's size.
84
82
 
85
83
  PEP 424 defines API for memory-efficiency.
@@ -166,15 +164,6 @@ class SimpleListWalker(MonitoredList[_T], ListWalker):
166
164
  """
167
165
  return self
168
166
 
169
- def _get_contents(self) -> Self:
170
- warnings.warn(
171
- f"Method `{self.__class__.__name__}._get_contents` is deprecated, "
172
- f"please use property`{self.__class__.__name__}.contents`",
173
- DeprecationWarning,
174
- stacklevel=3,
175
- )
176
- return self
177
-
178
167
  def _modified(self) -> None:
179
168
  if self.focus >= len(self):
180
169
  self.focus = max(0, len(self) - 1)
@@ -426,24 +415,6 @@ class ListBox(Widget, WidgetContainerMixin):
426
415
  self.render = nocache_widget_render_instance(self)
427
416
  self._invalidate()
428
417
 
429
- def _get_body(self):
430
- warnings.warn(
431
- f"Method `{self.__class__.__name__}._get_body` is deprecated, "
432
- f"please use property `{self.__class__.__name__}.body`",
433
- DeprecationWarning,
434
- stacklevel=3,
435
- )
436
- return self.body
437
-
438
- def _set_body(self, body):
439
- warnings.warn(
440
- f"Method `{self.__class__.__name__}._set_body` is deprecated, "
441
- f"please use property `{self.__class__.__name__}.body`",
442
- DeprecationWarning,
443
- stacklevel=3,
444
- )
445
- self.body = body
446
-
447
418
  @property
448
419
  def __len__(self) -> Callable[[], int]:
449
420
  if isinstance(self._body, Sized):
@@ -873,8 +844,9 @@ class ListBox(Widget, WidgetContainerMixin):
873
844
  warnings.warn(
874
845
  "only for backwards compatibility."
875
846
  "You may also use the new standard container property `focus` to get the focus "
876
- "and property `focus_position` to read these values.",
877
- PendingDeprecationWarning,
847
+ "and property `focus_position` to read these values."
848
+ "API will be removed in version 5.0.",
849
+ DeprecationWarning,
878
850
  stacklevel=2,
879
851
  )
880
852
  return self._body.get_focus()
@@ -888,15 +860,6 @@ class ListBox(Widget, WidgetContainerMixin):
888
860
  """
889
861
  return self._body.get_focus()[0]
890
862
 
891
- def _get_focus(self) -> Widget:
892
- warnings.warn(
893
- f"method `{self.__class__.__name__}._get_focus` is deprecated, "
894
- f"please use `{self.__class__.__name__}.focus` property",
895
- DeprecationWarning,
896
- stacklevel=3,
897
- )
898
- return self.focus
899
-
900
863
  def _get_focus_position(self):
901
864
  """
902
865
  Return the list walker position of the widget in focus. The type
@@ -1054,6 +1017,9 @@ class ListBox(Widget, WidgetContainerMixin):
1054
1017
  self._body.set_focus(focus_pos)
1055
1018
 
1056
1019
  middle, top, bottom = self.calculate_visible((maxcol, maxrow), focus)
1020
+ if middle is None:
1021
+ return None
1022
+
1057
1023
  focus_offset, _focus_widget, focus_pos, focus_rows, _cursor = middle # pylint: disable=unpacking-non-sequence
1058
1024
  _trim_top, fill_above = top # pylint: disable=unpacking-non-sequence
1059
1025
  _trim_bottom, fill_below = bottom # pylint: disable=unpacking-non-sequence
@@ -1231,7 +1197,7 @@ class ListBox(Widget, WidgetContainerMixin):
1231
1197
  # start from closest edge and move inwards
1232
1198
  (pref_col,) = cursor_coords
1233
1199
  if coming_from == "above":
1234
- attempt_rows = range(0, tgt_rows)
1200
+ attempt_rows = range(tgt_rows)
1235
1201
  else:
1236
1202
  if coming_from != "below":
1237
1203
  raise ValueError("must specify coming_from ('above' or 'below') if cursor row is not specified")
@@ -1938,8 +1904,7 @@ class ListBox(Widget, WidgetContainerMixin):
1938
1904
  )
1939
1905
  return False
1940
1906
 
1941
- handled = w.mouse_event((maxcol,), event, button, col, row - wrow, focus)
1942
- if handled:
1907
+ if w.mouse_event((maxcol,), event, button, col, row - wrow, focus):
1943
1908
  return True
1944
1909
 
1945
1910
  if is_mouse_press(event):
@@ -1995,8 +1960,8 @@ class ListBox(Widget, WidgetContainerMixin):
1995
1960
  the focus up to the top. This is the best we can do with
1996
1961
  a minimal list walker implementation.
1997
1962
  """
1998
- positions_fn = getattr(self._body, "positions", None)
1999
- if positions_fn:
1963
+
1964
+ if positions_fn := getattr(self._body, "positions", None):
2000
1965
  yield from positions_fn()
2001
1966
  return
2002
1967
 
@@ -2026,8 +1991,8 @@ class ListBox(Widget, WidgetContainerMixin):
2026
1991
  reverse of what `__iter__()` produces, but this is the best we can
2027
1992
  do with a minimal list walker implementation.
2028
1993
  """
2029
- positions_fn = getattr(self._body, "positions", None)
2030
- if positions_fn:
1994
+
1995
+ if positions_fn := getattr(self._body, "positions", None):
2031
1996
  yield from positions_fn(reverse=True)
2032
1997
  return
2033
1998