urwid 4.0.0__tar.gz → 4.0.2__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 (313) hide show
  1. {urwid-4.0.0 → urwid-4.0.2}/PKG-INFO +1 -1
  2. urwid-4.0.2/SECURITY.md +3 -0
  3. {urwid-4.0.0 → urwid-4.0.2}/docs/changelog.rst +75 -0
  4. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/bigtext.py +0 -1
  5. {urwid-4.0.0 → urwid-4.0.2}/examples/bigtext.py +0 -1
  6. {urwid-4.0.0 → urwid-4.0.2}/pyproject.toml +3 -0
  7. urwid-4.0.2/ruff-requirements.txt +1 -0
  8. {urwid-4.0.0 → urwid-4.0.2}/tests/test_listbox.py +25 -0
  9. {urwid-4.0.0 → urwid-4.0.2}/urwid/__init__.py +203 -1
  10. {urwid-4.0.0 → urwid-4.0.2}/urwid/canvas.py +28 -26
  11. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/__init__.py +3 -3
  12. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/_posix_raw_display.py +20 -11
  13. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/_raw_display_base.py +48 -24
  14. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/_win32.py +24 -11
  15. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/_win32_raw_display.py +3 -3
  16. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/common.py +8 -9
  17. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/curses.py +2 -2
  18. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/escape.py +3 -1
  19. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/lcd.py +1 -1
  20. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/web.py +3 -3
  21. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/abstract_loop.py +8 -1
  22. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/trio_loop.py +16 -13
  23. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/twisted_loop.py +10 -8
  24. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/zmq_loop.py +11 -12
  25. {urwid-4.0.0 → urwid-4.0.2}/urwid/graphics.py +2 -2
  26. {urwid-4.0.0 → urwid-4.0.2}/urwid/numedit.py +1 -1
  27. urwid-4.0.2/urwid/py.typed +0 -0
  28. {urwid-4.0.0 → urwid-4.0.2}/urwid/text_layout.py +9 -2
  29. {urwid-4.0.0 → urwid-4.0.2}/urwid/util.py +1 -1
  30. {urwid-4.0.0 → urwid-4.0.2}/urwid/version.py +3 -3
  31. {urwid-4.0.0 → urwid-4.0.2}/urwid/vterm.py +33 -24
  32. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/attr_map.py +5 -1
  33. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/columns.py +8 -6
  34. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/container.py +1 -1
  35. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/edit.py +1 -1
  36. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/frame.py +1 -1
  37. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/grid_flow.py +1 -1
  38. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/listbox.py +28 -2
  39. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/monitored_list.py +1 -1
  40. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/overlay.py +1 -1
  41. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/pile.py +23 -17
  42. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/popup.py +2 -2
  43. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/scrollable.py +20 -14
  44. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/text.py +4 -4
  45. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/treetools.py +8 -6
  46. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/widget_decoration.py +1 -1
  47. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/wimp.py +4 -4
  48. {urwid-4.0.0 → urwid-4.0.2}/urwid.egg-info/PKG-INFO +1 -1
  49. {urwid-4.0.0 → urwid-4.0.2}/urwid.egg-info/SOURCES.txt +2 -0
  50. urwid-4.0.0/ruff-requirements.txt +0 -1
  51. {urwid-4.0.0 → urwid-4.0.2}/.coveralls.yml +0 -0
  52. {urwid-4.0.0 → urwid-4.0.2}/.devcontainer/dev.dockerfile +0 -0
  53. {urwid-4.0.0 → urwid-4.0.2}/.devcontainer/devcontainer.json +0 -0
  54. {urwid-4.0.0 → urwid-4.0.2}/.dockerignore +0 -0
  55. {urwid-4.0.0 → urwid-4.0.2}/.editorconfig +0 -0
  56. {urwid-4.0.0 → urwid-4.0.2}/.github/CODE_OF_CONDUCT.md +0 -0
  57. {urwid-4.0.0 → urwid-4.0.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  58. {urwid-4.0.0 → urwid-4.0.2}/.github/ISSUE_TEMPLATE/docs.md +0 -0
  59. {urwid-4.0.0 → urwid-4.0.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  60. {urwid-4.0.0 → urwid-4.0.2}/.github/ISSUE_TEMPLATE/question.md +0 -0
  61. {urwid-4.0.0 → urwid-4.0.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  62. {urwid-4.0.0 → urwid-4.0.2}/.github/dependabot.yml +0 -0
  63. {urwid-4.0.0 → urwid-4.0.2}/.github/labeler.yml +0 -0
  64. {urwid-4.0.0 → urwid-4.0.2}/.github/release.yml +0 -0
  65. {urwid-4.0.0 → urwid-4.0.2}/.github/workflows/documentation.yml +0 -0
  66. {urwid-4.0.0 → urwid-4.0.2}/.github/workflows/isolated_static_check.yml +0 -0
  67. {urwid-4.0.0 → urwid-4.0.2}/.github/workflows/labels.yml +0 -0
  68. {urwid-4.0.0 → urwid-4.0.2}/.github/workflows/pythonpackage.yml +0 -0
  69. {urwid-4.0.0 → urwid-4.0.2}/.github/workflows/yamllint.yml +0 -0
  70. {urwid-4.0.0 → urwid-4.0.2}/.gitignore +0 -0
  71. {urwid-4.0.0 → urwid-4.0.2}/.pre-commit-config.yaml +0 -0
  72. {urwid-4.0.0 → urwid-4.0.2}/.yamllint.yml +0 -0
  73. {urwid-4.0.0 → urwid-4.0.2}/COPYING +0 -0
  74. {urwid-4.0.0 → urwid-4.0.2}/MANIFEST.in +0 -0
  75. {urwid-4.0.0 → urwid-4.0.2}/README.rst +0 -0
  76. {urwid-4.0.0 → urwid-4.0.2}/classifiers.txt +0 -0
  77. {urwid-4.0.0 → urwid-4.0.2}/docs/Makefile +0 -0
  78. {urwid-4.0.0 → urwid-4.0.2}/docs/conf.py +0 -0
  79. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/bigtext.py.xdotool +0 -0
  80. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/bigtext1.png +0 -0
  81. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/bigtext2.png +0 -0
  82. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/bigtext3.png +0 -0
  83. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/browse.py +0 -0
  84. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/browse.py.xdotool +0 -0
  85. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/browse1.png +0 -0
  86. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/browse2.png +0 -0
  87. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/edit.py +0 -0
  88. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/edit.py.xdotool +0 -0
  89. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/edit1.png +0 -0
  90. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/edit2.png +0 -0
  91. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/edit_text.txt +0 -0
  92. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/graph.py +0 -0
  93. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/graph.py.xdotool +0 -0
  94. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/graph1.png +0 -0
  95. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/graph2.png +0 -0
  96. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/index.rst +0 -0
  97. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/palette_test.py +0 -0
  98. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/palette_test.py.xdotool +0 -0
  99. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/palette_test1.png +0 -0
  100. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/palette_test2.png +0 -0
  101. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/pop_up.py +0 -0
  102. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/pop_up.py.xdotool +0 -0
  103. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/pop_up1.png +0 -0
  104. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/pop_up2.png +0 -0
  105. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/real_browse.py +0 -0
  106. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/real_edit.py +0 -0
  107. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/subproc.py +0 -0
  108. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/subproc.py.xdotool +0 -0
  109. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/subproc1.png +0 -0
  110. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/subproc2.png +0 -0
  111. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/subproc2.py +0 -0
  112. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/tour.py +0 -0
  113. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/tour.py.xdotool +0 -0
  114. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/tour1.png +0 -0
  115. {urwid-4.0.0 → urwid-4.0.2}/docs/examples/tour2.png +0 -0
  116. {urwid-4.0.0 → urwid-4.0.2}/docs/index.rst +0 -0
  117. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/bright_combinations.py +0 -0
  118. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/bright_combinations.py.xdotool +0 -0
  119. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/bright_combinations1.png +0 -0
  120. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/canvascache.rst +0 -0
  121. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/displayattributes.rst +0 -0
  122. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/displaymodules.rst +0 -0
  123. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/encodings.rst +0 -0
  124. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/images/display_modules.png +0 -0
  125. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/images/introduction.png +0 -0
  126. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/images/urwid_widgets.svgz +0 -0
  127. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/images/urwid_widgets_1.png +0 -0
  128. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/images/urwid_widgets_1.xcf +0 -0
  129. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/images/urwid_widgets_2.png +0 -0
  130. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/images/urwid_widgets_2.xcf +0 -0
  131. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/images/widget_layout.png +0 -0
  132. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/index.rst +0 -0
  133. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/mainloop.rst +0 -0
  134. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/overview.rst +0 -0
  135. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/safe_combinations.py +0 -0
  136. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/safe_combinations.py.xdotool +0 -0
  137. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/safe_combinations1.png +0 -0
  138. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/textlayout.rst +0 -0
  139. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/userinput.rst +0 -0
  140. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/wanat.py +0 -0
  141. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/wanat_multi.py +0 -0
  142. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/wcur1.py +0 -0
  143. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/wcur2.py +0 -0
  144. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/widgets.rst +0 -0
  145. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/wmod.py +0 -0
  146. {urwid-4.0.0 → urwid-4.0.2}/docs/manual/wsel.py +0 -0
  147. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/attrspec.rst +0 -0
  148. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/canvas.rst +0 -0
  149. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/command_map.rst +0 -0
  150. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/constants.rst +0 -0
  151. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/deprecated.rst +0 -0
  152. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/display_modules.rst +0 -0
  153. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/exceptions.rst +0 -0
  154. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/global_settings.rst +0 -0
  155. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/index.rst +0 -0
  156. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/list_walkers.rst +0 -0
  157. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/main_loop.rst +0 -0
  158. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/meta.rst +0 -0
  159. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/signals.rst +0 -0
  160. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/text_layout.rst +0 -0
  161. {urwid-4.0.0 → urwid-4.0.2}/docs/reference/widget.rst +0 -0
  162. {urwid-4.0.0 → urwid-4.0.2}/docs/tools/compile_pngs.sh +0 -0
  163. {urwid-4.0.0 → urwid-4.0.2}/docs/tools/screenshots.sh +0 -0
  164. {urwid-4.0.0 → urwid-4.0.2}/docs/tools/static/.placeholder +0 -0
  165. {urwid-4.0.0 → urwid-4.0.2}/docs/tools/templates/indexcontent.html +0 -0
  166. {urwid-4.0.0 → urwid-4.0.2}/docs/tools/templates/indexsidebar.html +0 -0
  167. {urwid-4.0.0 → urwid-4.0.2}/docs/tools/templates/localtoc.html +0 -0
  168. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/adventure.py +0 -0
  169. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/adventure.py.xdotool +0 -0
  170. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/adventure1.png +0 -0
  171. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/adventure2.png +0 -0
  172. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/adventure3.png +0 -0
  173. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/adventure4.png +0 -0
  174. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/cmenu.py +0 -0
  175. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/cmenu.py.xdotool +0 -0
  176. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/cmenu1.png +0 -0
  177. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/cmenu2.png +0 -0
  178. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/cmenu3.png +0 -0
  179. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/cmenu4.png +0 -0
  180. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/highcolors.py +0 -0
  181. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/highcolors.py.xdotool +0 -0
  182. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/highcolors1.png +0 -0
  183. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/hmenu.py +0 -0
  184. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/hmenu.py.xdotool +0 -0
  185. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/hmenu1.png +0 -0
  186. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/hmenu2.png +0 -0
  187. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/hmenu3.png +0 -0
  188. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/hmenu4.png +0 -0
  189. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/index.rst +0 -0
  190. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/input.py +0 -0
  191. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/input.py.xdotool +0 -0
  192. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/input1.png +0 -0
  193. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/input2.png +0 -0
  194. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/input3.png +0 -0
  195. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/input4.png +0 -0
  196. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/input5.png +0 -0
  197. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/menu25.png +0 -0
  198. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/minimal.py +0 -0
  199. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/minimal.py.xdotool +0 -0
  200. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/minimal1.png +0 -0
  201. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/multiple.py +0 -0
  202. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/multiple.py.xdotool +0 -0
  203. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/multiple1.png +0 -0
  204. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/multiple2.png +0 -0
  205. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/multiple3.png +0 -0
  206. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/multiple4.png +0 -0
  207. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/qa.py +0 -0
  208. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/qa.py.xdotool +0 -0
  209. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/qa1.png +0 -0
  210. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/qa2.png +0 -0
  211. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/qa3.png +0 -0
  212. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/sig.py +0 -0
  213. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/sig.py.xdotool +0 -0
  214. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/sig1.png +0 -0
  215. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/sig2.png +0 -0
  216. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/sig3.png +0 -0
  217. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/sig4.png +0 -0
  218. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/smenu.py +0 -0
  219. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/smenu.py.xdotool +0 -0
  220. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/smenu1.png +0 -0
  221. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/smenu2.png +0 -0
  222. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/smenu3.png +0 -0
  223. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/urwid_attr.py +0 -0
  224. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/urwid_attr.py.xdotool +0 -0
  225. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/urwid_attr1.png +0 -0
  226. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/urwid_attr2.png +0 -0
  227. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/urwid_attr3.png +0 -0
  228. {urwid-4.0.0 → urwid-4.0.2}/docs/tutorial/urwid_attr4.png +0 -0
  229. {urwid-4.0.0 → urwid-4.0.2}/docs/urwid-logo.png +0 -0
  230. {urwid-4.0.0 → urwid-4.0.2}/examples/asyncio_socket_server.py +0 -0
  231. {urwid-4.0.0 → urwid-4.0.2}/examples/browse.py +0 -0
  232. {urwid-4.0.0 → urwid-4.0.2}/examples/calc.py +0 -0
  233. {urwid-4.0.0 → urwid-4.0.2}/examples/dialog.py +0 -0
  234. {urwid-4.0.0 → urwid-4.0.2}/examples/edit.py +0 -0
  235. {urwid-4.0.0 → urwid-4.0.2}/examples/fib.py +0 -0
  236. {urwid-4.0.0 → urwid-4.0.2}/examples/graph.py +0 -0
  237. {urwid-4.0.0 → urwid-4.0.2}/examples/input_test.py +0 -0
  238. {urwid-4.0.0 → urwid-4.0.2}/examples/lcd_cf635.py +0 -0
  239. {urwid-4.0.0 → urwid-4.0.2}/examples/palette_test.py +0 -0
  240. {urwid-4.0.0 → urwid-4.0.2}/examples/pop_up.py +0 -0
  241. {urwid-4.0.0 → urwid-4.0.2}/examples/subproc.py +0 -0
  242. {urwid-4.0.0 → urwid-4.0.2}/examples/subproc2.py +0 -0
  243. {urwid-4.0.0 → urwid-4.0.2}/examples/terminal.py +0 -0
  244. {urwid-4.0.0 → urwid-4.0.2}/examples/tour.py +0 -0
  245. {urwid-4.0.0 → urwid-4.0.2}/examples/treesample.py +0 -0
  246. {urwid-4.0.0 → urwid-4.0.2}/examples/twisted_serve_ssh.py +0 -0
  247. {urwid-4.0.0 → urwid-4.0.2}/examples/twisted_serve_ssh.tac +0 -0
  248. {urwid-4.0.0 → urwid-4.0.2}/pylint-requirements.txt +0 -0
  249. {urwid-4.0.0 → urwid-4.0.2}/requirements.txt +0 -0
  250. {urwid-4.0.0 → urwid-4.0.2}/setup.cfg +0 -0
  251. {urwid-4.0.0 → urwid-4.0.2}/test_requirements.txt +0 -0
  252. {urwid-4.0.0 → urwid-4.0.2}/tests/__init__.py +0 -0
  253. {urwid-4.0.0 → urwid-4.0.2}/tests/test_canvas.py +0 -0
  254. {urwid-4.0.0 → urwid-4.0.2}/tests/test_columns.py +0 -0
  255. {urwid-4.0.0 → urwid-4.0.2}/tests/test_container.py +0 -0
  256. {urwid-4.0.0 → urwid-4.0.2}/tests/test_doctests.py +0 -0
  257. {urwid-4.0.0 → urwid-4.0.2}/tests/test_escapes.py +0 -0
  258. {urwid-4.0.0 → urwid-4.0.2}/tests/test_event_loops.py +0 -0
  259. {urwid-4.0.0 → urwid-4.0.2}/tests/test_filler.py +0 -0
  260. {urwid-4.0.0 → urwid-4.0.2}/tests/test_floatedit.py +0 -0
  261. {urwid-4.0.0 → urwid-4.0.2}/tests/test_font.py +0 -0
  262. {urwid-4.0.0 → urwid-4.0.2}/tests/test_frame.py +0 -0
  263. {urwid-4.0.0 → urwid-4.0.2}/tests/test_grapheme_clusters.py +0 -0
  264. {urwid-4.0.0 → urwid-4.0.2}/tests/test_graphics.py +0 -0
  265. {urwid-4.0.0 → urwid-4.0.2}/tests/test_grid_flow.py +0 -0
  266. {urwid-4.0.0 → urwid-4.0.2}/tests/test_line_box.py +0 -0
  267. {urwid-4.0.0 → urwid-4.0.2}/tests/test_main_loop.py +0 -0
  268. {urwid-4.0.0 → urwid-4.0.2}/tests/test_overlay.py +0 -0
  269. {urwid-4.0.0 → urwid-4.0.2}/tests/test_padding.py +0 -0
  270. {urwid-4.0.0 → urwid-4.0.2}/tests/test_pile.py +0 -0
  271. {urwid-4.0.0 → urwid-4.0.2}/tests/test_raw_display.py +0 -0
  272. {urwid-4.0.0 → urwid-4.0.2}/tests/test_scrollable.py +0 -0
  273. {urwid-4.0.0 → urwid-4.0.2}/tests/test_signals.py +0 -0
  274. {urwid-4.0.0 → urwid-4.0.2}/tests/test_str_util.py +0 -0
  275. {urwid-4.0.0 → urwid-4.0.2}/tests/test_text_layout.py +0 -0
  276. {urwid-4.0.0 → urwid-4.0.2}/tests/test_tree.py +0 -0
  277. {urwid-4.0.0 → urwid-4.0.2}/tests/test_util.py +0 -0
  278. {urwid-4.0.0 → urwid-4.0.2}/tests/test_vterm.py +0 -0
  279. {urwid-4.0.0 → urwid-4.0.2}/tests/test_widget.py +0 -0
  280. {urwid-4.0.0 → urwid-4.0.2}/tests/util.py +0 -0
  281. {urwid-4.0.0 → urwid-4.0.2}/tox.ini +0 -0
  282. {urwid-4.0.0 → urwid-4.0.2}/urwid/command_map.py +0 -0
  283. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/_web.css +0 -0
  284. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/_web.js +0 -0
  285. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/html_fragment.py +0 -0
  286. {urwid-4.0.0 → urwid-4.0.2}/urwid/display/raw.py +0 -0
  287. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/__init__.py +0 -0
  288. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/asyncio_loop.py +0 -0
  289. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/glib_loop.py +0 -0
  290. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/main_loop.py +0 -0
  291. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/select_loop.py +0 -0
  292. {urwid-4.0.0 → urwid-4.0.2}/urwid/event_loop/tornado_loop.py +0 -0
  293. {urwid-4.0.0 → urwid-4.0.2}/urwid/font.py +0 -0
  294. {urwid-4.0.0 → urwid-4.0.2}/urwid/signals.py +0 -0
  295. {urwid-4.0.0 → urwid-4.0.2}/urwid/split_repr.py +0 -0
  296. {urwid-4.0.0 → urwid-4.0.2}/urwid/str_util.py +0 -0
  297. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/__init__.py +0 -0
  298. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/attr_wrap.py +0 -0
  299. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/bar_graph.py +0 -0
  300. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/big_text.py +0 -0
  301. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/box_adapter.py +0 -0
  302. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/constants.py +0 -0
  303. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/divider.py +0 -0
  304. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/filler.py +0 -0
  305. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/line_box.py +0 -0
  306. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/padding.py +0 -0
  307. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/progress_bar.py +0 -0
  308. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/solid_fill.py +0 -0
  309. {urwid-4.0.0 → urwid-4.0.2}/urwid/widget/widget.py +0 -0
  310. {urwid-4.0.0 → urwid-4.0.2}/urwid.egg-info/dependency_links.txt +0 -0
  311. {urwid-4.0.0 → urwid-4.0.2}/urwid.egg-info/not-zip-safe +0 -0
  312. {urwid-4.0.0 → urwid-4.0.2}/urwid.egg-info/requires.txt +0 -0
  313. {urwid-4.0.0 → urwid-4.0.2}/urwid.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: urwid
3
- Version: 4.0.0
3
+ Version: 4.0.2
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,3 @@
1
+ # Security
2
+
3
+ Report vulnerabilities at https://github.com/urwid/urwid/security/advisories
@@ -2,6 +2,81 @@
2
2
  Changelog
3
3
  ---------
4
4
 
5
+ Urwid 4.0.2
6
+ ===========
7
+
8
+ 2026-06-02
9
+
10
+ New features 🗹
11
+ +++++++++++++++
12
+ * Initial typing support for urwid package by @penguinolog in https://github.com/urwid/urwid/pull/1144
13
+ Bug fixes 🕷
14
+ ++++++++++++
15
+ * Fix ListBoxError in _keypress_page_down when snapping to a widget above the top by @neutralinsomniac in https://github.com/urwid/urwid/pull/1133
16
+ * Fix lazy_import of display modules if __package__ is not defined by @penguinolog in https://github.com/urwid/urwid/pull/1136
17
+ Documentation 🕮
18
+ ++++++++++++++++
19
+ * Adjust typing for `urwid.display` and `urwid.event_loop` by @penguinolog in https://github.com/urwid/urwid/pull/1138
20
+ * Typing: extend typing information for `urwid.display` by @penguinolog in https://github.com/urwid/urwid/pull/1139
21
+ * Typing: adjust event loop types by @penguinolog in https://github.com/urwid/urwid/pull/1140
22
+ * Typing: adjust types for vterm, numedit and graphics by @penguinolog in https://github.com/urwid/urwid/pull/1141
23
+ * Typing: adjust types for `urwid.widget` by @penguinolog in https://github.com/urwid/urwid/pull/1142
24
+ Refactoring 🛠
25
+ ++++++++++++++
26
+ * Feat: refactor `urwid.widget.scrollable` by @penguinolog in https://github.com/urwid/urwid/pull/1143
27
+ Other Changes
28
+ +++++++++++++
29
+ * Web display: tighten security by using more complex identifiers by @penguinolog in https://github.com/urwid/urwid/pull/1137
30
+
31
+ New Contributors
32
+ ++++++++++++++++
33
+ * @neutralinsomniac made their first contribution in https://github.com/urwid/urwid/pull/1133
34
+
35
+ **Full Changelog**: https://github.com/urwid/urwid/compare/4.0.1...4.0.2
36
+
37
+ Urwid 4.0.1
38
+ ===========
39
+
40
+ 2026-05-26
41
+
42
+ Bug fixes 🕷
43
+ ++++++++++++
44
+ * fix three return type annotations by @evgunter in https://github.com/urwid/urwid/pull/1121
45
+ * Web display: use secure random session identifiers by @penguinolog in https://github.com/urwid/urwid/pull/1128
46
+ Other Changes
47
+ +++++++++++++
48
+ * Add SECURITY.md by @jrwe in https://github.com/urwid/urwid/pull/1123
49
+
50
+ New Contributors
51
+ ++++++++++++++++
52
+ * @evgunter made their first contribution in https://github.com/urwid/urwid/pull/1121
53
+ * @jrwe made their first contribution in https://github.com/urwid/urwid/pull/1123
54
+
55
+ **Full Changelog**: https://github.com/urwid/urwid/compare/4.0.0...4.0.1
56
+
57
+ Urwid 4.0.0
58
+ ===========
59
+
60
+ 2026-03-30
61
+
62
+ Breaking Changes ⚠
63
+ ++++++++++++++++++
64
+ * Deprecation: Remove deprecated protected methods for version 4 by @penguinolog in https://github.com/urwid/urwid/pull/1078
65
+ * Deprecation: Remove deprecated public methods announced to be removed in v4 by @penguinolog in https://github.com/urwid/urwid/pull/1085
66
+ * Deprecation: Remove deprecated `Filler.get_body` and `Filler.set_body` by @penguinolog in https://github.com/urwid/urwid/pull/1117
67
+ Deprecations ⚡
68
+ ++++++++++++++
69
+ * Deprecation: announce deadline for deprecated APIs by @penguinolog in https://github.com/urwid/urwid/pull/1118
70
+ Bug fixes 🕷
71
+ ++++++++++++
72
+ * stdin handling for closed state by @wilkpio in https://github.com/urwid/urwid/pull/1112
73
+
74
+ New Contributors
75
+ ++++++++++++++++
76
+ * @wilkpio made their first contribution in https://github.com/urwid/urwid/pull/1112
77
+
78
+ **Full Changelog**: https://github.com/urwid/urwid/compare/3.0.5...4.0.0
79
+
5
80
  Urwid 3.0.5
6
81
  ===========
7
82
 
@@ -28,7 +28,6 @@ from __future__ import annotations
28
28
  import typing
29
29
 
30
30
  import urwid
31
- import urwid.display.raw
32
31
 
33
32
  if typing.TYPE_CHECKING:
34
33
  from collections.abc import Callable
@@ -28,7 +28,6 @@ from __future__ import annotations
28
28
  import typing
29
29
 
30
30
  import urwid
31
- import urwid.display.raw
32
31
 
33
32
  if typing.TYPE_CHECKING:
34
33
  from collections.abc import Callable
@@ -54,6 +54,9 @@ lcd = ["pyserial"]
54
54
  [tool.distutils.bdist_wheel]
55
55
  universal = 0
56
56
 
57
+ [tool.setuptools.package-data]
58
+ urwid = [ "py.typed" ]
59
+
57
60
  [tool.setuptools_scm]
58
61
  write_to = "urwid/version.py"
59
62
 
@@ -0,0 +1 @@
1
+ ruff==0.15.15
@@ -1960,6 +1960,31 @@ class ZeroHeightContentsTest(unittest.TestCase):
1960
1960
  self.assertEqual([b"below ", b" ", b" ", b" ", b" "], canvas.text)
1961
1961
 
1962
1962
 
1963
+ class PageDownAboveTopTest(unittest.TestCase):
1964
+ def test_page_down_does_not_raise(self):
1965
+ # Two-row rows so the four-item list does not fit the viewport at once.
1966
+ lb = urwid.ListBox(
1967
+ urwid.SimpleListWalker(
1968
+ [
1969
+ urwid.Text("a0\nb0"),
1970
+ SelectableText("a1\nb1"),
1971
+ urwid.Text("a2\nb2"),
1972
+ urwid.Text("a3\nb3"),
1973
+ ]
1974
+ )
1975
+ )
1976
+ size = (7, 4)
1977
+ lb.set_focus(0)
1978
+ lb.render(size, focus=True)
1979
+ lb.keypress(size, "page down") # used to raise ListBoxError
1980
+ self.assertEqual(lb.focus_position, 3)
1981
+ canvas = lb.render(size, focus=True)
1982
+ self.assertEqual([b"a2 ", b"b2 ", b"a3 ", b"b3 "], canvas.text)
1983
+ # a second page down at the bottom is a no-op, not a crash
1984
+ lb.keypress(size, "page down")
1985
+ self.assertEqual(lb.focus_position, 3)
1986
+
1987
+
1963
1988
  class ListBoxSetBodyTest(unittest.TestCase):
1964
1989
  def test_signal_connected(self):
1965
1990
  lb = urwid.ListBox([])
@@ -215,37 +215,239 @@ from .widget import (
215
215
  scale_bar_values,
216
216
  )
217
217
 
218
+ __all__ = (
219
+ "ACTIVATE",
220
+ "ANY",
221
+ "BLACK",
222
+ "BOTTOM",
223
+ "BOX",
224
+ "BROWN",
225
+ "CENTER",
226
+ "CLIP",
227
+ "CURSOR_DOWN",
228
+ "CURSOR_LEFT",
229
+ "CURSOR_MAX_LEFT",
230
+ "CURSOR_MAX_RIGHT",
231
+ "CURSOR_PAGE_DOWN",
232
+ "CURSOR_PAGE_UP",
233
+ "CURSOR_RIGHT",
234
+ "CURSOR_UP",
235
+ "DARK_BLUE",
236
+ "DARK_CYAN",
237
+ "DARK_GRAY",
238
+ "DARK_GREEN",
239
+ "DARK_MAGENTA",
240
+ "DARK_RED",
241
+ "DEFAULT",
242
+ "ELLIPSIS",
243
+ "FIXED",
244
+ "FLOW",
245
+ "GIVEN",
246
+ "LEFT",
247
+ "LIGHT_BLUE",
248
+ "LIGHT_CYAN",
249
+ "LIGHT_GRAY",
250
+ "LIGHT_GREEN",
251
+ "LIGHT_MAGENTA",
252
+ "LIGHT_RED",
253
+ "MIDDLE",
254
+ "PACK",
255
+ "REDRAW_SCREEN",
256
+ "RELATIVE",
257
+ "RELATIVE_100",
258
+ "RIGHT",
259
+ "SPACE",
260
+ "TOP",
261
+ "UPDATE_PALETTE_ENTRY",
262
+ "WEIGHT",
263
+ "WHITE",
264
+ "YELLOW",
265
+ "Align",
266
+ "AsyncioEventLoop",
267
+ "AttrMap",
268
+ "AttrMapError",
269
+ "AttrSpec",
270
+ "AttrSpecError",
271
+ "AttrWrap",
272
+ "BarGraph",
273
+ "BarGraphError",
274
+ "BarGraphMeta",
275
+ "BaseScreen",
276
+ "BigText",
277
+ "BlankCanvas",
278
+ "BoxAdapter",
279
+ "BoxAdapterError",
280
+ "Button",
281
+ "Canvas",
282
+ "CanvasCache",
283
+ "CanvasCombine",
284
+ "CanvasError",
285
+ "CanvasJoin",
286
+ "CanvasOverlay",
287
+ "CheckBox",
288
+ "CheckBoxError",
289
+ "Columns",
290
+ "ColumnsError",
291
+ "CommandMap",
292
+ "CompositeCanvas",
293
+ "Divider",
294
+ "Edit",
295
+ "EditError",
296
+ "EventLoop",
297
+ "ExitMainLoop",
298
+ "Filler",
299
+ "FillerError",
300
+ "Font",
301
+ "FontRegistry",
302
+ "Frame",
303
+ "FrameError",
304
+ "GraphVScale",
305
+ "GridFlow",
306
+ "GridFlowError",
307
+ "HalfBlock5x4Font",
308
+ "HalfBlock6x5Font",
309
+ "HalfBlock7x7Font",
310
+ "HalfBlockHeavy6x5Font",
311
+ "IntEdit",
312
+ "LayoutSegment",
313
+ "LineBox",
314
+ "ListBox",
315
+ "ListBoxError",
316
+ "ListWalker",
317
+ "ListWalkerError",
318
+ "MainLoop",
319
+ "MetaSignals",
320
+ "MetaSuper",
321
+ "MonitoredFocusList",
322
+ "MonitoredList",
323
+ "Overlay",
324
+ "OverlayError",
325
+ "Padding",
326
+ "PaddingError",
327
+ "ParentNode",
328
+ "Pile",
329
+ "PileError",
330
+ "PopUpLauncher",
331
+ "PopUpTarget",
332
+ "ProgressBar",
333
+ "RadioButton",
334
+ "RealTerminal",
335
+ "ScreenError",
336
+ "ScrollBar",
337
+ "Scrollable",
338
+ "SelectEventLoop",
339
+ "SelectableIcon",
340
+ "Sextant2x2Font",
341
+ "Sextant3x3Font",
342
+ "Signals",
343
+ "SimpleFocusListWalker",
344
+ "SimpleListWalker",
345
+ "Sizing",
346
+ "SolidCanvas",
347
+ "SolidFill",
348
+ "StandardTextLayout",
349
+ "TagMarkupException",
350
+ "Text",
351
+ "TextCanvas",
352
+ "TextError",
353
+ "TextLayout",
354
+ "Thin3x3Font",
355
+ "Thin4x3Font",
356
+ "Thin6x6Font",
357
+ "TreeListBox",
358
+ "TreeNode",
359
+ "TreeWalker",
360
+ "TreeWidget",
361
+ "TreeWidgetError",
362
+ "VAlign",
363
+ "WHSettings",
364
+ "Widget",
365
+ "WidgetContainerMixin",
366
+ "WidgetDecoration",
367
+ "WidgetDisable",
368
+ "WidgetError",
369
+ "WidgetMeta",
370
+ "WidgetPlaceholder",
371
+ "WidgetWrap",
372
+ "WidgetWrapError",
373
+ "WrapMode",
374
+ "__version__",
375
+ "__version_tuple__",
376
+ "apply_target_encoding",
377
+ "calc_text_pos",
378
+ "calc_trim_text",
379
+ "calc_width",
380
+ "command_map",
381
+ "connect_signal",
382
+ "decompose_tagmarkup",
383
+ "default_layout",
384
+ "delegate_to_widget_mixin",
385
+ "detected_encoding",
386
+ "disconnect_signal",
387
+ "disconnect_signal_by_key",
388
+ "display",
389
+ "emit_signal",
390
+ "event_loop",
391
+ "fixed_size",
392
+ "get_all_fonts",
393
+ "get_encoding_mode",
394
+ "int_scale",
395
+ "is_mouse_event",
396
+ "is_wide_char",
397
+ "move_next_char",
398
+ "move_prev_char",
399
+ "register_signal",
400
+ "scale_bar_values",
401
+ "set_encoding",
402
+ "supports_unicode",
403
+ "widget",
404
+ "within_double_byte",
405
+ )
406
+
407
+
218
408
  # Optional event loops with external dependencies
219
409
 
220
410
  try:
221
411
  from .event_loop import TornadoEventLoop
222
412
  except ImportError:
223
413
  pass
414
+ else:
415
+ __all__ += ("TornadoEventLoop",)
224
416
 
225
417
  try:
226
418
  from .event_loop import GLibEventLoop
227
419
  except ImportError:
228
420
  pass
421
+ else:
422
+ __all__ += ("GLibEventLoop",)
229
423
 
230
424
  try:
231
425
  from .event_loop import TwistedEventLoop
232
426
  except ImportError:
233
427
  pass
428
+ else:
429
+ __all__ += ("TwistedEventLoop",)
234
430
 
235
431
  try:
236
432
  from .event_loop import TrioEventLoop
237
433
  except ImportError:
238
434
  pass
435
+ else:
436
+ __all__ += ("TrioEventLoop",)
239
437
 
240
438
  # OS Specific
241
439
  if sys.platform != "win32":
242
440
  from .vterm import TermCanvas, TermCharset, Terminal, TermModes
243
441
 
244
- # ZMQEventLoop cause interpreter crash on windows
442
+ __all__ += ("TermCanvas", "TermCharset", "TermModes", "Terminal")
443
+
444
+ # ZMQEventLoop cause interpreter crash on Windows
245
445
  try:
246
446
  from .event_loop import ZMQEventLoop
247
447
  except ImportError:
248
448
  pass
449
+ else:
450
+ __all__ += ("ZMQEventLoop",)
249
451
 
250
452
  # Backward compatibility
251
453
  VERSION = __version_tuple__
@@ -39,10 +39,11 @@ from urwid.util import (
39
39
  )
40
40
 
41
41
  if typing.TYPE_CHECKING:
42
- from collections.abc import Hashable, Iterable, Iterator, Sequence
42
+ from collections.abc import Hashable, Iterable, Iterator, Mapping, Sequence
43
43
 
44
44
  from typing_extensions import Literal
45
45
 
46
+ from .display.common import AttrSpec
46
47
  from .widget import Widget
47
48
 
48
49
 
@@ -214,7 +215,7 @@ class Canvas:
214
215
 
215
216
  def __init__(self) -> None:
216
217
  """Base Canvas class"""
217
- self._widget_info: tuple[Widget, tuple[[]] | tuple[int] | tuple[int, int], bool] | None = None
218
+ self._widget_info: tuple[Widget, tuple[()] | tuple[int] | tuple[int, int], bool] | None = None
218
219
  self.coords: dict[str, tuple[int, int, tuple[Widget, int, int]] | tuple[int, int, None]] = {}
219
220
  self.shortcuts: dict[str, str] = {}
220
221
 
@@ -240,7 +241,7 @@ class Canvas:
240
241
  self._widget_info = widget, size, focus
241
242
 
242
243
  @property
243
- def widget_info(self) -> tuple[Widget, tuple[[]] | tuple[int] | tuple[int, int], bool] | None:
244
+ def widget_info(self) -> tuple[Widget, tuple[()] | tuple[int] | tuple[int, int], bool] | None:
244
245
  return self._widget_info
245
246
 
246
247
  @property
@@ -260,10 +261,10 @@ class Canvas:
260
261
  self,
261
262
  trim_left: int = 0,
262
263
  trim_top: int = 0,
263
- cols: int | None = None,
264
- rows: int | None = None,
265
- attr=None,
266
- ) -> Iterator[list[tuple[object, Literal["0", "U"] | None, bytes]]]:
264
+ cols: int = 0,
265
+ rows: int = 0,
266
+ attr: Mapping[object, AttrSpec | str | None] | None = None,
267
+ ) -> Iterator[list[tuple[AttrSpec | str | None, Literal["0", "U"] | None, bytes]]]:
267
268
  raise NotImplementedError()
268
269
 
269
270
  def cols(self) -> int:
@@ -321,7 +322,7 @@ class Canvas:
321
322
 
322
323
  self.coords["pop up"] = (left, top, (w, overlay_width, overlay_height))
323
324
 
324
- def translate_coords(self, dx: int, dy: int) -> dict[str, tuple[int, int, tuple[Widget, int, int]]]:
325
+ def translate_coords(self, dx: int, dy: int) -> dict[str, tuple[int, int, tuple[Widget, int, int] | None]]:
325
326
  """
326
327
  Return coords shifted by (dx, dy).
327
328
  """
@@ -455,10 +456,10 @@ class TextCanvas(Canvas):
455
456
  self,
456
457
  trim_left: int = 0,
457
458
  trim_top: int = 0,
458
- cols: int | None = 0,
459
- rows: int | None = 0,
460
- attr=None,
461
- ) -> Iterator[tuple[object, Literal["0", "U"] | None, bytes]]:
459
+ cols: int = 0,
460
+ rows: int = 0,
461
+ attr: Mapping[object, AttrSpec | str | None] | None = None,
462
+ ) -> Iterator[list[tuple[AttrSpec | str | None, Literal["0", "U"] | None, bytes]]]:
462
463
  """
463
464
  Return the canvas content as a list of rows where each row
464
465
  is a list of (attr, cs, text) tuples.
@@ -529,10 +530,10 @@ class BlankCanvas(Canvas):
529
530
  self,
530
531
  trim_left: int = 0,
531
532
  trim_top: int = 0,
532
- cols: int | None = 0,
533
- rows: int | None = 0,
534
- attr=None,
535
- ) -> Iterator[list[tuple[object, Literal["0", "U"] | None, bytes]]]:
533
+ cols: int = 0,
534
+ rows: int = 0,
535
+ attr: Mapping[object, AttrSpec | str | None] | None = None,
536
+ ) -> Iterator[list[tuple[AttrSpec | str | None, Literal["0", "U"] | None, bytes]]]:
536
537
  """
537
538
  return (cols, rows) of spaces with default attributes.
538
539
  """
@@ -583,8 +584,8 @@ class SolidCanvas(Canvas):
583
584
  trim_top: int = 0,
584
585
  cols: int | None = None,
585
586
  rows: int | None = None,
586
- attr=None,
587
- ) -> Iterator[list[tuple[object, Literal["0", "U"] | None, bytes]]]:
587
+ attr: Mapping[object, AttrSpec | str | None] | None = None,
588
+ ) -> Iterator[list[tuple[AttrSpec | str | None, Literal["0", "U"] | None, bytes]]]:
588
589
  if cols is None:
589
590
  cols = self.size[0]
590
591
  if rows is None:
@@ -611,7 +612,7 @@ class CompositeCanvas(Canvas):
611
612
  class for storing a combination of canvases
612
613
  """
613
614
 
614
- def __init__(self, canv: Canvas = None) -> None:
615
+ def __init__(self, canv: Canvas | None = None) -> None:
615
616
  """
616
617
  canv -- a Canvas object to wrap this CompositeCanvas around.
617
618
 
@@ -682,13 +683,14 @@ class CompositeCanvas(Canvas):
682
683
  self,
683
684
  trim_left: int = 0,
684
685
  trim_top: int = 0,
685
- cols: int | None = None,
686
- rows: int | None = None,
687
- attr=None,
688
- ) -> Iterator[list[tuple[object, Literal["0", "U"] | None, bytes]]]:
686
+ cols: int = 0,
687
+ rows: int = 0,
688
+ attr: Mapping[object, AttrSpec | str | None] | None = None,
689
+ ) -> Iterator[list[tuple[AttrSpec | str | None, Literal["0", "U"] | None, bytes]]]:
689
690
  """
690
- Return the canvas content as a list of rows where each row
691
- is a list of (attr, cs, text) tuples.
691
+ Return the canvas content as a list of rows where each row is a list of (attr, cs, text) tuples.
692
+
693
+ All parameters are ignored.
692
694
  """
693
695
  shard_tail = []
694
696
  for num_rows, cviews in self.shards:
@@ -1217,7 +1219,7 @@ def CanvasCombine(canvas_info: Iterable[tuple[Canvas, typing.Any, bool]]) -> Com
1217
1219
  return combined_canvas
1218
1220
 
1219
1221
 
1220
- def CanvasOverlay(top_c: Canvas, bottom_c: Canvas, left: int, top: int) -> CompositeCanvas:
1222
+ def CanvasOverlay(top_c: CompositeCanvas, bottom_c: Canvas, left: int, top: int) -> CompositeCanvas:
1221
1223
  """
1222
1224
  Overlay canvas top_c onto bottom_c at position (left, top).
1223
1225
  """
@@ -97,6 +97,6 @@ def lazy_import(name: str, package: str | None = None) -> types.ModuleType:
97
97
  return module
98
98
 
99
99
 
100
- html_fragment = lazy_import(".html_fragment", __package__)
101
- lcd = lazy_import(".lcd", __package__)
102
- web = lazy_import(".web", __package__)
100
+ html_fragment = lazy_import(".html_fragment", "urwid.display")
101
+ lcd = lazy_import(".lcd", "urwid.display")
102
+ web = lazy_import(".web", "urwid.display")
@@ -43,18 +43,19 @@ from . import _raw_display_base, escape
43
43
  from .common import INPUT_DESCRIPTORS_CHANGED
44
44
 
45
45
  if typing.TYPE_CHECKING:
46
- import socket
47
46
  from collections.abc import Callable
48
47
  from types import FrameType
49
48
 
50
49
  from urwid.event_loop import EventLoop
51
50
 
51
+ SignalHandler = Callable[[int, FrameType | None], typing.Any] | int | None # pylint: disable=unsupported-binary-operation
52
+
52
53
 
53
54
  class Screen(_raw_display_base.Screen):
54
55
  def __init__(
55
56
  self,
56
- input: typing.TextIO = sys.stdin, # noqa: A002 # pylint: disable=redefined-builtin
57
- output: typing.TextIO = sys.stdout,
57
+ input: _raw_display_base.SupportsFileno = sys.stdin, # noqa: A002 # pylint: disable=redefined-builtin
58
+ output: _raw_display_base.TextWriter = sys.stdout,
58
59
  bracketed_paste_mode=False,
59
60
  focus_reporting=False,
60
61
  ) -> None:
@@ -75,9 +76,9 @@ class Screen(_raw_display_base.Screen):
75
76
  self.focus_reporting = focus_reporting
76
77
 
77
78
  # These store the previous signal handlers after setting ours
78
- self._prev_sigcont_handler = None
79
- self._prev_sigtstp_handler = None
80
- self._prev_sigwinch_handler = None
79
+ self._prev_sigcont_handler: SignalHandler = None
80
+ self._prev_sigtstp_handler: SignalHandler = None
81
+ self._prev_sigwinch_handler: SignalHandler = None
81
82
 
82
83
  def __repr__(self) -> str:
83
84
  return (
@@ -161,6 +162,8 @@ class Screen(_raw_display_base.Screen):
161
162
  close_fds=True,
162
163
  encoding="ascii",
163
164
  )
165
+ if m.stdout is None:
166
+ raise RuntimeError("gpm mouse tracking stdout was not created")
164
167
  fcntl.fcntl(m.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
165
168
  self.gpm_mev = m
166
169
 
@@ -205,7 +208,7 @@ class Screen(_raw_display_base.Screen):
205
208
  # restore mouse tracking to previous state
206
209
  self._mouse_tracking(self._mouse_tracking_enabled)
207
210
 
208
- return super()._start()
211
+ super()._start()
209
212
 
210
213
  def _stop(self) -> None:
211
214
  """
