urwid 4.2.3__tar.gz → 4.2.4__tar.gz

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 (118) hide show
  1. {urwid-4.2.3/urwid.egg-info → urwid-4.2.4}/PKG-INFO +1 -1
  2. {urwid-4.2.3 → urwid-4.2.4}/urwid/version.py +3 -3
  3. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/listbox.py +8 -1
  4. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/text.py +22 -4
  5. {urwid-4.2.3 → urwid-4.2.4/urwid.egg-info}/PKG-INFO +1 -1
  6. urwid-4.2.4/urwid.egg-info/scm_version.json +8 -0
  7. urwid-4.2.3/urwid.egg-info/scm_version.json +0 -8
  8. {urwid-4.2.3 → urwid-4.2.4}/.devcontainer/dev.dockerfile +0 -0
  9. {urwid-4.2.3 → urwid-4.2.4}/.devcontainer/devcontainer.json +0 -0
  10. {urwid-4.2.3 → urwid-4.2.4}/.dockerignore +0 -0
  11. {urwid-4.2.3 → urwid-4.2.4}/.editorconfig +0 -0
  12. {urwid-4.2.3 → urwid-4.2.4}/.github/CODE_OF_CONDUCT.md +0 -0
  13. {urwid-4.2.3 → urwid-4.2.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {urwid-4.2.3 → urwid-4.2.4}/.github/ISSUE_TEMPLATE/docs.md +0 -0
  15. {urwid-4.2.3 → urwid-4.2.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  16. {urwid-4.2.3 → urwid-4.2.4}/.github/ISSUE_TEMPLATE/question.md +0 -0
  17. {urwid-4.2.3 → urwid-4.2.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  18. {urwid-4.2.3 → urwid-4.2.4}/.github/dependabot.yml +0 -0
  19. {urwid-4.2.3 → urwid-4.2.4}/.github/labeler.yml +0 -0
  20. {urwid-4.2.3 → urwid-4.2.4}/.github/release.yml +0 -0
  21. {urwid-4.2.3 → urwid-4.2.4}/.github/workflows/documentation.yml +0 -0
  22. {urwid-4.2.3 → urwid-4.2.4}/.github/workflows/isolated_mypy.yml +0 -0
  23. {urwid-4.2.3 → urwid-4.2.4}/.github/workflows/isolated_pylint.yml +0 -0
  24. {urwid-4.2.3 → urwid-4.2.4}/.github/workflows/labels.yml +0 -0
  25. {urwid-4.2.3 → urwid-4.2.4}/.github/workflows/pythonpackage.yml +0 -0
  26. {urwid-4.2.3 → urwid-4.2.4}/.github/workflows/yamllint.yml +0 -0
  27. {urwid-4.2.3 → urwid-4.2.4}/.gitignore +0 -0
  28. {urwid-4.2.3 → urwid-4.2.4}/.pre-commit-config.yaml +0 -0
  29. {urwid-4.2.3 → urwid-4.2.4}/.yamllint.yml +0 -0
  30. {urwid-4.2.3 → urwid-4.2.4}/COPYING +0 -0
  31. {urwid-4.2.3 → urwid-4.2.4}/MANIFEST.in +0 -0
  32. {urwid-4.2.3 → urwid-4.2.4}/README.rst +0 -0
  33. {urwid-4.2.3 → urwid-4.2.4}/SECURITY.md +0 -0
  34. {urwid-4.2.3 → urwid-4.2.4}/classifiers.txt +0 -0
  35. {urwid-4.2.3 → urwid-4.2.4}/conftest.py +0 -0
  36. {urwid-4.2.3 → urwid-4.2.4}/mypy-requirements.txt +0 -0
  37. {urwid-4.2.3 → urwid-4.2.4}/pylint-requirements.txt +0 -0
  38. {urwid-4.2.3 → urwid-4.2.4}/pyproject.toml +0 -0
  39. {urwid-4.2.3 → urwid-4.2.4}/pytest_requirements.txt +0 -0
  40. {urwid-4.2.3 → urwid-4.2.4}/requirements.txt +0 -0
  41. {urwid-4.2.3 → urwid-4.2.4}/setup.cfg +0 -0
  42. {urwid-4.2.3 → urwid-4.2.4}/tox.ini +0 -0
  43. {urwid-4.2.3 → urwid-4.2.4}/urwid/__init__.py +0 -0
  44. {urwid-4.2.3 → urwid-4.2.4}/urwid/ansi_parser.py +0 -0
  45. {urwid-4.2.3 → urwid-4.2.4}/urwid/canvas.py +0 -0
  46. {urwid-4.2.3 → urwid-4.2.4}/urwid/command_map.py +0 -0
  47. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/__init__.py +0 -0
  48. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/_posix_raw_display.py +0 -0
  49. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/_raw_display_base.py +0 -0
  50. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/_web.css +0 -0
  51. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/_web.js +0 -0
  52. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/_win32.py +0 -0
  53. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/_win32_raw_display.py +0 -0
  54. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/common.py +0 -0
  55. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/curses.py +0 -0
  56. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/escape.py +0 -0
  57. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/html_fragment.py +0 -0
  58. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/lcd.py +0 -0
  59. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/raw.py +0 -0
  60. {urwid-4.2.3 → urwid-4.2.4}/urwid/display/web.py +0 -0
  61. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/__init__.py +0 -0
  62. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/abstract_loop.py +0 -0
  63. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/asyncio_loop.py +0 -0
  64. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/glib_loop.py +0 -0
  65. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/main_loop.py +0 -0
  66. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/select_loop.py +0 -0
  67. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/tornado_loop.py +0 -0
  68. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/trio_loop.py +0 -0
  69. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/twisted_loop.py +0 -0
  70. {urwid-4.2.3 → urwid-4.2.4}/urwid/event_loop/zmq_loop.py +0 -0
  71. {urwid-4.2.3 → urwid-4.2.4}/urwid/font.py +0 -0
  72. {urwid-4.2.3 → urwid-4.2.4}/urwid/graphics.py +0 -0
  73. {urwid-4.2.3 → urwid-4.2.4}/urwid/numedit.py +0 -0
  74. {urwid-4.2.3 → urwid-4.2.4}/urwid/py.typed +0 -0
  75. {urwid-4.2.3 → urwid-4.2.4}/urwid/signals.py +0 -0
  76. {urwid-4.2.3 → urwid-4.2.4}/urwid/split_repr.py +0 -0
  77. {urwid-4.2.3 → urwid-4.2.4}/urwid/str_util.py +0 -0
  78. {urwid-4.2.3 → urwid-4.2.4}/urwid/text_layout.py +0 -0
  79. {urwid-4.2.3 → urwid-4.2.4}/urwid/util.py +0 -0
  80. {urwid-4.2.3 → urwid-4.2.4}/urwid/vterm.py +0 -0
  81. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/__init__.py +0 -0
  82. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/ansi_text.py +0 -0
  83. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/attr_map.py +0 -0
  84. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/attr_wrap.py +0 -0
  85. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/bar_graph.py +0 -0
  86. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/big_text.py +0 -0
  87. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/box_adapter.py +0 -0
  88. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/columns.py +0 -0
  89. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/constants.py +0 -0
  90. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/container.py +0 -0
  91. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/deque_walker.py +0 -0
  92. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/divider.py +0 -0
  93. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/edit.py +0 -0
  94. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/filler.py +0 -0
  95. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/frame.py +0 -0
  96. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/grid_flow.py +0 -0
  97. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/line_box.py +0 -0
  98. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/list_walker.py +0 -0
  99. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/monitored_deque.py +0 -0
  100. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/monitored_list.py +0 -0
  101. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/overlay.py +0 -0
  102. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/padding.py +0 -0
  103. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/pile.py +0 -0
  104. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/popup.py +0 -0
  105. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/progress_bar.py +0 -0
  106. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/scrollable.py +0 -0
  107. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/solid_fill.py +0 -0
  108. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/treetools.py +0 -0
  109. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/widget.py +0 -0
  110. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/widget_decoration.py +0 -0
  111. {urwid-4.2.3 → urwid-4.2.4}/urwid/widget/wimp.py +0 -0
  112. {urwid-4.2.3 → urwid-4.2.4}/urwid.egg-info/SOURCES.txt +0 -0
  113. {urwid-4.2.3 → urwid-4.2.4}/urwid.egg-info/dependency_links.txt +0 -0
  114. {urwid-4.2.3 → urwid-4.2.4}/urwid.egg-info/not-zip-safe +0 -0
  115. {urwid-4.2.3 → urwid-4.2.4}/urwid.egg-info/requires.txt +0 -0
  116. {urwid-4.2.3 → urwid-4.2.4}/urwid.egg-info/scm_file_list.json +0 -0
  117. {urwid-4.2.3 → urwid-4.2.4}/urwid.egg-info/top_level.txt +0 -0
  118. {urwid-4.2.3 → urwid-4.2.4}/yamllint-requirements.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: urwid
3
- Version: 4.2.3
3
+ Version: 4.2.4
4
4
  Summary: A full-featured console (xterm et al.) user interface library
5
5
  Author-email: Ian Ward <ian@excess.org>
6
6
  License-Expression: LGPL-2.1-only
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '4.2.3'
22
- __version_tuple__ = version_tuple = (4, 2, 3)
21
+ __version__ = version = '4.2.4'
22
+ __version_tuple__ = version_tuple = (4, 2, 4)
23
23
 
24
- __commit_id__ = commit_id = 'gbb4bfdce9'
24
+ __commit_id__ = commit_id = 'gb84a230c2'
@@ -900,7 +900,14 @@ class ListBox(Widget, WidgetContainerMixin[_K]):
900
900
  raise TypeError(f"{type(self._body)}.set_focus is not implemented.")
901
901
 
902
902
  # restore old focus temporarily
903
- self._body.set_focus(focus_pos)
903
+ try:
904
+ self._body.set_focus(focus_pos)
905
+ except (IndexError, KeyError):
906
+ # A focus that did move means a "modified" signal callback raised, not that the position is gone.
907
+ if self._body.get_focus()[1] != position:
908
+ raise
909
+ # The body lost the old focus position after ListBox.set_focus().
910
+ # The walker still focuses the new position, and the placement below starts from it.
904
911
 
905
912
  middle, top, bottom = self.calculate_visible((maxcol, maxrow), focus)
906
913
  if middle is None or top is None or bottom is None:
@@ -316,6 +316,17 @@ class Text(Widget):
316
316
  """Return the number of screen columns and rows required for this Text widget.
317
317
 
318
318
  The widget is expected to be displayed without wrapping or clipping, as a single element tuple.
319
+ With *maxcol* the size is taken from the layout at that width.
320
+ Without it the width is searched for::
321
+
322
+ maxcol = text width + 1, with StandardTextLayout tabs at their widest
323
+ |
324
+ v
325
+ lay out at maxcol --> layout has pack()? --no--> widest line, line count
326
+ ^ |
327
+ | yes
328
+ | v
329
+ double maxcol <--no-- layout.pack() < maxcol? --yes--> pack() columns, line count
319
330
 
320
331
  :param size: ``None`` or ``()`` for unlimited screen columns (like FIXED sizing)
321
332
  or (*maxcol*,) to specify a maximum column size
@@ -354,12 +365,19 @@ class Text(Widget):
354
365
  cols = self.layout.pack(maxcol, trans)
355
366
  return (cols, len(trans))
356
367
 
357
- # no line is wider than the whole text, except when tabs (counted here as 0 columns) push it further
368
+ layout = self.layout
369
+ # No line is wider than the whole text with every tab taking the widest gap between tab stops.
370
+ # A custom layout may still widen a line.
358
371
  maxcol = calc_width(text, 0, len(text)) + 1
372
+ tabs = text.count("\t") if isinstance(text, str) else text.count(b"\t")
373
+ if tabs and isinstance(layout, text_layout.StandardTextLayout):
374
+ stops = (0, *layout.tab_stops)
375
+ widest_tab = max((layout.tab_stop_every, *(end - start for start, end in zip(stops, stops[1:]))))
376
+ maxcol += widest_tab * tabs
359
377
  while True:
360
- trans = self.layout.layout(text, maxcol, self._align_mode, self._wrap_mode)
361
- if not hasattr(self.layout, "pack"):
378
+ trans = layout.layout(text, maxcol, self._align_mode, self._wrap_mode)
379
+ if not hasattr(layout, "pack"):
362
380
  return max(text_layout.line_width(line) for line in trans), len(trans)
363
- if (cols := self.layout.pack(maxcol, trans)) < maxcol:
381
+ if (cols := layout.pack(maxcol, trans)) < maxcol:
364
382
  return cols, len(trans)
365
383
  maxcol *= 2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: urwid
3
- Version: 4.2.3
3
+ Version: 4.2.4
4
4
  Summary: A full-featured console (xterm et al.) user interface library
5
5
  Author-email: Ian Ward <ian@excess.org>
6
6
  License-Expression: LGPL-2.1-only
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "4.2.4",
3
+ "distance": 0,
4
+ "node": "gb84a230c2b7d3de4a96480668002c34db0ff6e95",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-10-01"
8
+ }
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "4.2.3",
3
- "distance": 0,
4
- "node": "gbb4bfdce968f57f77bdbd69b5ad865dc4ea956b8",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-09-30"
8
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes