urwid 2.6.15__py3-none-any.whl → 3.0.0__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.

Potentially problematic release.


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

Files changed (54) hide show
  1. urwid/__init__.py +1 -4
  2. urwid/canvas.py +27 -46
  3. urwid/command_map.py +6 -4
  4. urwid/container.py +1 -1
  5. urwid/decoration.py +1 -1
  6. urwid/display/_posix_raw_display.py +16 -4
  7. urwid/display/_raw_display_base.py +8 -5
  8. urwid/display/_win32_raw_display.py +16 -17
  9. urwid/display/common.py +26 -55
  10. urwid/display/curses.py +1 -1
  11. urwid/display/escape.py +15 -12
  12. urwid/display/lcd.py +4 -6
  13. urwid/display/web.py +7 -12
  14. urwid/event_loop/asyncio_loop.py +1 -2
  15. urwid/event_loop/main_loop.py +13 -18
  16. urwid/event_loop/tornado_loop.py +4 -5
  17. urwid/event_loop/trio_loop.py +1 -1
  18. urwid/font.py +13 -18
  19. urwid/signals.py +2 -1
  20. urwid/str_util.py +15 -18
  21. urwid/text_layout.py +6 -7
  22. urwid/util.py +7 -18
  23. urwid/version.py +9 -4
  24. urwid/vterm.py +18 -45
  25. urwid/widget/__init__.py +0 -6
  26. urwid/widget/attr_wrap.py +8 -10
  27. urwid/widget/bar_graph.py +3 -8
  28. urwid/widget/big_text.py +9 -7
  29. urwid/widget/box_adapter.py +4 -4
  30. urwid/widget/columns.py +52 -83
  31. urwid/widget/container.py +29 -75
  32. urwid/widget/edit.py +8 -8
  33. urwid/widget/filler.py +6 -6
  34. urwid/widget/frame.py +28 -37
  35. urwid/widget/grid_flow.py +25 -110
  36. urwid/widget/line_box.py +13 -0
  37. urwid/widget/listbox.py +12 -50
  38. urwid/widget/monitored_list.py +6 -4
  39. urwid/widget/overlay.py +4 -37
  40. urwid/widget/padding.py +11 -48
  41. urwid/widget/pile.py +179 -158
  42. urwid/widget/popup.py +2 -2
  43. urwid/widget/progress_bar.py +10 -11
  44. urwid/widget/scrollable.py +25 -33
  45. urwid/widget/treetools.py +27 -48
  46. urwid/widget/widget.py +7 -124
  47. urwid/widget/widget_decoration.py +4 -33
  48. urwid/wimp.py +1 -1
  49. {urwid-2.6.15.dist-info → urwid-3.0.0.dist-info}/METADATA +18 -18
  50. urwid-3.0.0.dist-info/RECORD +74 -0
  51. {urwid-2.6.15.dist-info → urwid-3.0.0.dist-info}/WHEEL +1 -1
  52. urwid-2.6.15.dist-info/RECORD +0 -74
  53. {urwid-2.6.15.dist-info → urwid-3.0.0.dist-info/licenses}/COPYING +0 -0
  54. {urwid-2.6.15.dist-info → urwid-3.0.0.dist-info}/top_level.txt +0 -0
urwid/widget/filler.py CHANGED
@@ -162,8 +162,8 @@ class Filler(WidgetDecoration[WrappedWidget]):
162
162
  def body(self) -> WrappedWidget:
163
163
  """backwards compatibility, widget used to be stored as body"""
164
164
  warnings.warn(
165
- "backwards compatibility, widget used to be stored as body",
166
- PendingDeprecationWarning,
165
+ "backwards compatibility, widget used to be stored as body. API will be removed in version 5.0.",
166
+ DeprecationWarning,
167
167
  stacklevel=2,
168
168
  )
169
169
  return self.original_widget
@@ -171,8 +171,8 @@ class Filler(WidgetDecoration[WrappedWidget]):
171
171
  @body.setter
172
172
  def body(self, new_body: WrappedWidget) -> None:
173
173
  warnings.warn(
174
- "backwards compatibility, widget used to be stored as body",
175
- PendingDeprecationWarning,
174
+ "backwards compatibility, widget used to be stored as body. API will be removed in version 5.0.",
175
+ DeprecationWarning,
176
176
  stacklevel=2,
177
177
  )
178
178
  self.original_widget = new_body
@@ -180,7 +180,7 @@ class Filler(WidgetDecoration[WrappedWidget]):
180
180
  def get_body(self) -> WrappedWidget:
181
181
  """backwards compatibility, widget used to be stored as body"""
182
182
  warnings.warn(
183
- "backwards compatibility, widget used to be stored as body",
183
+ "backwards compatibility, widget used to be stored as body. API will be removed in version 4.0.",
184
184
  DeprecationWarning,
185
185
  stacklevel=2,
186
186
  )