@@ -234,7 +237,7 @@ class Screen(_raw_display_base.Screen):
234
237
 
235
238
  super()._stop()
236
239
 
237
- def get_input_descriptors(self) -> list[socket.socket | typing.IO | int]:
240
+ def get_input_descriptors(self) -> list[_raw_display_base.SupportsFileno | int]:
238
241
  """
239
242
  Return a list of integer file descriptors that should be
240
243
  polled in external event loops to check for user input.
@@ -292,9 +295,11 @@ class Screen(_raw_display_base.Screen):
292
295
  return super()._get_input_codes() + self._get_gpm_codes()
293
296
 
294
297
  def _get_gpm_codes(self) -> list[int]:
295
- codes = []
298
+ codes: list[int] = []
296
299
  try:
297
300
  while self.gpm_mev is not None and self.gpm_event_pending:
301
+ if self.gpm_mev.stdout is None:
302
+ return codes
298
303
  codes.extend(self._encode_gpm_event())
299
304
  except OSError as e:
300
305
  if e.args[0] != 11:
@@ -303,7 +308,8 @@ class Screen(_raw_display_base.Screen):
303
308
 
304
309
  def _read_raw_input(self, timeout: int) -> bytearray:
305
310
  ready = self._wait_for_input_ready(timeout)
306
- if self.gpm_mev is not None and self.gpm_mev.stdout.fileno() in ready:
311
+ gpm_stdout = self.gpm_mev.stdout if self.gpm_mev is not None else None
312
+ if gpm_stdout is not None and gpm_stdout.fileno() in ready:
307
313
  self.gpm_event_pending = True
308
314
  fd = self._input_fileno()
309
315
  chars = bytearray()
@@ -325,6 +331,9 @@ class Screen(_raw_display_base.Screen):
325
331
 
326
332
  def _encode_gpm_event(self) -> list[int]:
327
333
  self.gpm_event_pending = False
334
+ if self.gpm_mev is None or self.gpm_mev.stdout is None:
335
+ return []
336
+
328
337
  s = self.gpm_mev.stdout.readline()
329
338
  result = s.split(", ")
330
339
  if len(result) != 6:
@@ -405,7 +414,7 @@ class Screen(_raw_display_base.Screen):
405
414
  """Return the terminal dimensions (num columns, num rows)."""
406
415
  y, x = super().get_cols_rows()
407
416
  with contextlib.suppress(OSError): # Term size could not be determined
408
- if hasattr(self._term_output_file, "fileno"):
417
+ if isinstance(self._term_output_file, _raw_display_base.SupportsFileno):
409
418
  buf = fcntl.ioctl(self._term_output_file.fileno(), termios.TIOCGWINSZ, b" " * 8)
410
419
  y, x, _, _ = struct.unpack("hhhh", buf)
411
420