@@ -188,7 +188,7 @@ class Filler(WidgetDecoration[WrappedWidget]):
188
188
 
189
189
  def set_body(self, new_body: WrappedWidget) -> None:
190
190
  warnings.warn(
191
- "backwards compatibility, widget used to be stored as body",
191
+ "backwards compatibility, widget used to be stored as body. API will be removed in version 4.0.",
192
192
  DeprecationWarning,
193
193
  stacklevel=2,
194
194
  )
urwid/widget/frame.py CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import typing
4
4
  import warnings
5
+ from collections.abc import MutableMapping
5
6
 
6
7
  from urwid.canvas import CanvasCombine, CompositeCanvas
7
8
  from urwid.split_repr import remove_defaults
@@ -13,7 +14,7 @@ from .filler import Filler
13
14
  from .widget import Widget, WidgetError
14
15
 
15
16
  if typing.TYPE_CHECKING:
16
- from collections.abc import Iterator, MutableMapping
17
+ from collections.abc import Iterator
17
18
 
18
19
  from typing_extensions import Literal
19
20
 
@@ -121,8 +122,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
121
122
  def get_header(self) -> HeaderWidget:
122
123
  warnings.warn(
123
124
  f"method `{self.__class__.__name__}.get_header` is deprecated, "
124
- f"standard property `{self.__class__.__name__}.header` should be used instead",
125
- PendingDeprecationWarning,
125
+ f"standard property `{self.__class__.__name__}.header` should be used instead."
126
+ "API will be removed in version 5.0.",
127
+ DeprecationWarning,
126
128
  stacklevel=2,
127
129
  )
128
130
  return self.header
@@ -130,8 +132,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
130
132
  def set_header(self, header: HeaderWidget) -> None:
131
133
  warnings.warn(
132
134
  f"method `{self.__class__.__name__}.set_header` is deprecated, "
133
- f"standard property `{self.__class__.__name__}.header` should be used instead",
134
- PendingDeprecationWarning,
135
+ f"standard property `{self.__class__.__name__}.header` should be used instead."
136
+ "API will be removed in version 5.0.",
137
+ DeprecationWarning,
135
138
  stacklevel=2,
136
139
  )
137
140
  self.header = header
@@ -149,8 +152,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
149
152
  def get_body(self) -> BodyWidget:
150
153
  warnings.warn(
151
154
  f"method `{self.__class__.__name__}.get_body` is deprecated, "
152
- f"standard property {self.__class__.__name__}.body should be used instead",
153
- PendingDeprecationWarning,
155
+ f"standard property {self.__class__.__name__}.body should be used instead."
156
+ "API will be removed in version 5.0.",
157
+ DeprecationWarning,
154
158
  stacklevel=2,
155
159
  )
156
160
  return self.body
@@ -158,8 +162,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
158
162
  def set_body(self, body: BodyWidget) -> None:
159
163
  warnings.warn(
160
164
  f"method `{self.__class__.__name__}.set_body` is deprecated, "
161
- f"standard property `{self.__class__.__name__}.body` should be used instead",
162
- PendingDeprecationWarning,
165
+ f"standard property `{self.__class__.__name__}.body` should be used instead."
166
+ "API will be removed in version 5.0.",
167
+ DeprecationWarning,
163
168
  stacklevel=2,
164
169
  )
165
170
  self.body = body
@@ -179,8 +184,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
179
184
  def get_footer(self) -> FooterWidget:
180
185
  warnings.warn(
181
186
  f"method `{self.__class__.__name__}.get_footer` is deprecated, "
182
- f"standard property `{self.__class__.__name__}.footer` should be used instead",
183
- PendingDeprecationWarning,
187
+ f"standard property `{self.__class__.__name__}.footer` should be used instead."
188
+ "API will be removed in version 5.0.",
189
+ DeprecationWarning,
184
190
  stacklevel=2,
185
191
  )
186
192
  return self.footer
@@ -188,8 +194,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
188
194
  def set_footer(self, footer: FooterWidget) -> None:
189
195
  warnings.warn(
190
196
  f"method `{self.__class__.__name__}.set_footer` is deprecated, "
191
- f"standard property `{self.__class__.__name__}.footer` should be used instead",
192
- PendingDeprecationWarning,
197
+ f"standard property `{self.__class__.__name__}.footer` should be used instead."
198
+ "API will be removed in version 5.0.",
199
+ DeprecationWarning,
193
200
  stacklevel=2,
194
201
  )
195
202
  self.footer = footer
@@ -233,8 +240,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
233
240
  """
234
241
  warnings.warn(
235
242
  "included for backwards compatibility."
236
- "You should rather use the container property `.focus_position` to get this value.",
237
- PendingDeprecationWarning,
243
+ "You should rather use the container property `.focus_position` to get this value."
244
+ "API will be removed in version 5.0.",
245
+ DeprecationWarning,
238
246
  stacklevel=2,
239
247
  )
240
248
  return self.focus_position
@@ -242,8 +250,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
242
250
  def set_focus(self, part: Literal["header", "footer", "body"]) -> None:
243
251
  warnings.warn(
244
252
  "included for backwards compatibility."
245
- "You should rather use the container property `.focus_position` to set this value.",
246
- PendingDeprecationWarning,
253
+ "You should rather use the container property `.focus_position` to set this value."
254
+ "API will be removed in version 5.0.",
255
+ DeprecationWarning,
247
256
  stacklevel=2,
248
257
  )
249
258
  self.focus_position = part
@@ -255,15 +264,6 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
255
264
  This is a read-only property."""
256
265
  return {"header": self._header, "footer": self._footer, "body": self._body}[self.focus_part]
257
266
 
258
- def _get_focus(self) -> BodyWidget | HeaderWidget | FooterWidget:
259
- warnings.warn(
260
- f"method `{self.__class__.__name__}._get_focus` is deprecated, "
261
- f"please use `{self.__class__.__name__}.focus` property",
262
- DeprecationWarning,
263
- stacklevel=3,
264
- )
265
- return {"header": self._header, "footer": self._footer, "body": self._body}[self.focus_part]
266
-
267
267
  @property
268
268
  def contents(
269
269
  self,
@@ -294,9 +294,9 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
294
294
 
295
295
  # noinspection PyMethodParameters
296
296
  class FrameContents(
297
- typing.MutableMapping[
297
+ MutableMapping[
298
298
  str,
299
- typing.Tuple[typing.Union[BodyWidget, HeaderWidget, FooterWidget], None],
299
+ tuple[typing.Union[BodyWidget, HeaderWidget, FooterWidget], None],
300
300
  ]
301
301
  ):
302
302
  # pylint: disable=no-self-argument
@@ -388,15 +388,6 @@ class Frame(Widget, WidgetContainerMixin, typing.Generic[BodyWidget, HeaderWidge
388
388
  else:
389
389
  self.footer = None
390
390
 
391
- def _contents(self):
392
- warnings.warn(
393
- f"method `{self.__class__.__name__}._contents` is deprecated, "
394
- f"please use property `{self.__class__.__name__}.contents`",
395
- DeprecationWarning,
396
- stacklevel=3,
397
- )
398
- return self.contents
399
-
400
391
  def options(self) -> None:
401
392
  """
402
393
  There are currently no options for Frame contents.
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
@@ -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)
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
@@ -1938,8 +1901,7 @@ class ListBox(Widget, WidgetContainerMixin):
1938
1901
  )
1939
1902
  return False
1940
1903
 
1941
- handled = w.mouse_event((maxcol,), event, button, col, row - wrow, focus)
1942
- if handled:
1904
+ if w.mouse_event((maxcol,), event, button, col, row - wrow, focus):
1943
1905
  return True
1944
1906
 
1945
1907
  if is_mouse_press(event):
@@ -1995,8 +1957,8 @@ class ListBox(Widget, WidgetContainerMixin):
1995
1957
  the focus up to the top. This is the best we can do with
1996
1958
  a minimal list walker implementation.
1997
1959
  """
1998
- positions_fn = getattr(self._body, "positions", None)
1999
- if positions_fn:
1960
+
1961
+ if positions_fn := getattr(self._body, "positions", None):
2000
1962
  yield from positions_fn()
2001
1963
  return
2002
1964
 
@@ -2026,8 +1988,8 @@ class ListBox(Widget, WidgetContainerMixin):
2026
1988
  reverse of what `__iter__()` produces, but this is the best we can
2027
1989
  do with a minimal list walker implementation.
2028
1990
  """
2029
- positions_fn = getattr(self._body, "positions", None)
2030
- if positions_fn:
1991
+
1992
+ if positions_fn := getattr(self._body, "positions", None):
2031
1993
  yield from positions_fn(reverse=True)
2032
1994
  return
2033
1995
 
@@ -37,7 +37,7 @@ _T = typing.TypeVar("_T")
37
37
 
38
38
 
39
39
  def _call_modified(
40
- fn: Callable[Concatenate[MonitoredList, ArgSpec], Ret]
40
+ fn: Callable[Concatenate[MonitoredList, ArgSpec], Ret],
41
41
  ) -> Callable[Concatenate[MonitoredList, ArgSpec], Ret]:
42
42
  @functools.wraps(fn)
43
43
  def call_modified_wrapper(self: MonitoredList, *args: ArgSpec.args, **kwargs: ArgSpec.kwargs) -> Ret:
@@ -48,7 +48,7 @@ def _call_modified(
48
48
  return call_modified_wrapper
49
49
 
50
50
 
51
- class MonitoredList(typing.List[_T], typing.Generic[_T]):
51
+ class MonitoredList(list[_T], typing.Generic[_T]):
52
52
  """
53
53
  This class can trigger a callback any time its contents are changed
54
54
  with the usual list operations append, extend, etc.
@@ -245,7 +245,8 @@ class MonitoredFocusList(MonitoredList[_T], typing.Generic[_T]):
245
245
  def _get_focus(self) -> int | None:
246
246
  warnings.warn(
247
247
  f"method `{self.__class__.__name__}._get_focus` is deprecated, "
248
- f"please use `{self.__class__.__name__}.focus` property",
248
+ f"please use `{self.__class__.__name__}.focus` property."
249
+ "API will be removed in version 4.0.",
249
250
  DeprecationWarning,
250
251
  stacklevel=3,
251
252
  )
@@ -254,7 +255,8 @@ class MonitoredFocusList(MonitoredList[_T], typing.Generic[_T]):
254
255
  def _set_focus(self, index: int) -> None:
255
256
  warnings.warn(
256
257
  f"method `{self.__class__.__name__}._set_focus` is deprecated, "
257
- f"please use `{self.__class__.__name__}.focus` property",
258
+ f"please use `{self.__class__.__name__}.focus` property."
259
+ "API will be removed in version 4.0.",
258
260
  DeprecationWarning,
259
261
  stacklevel=3,
260
262
  )
urwid/widget/overlay.py CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import typing
4
4
  import warnings
5
+ from collections.abc import MutableSequence
5
6
 
6
7
  from urwid.canvas import CanvasOverlay, CompositeCanvas
7
8
  from urwid.split_repr import remove_defaults
@@ -28,7 +29,7 @@ from .padding import calculate_left_right_padding
28
29
  from .widget import Widget, WidgetError, WidgetWarning
29
30
 
30
31
  if typing.TYPE_CHECKING:
31
- from collections.abc import Iterator, MutableSequence, Sequence
32
+ from collections.abc import Iterator, Sequence
32
33
 
33
34
  from typing_extensions import Literal
34
35
 
@@ -582,15 +583,6 @@ class Overlay(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin, ty
582
583
  """
583
584
  return self.top_w
584
585
 
585
- def _get_focus(self) -> TopWidget:
586
- warnings.warn(
587
- f"method `{self.__class__.__name__}._get_focus` is deprecated, "
588
- f"please use `{self.__class__.__name__}.focus` property",
589
- DeprecationWarning,
590
- stacklevel=3,
591
- )
592
- return self.top_w
593
-
594
586
  @property
595
587
  def focus_position(self) -> Literal[1]:
596
588
  """
@@ -608,30 +600,6 @@ class Overlay(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin, ty
608
600
  if position != 1:
609
601
  raise IndexError(f"Overlay widget focus_position currently must always be set to 1, not {position}")
610
602
 
611
- def _get_focus_position(self) -> int | None:
612
- warnings.warn(
613
- f"method `{self.__class__.__name__}._get_focus_position` is deprecated, "
614
- f"please use `{self.__class__.__name__}.focus_position` property",
615
- DeprecationWarning,
616
- stacklevel=3,
617
- )
618
- return 1
619
-
620
- def _set_focus_position(self, position: int) -> None:
621
- """
622
- Set the widget in focus.
623
-
624
- position -- index of child widget to be made focus
625
- """
626
- warnings.warn(
627
- f"method `{self.__class__.__name__}._set_focus_position` is deprecated, "
628
- f"please use `{self.__class__.__name__}.focus_position` property",
629
- DeprecationWarning,
630
- stacklevel=3,
631
- )
632
- if position != 1:
633
- raise IndexError(f"Overlay widget focus_position currently must always be set to 1, not {position}")
634
-
635
603
  @property
636
604
  def contents(self) -> MutableSequence[tuple[TopWidget | BottomWidget, OverlayOptions]]:
637
605
  """
@@ -658,14 +626,13 @@ class Overlay(Widget, WidgetContainerMixin, WidgetContainerListContentsMixin, ty
658
626
 
659
627
  # noinspection PyMethodParameters
660
628
  class OverlayContents(
661
- typing.MutableSequence[
662
- typing.Tuple[
629
+ MutableSequence[
630
+ tuple[
663
631
  typing.Union[TopWidget, BottomWidget],
664
632
  OverlayOptions,
665
633
  ]
666
634
  ]
667
635
  ):
668
-
669
636
  # pylint: disable=no-self-argument
670
637
  def __len__(inner_self) -> int:
671
638
  return 2