urwid 2.6.9__tar.gz → 2.6.11__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.

Potentially problematic release.


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

Files changed (331) hide show
  1. urwid-2.6.11/.editorconfig +22 -0
  2. {urwid-2.6.9 → urwid-2.6.11}/PKG-INFO +1 -1
  3. urwid-2.6.11/black-requirements.txt +1 -0
  4. urwid-2.6.11/docs/examples/bigtext.py.xdotool +3 -0
  5. urwid-2.6.11/docs/examples/bigtext1.png +0 -0
  6. urwid-2.6.11/docs/examples/bigtext2.png +0 -0
  7. urwid-2.6.11/docs/examples/bigtext3.png +0 -0
  8. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/browse.py +1 -1
  9. urwid-2.6.11/docs/examples/edit1.png +0 -0
  10. urwid-2.6.11/docs/examples/edit2.png +0 -0
  11. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/graph.py +26 -4
  12. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/real_browse.py +10 -3
  13. urwid-2.6.11/docs/examples/tour.py.xdotool +2 -0
  14. urwid-2.6.11/docs/examples/tour1.png +0 -0
  15. urwid-2.6.11/docs/examples/tour2.png +0 -0
  16. urwid-2.6.11/docs/tutorial/hmenu1.png +0 -0
  17. urwid-2.6.11/docs/tutorial/hmenu2.png +0 -0
  18. urwid-2.6.11/docs/tutorial/hmenu3.png +0 -0
  19. urwid-2.6.11/docs/tutorial/hmenu4.png +0 -0
  20. {urwid-2.6.9 → urwid-2.6.11}/examples/browse.py +10 -3
  21. {urwid-2.6.9 → urwid-2.6.11}/examples/dialog.py +2 -2
  22. {urwid-2.6.9 → urwid-2.6.11}/examples/graph.py +26 -4
  23. {urwid-2.6.9 → urwid-2.6.11}/pyproject.toml +4 -4
  24. urwid-2.6.11/ruff-requirements.txt +1 -0
  25. {urwid-2.6.9 → urwid-2.6.11}/tests/test_scrollable.py +57 -4
  26. {urwid-2.6.9 → urwid-2.6.11}/tox.ini +10 -10
  27. {urwid-2.6.9 → urwid-2.6.11}/urwid/version.py +2 -2
  28. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/listbox.py +25 -5
  29. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/monitored_list.py +65 -19
  30. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/padding.py +4 -2
  31. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/popup.py +16 -13
  32. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/scrollable.py +22 -10
  33. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/widget.py +1 -1
  34. {urwid-2.6.9 → urwid-2.6.11}/urwid.egg-info/PKG-INFO +1 -1
  35. {urwid-2.6.9 → urwid-2.6.11}/urwid.egg-info/SOURCES.txt +1 -0
  36. urwid-2.6.9/black-requirements.txt +0 -1
  37. urwid-2.6.9/docs/examples/bigtext.py.xdotool +0 -3
  38. urwid-2.6.9/docs/examples/bigtext1.png +0 -0
  39. urwid-2.6.9/docs/examples/bigtext2.png +0 -0
  40. urwid-2.6.9/docs/examples/bigtext3.png +0 -0
  41. urwid-2.6.9/docs/examples/edit1.png +0 -0
  42. urwid-2.6.9/docs/examples/edit2.png +0 -0
  43. urwid-2.6.9/docs/examples/tour.py.xdotool +0 -2
  44. urwid-2.6.9/docs/examples/tour1.png +0 -0
  45. urwid-2.6.9/docs/examples/tour2.png +0 -0
  46. urwid-2.6.9/docs/tutorial/hmenu1.png +0 -0
  47. urwid-2.6.9/docs/tutorial/hmenu2.png +0 -0
  48. urwid-2.6.9/docs/tutorial/hmenu3.png +0 -0
  49. urwid-2.6.9/docs/tutorial/hmenu4.png +0 -0
  50. urwid-2.6.9/ruff-requirements.txt +0 -1
  51. {urwid-2.6.9 → urwid-2.6.11}/.coveralls.yml +0 -0
  52. {urwid-2.6.9 → urwid-2.6.11}/.devcontainer/dev.dockerfile +0 -0
  53. {urwid-2.6.9 → urwid-2.6.11}/.devcontainer/devcontainer.json +0 -0
  54. {urwid-2.6.9 → urwid-2.6.11}/.dockerignore +0 -0
  55. {urwid-2.6.9 → urwid-2.6.11}/.github/CODE_OF_CONDUCT.md +0 -0
  56. {urwid-2.6.9 → urwid-2.6.11}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  57. {urwid-2.6.9 → urwid-2.6.11}/.github/ISSUE_TEMPLATE/docs.md +0 -0
  58. {urwid-2.6.9 → urwid-2.6.11}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  59. {urwid-2.6.9 → urwid-2.6.11}/.github/ISSUE_TEMPLATE/question.md +0 -0
  60. {urwid-2.6.9 → urwid-2.6.11}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  61. {urwid-2.6.9 → urwid-2.6.11}/.github/dependabot.yml +0 -0
  62. {urwid-2.6.9 → urwid-2.6.11}/.github/labeler.yml +0 -0
  63. {urwid-2.6.9 → urwid-2.6.11}/.github/release.yml +0 -0
  64. {urwid-2.6.9 → urwid-2.6.11}/.github/workflows/documentation.yml +0 -0
  65. {urwid-2.6.9 → urwid-2.6.11}/.github/workflows/isolated_static_check.yml +0 -0
  66. {urwid-2.6.9 → urwid-2.6.11}/.github/workflows/labels.yml +0 -0
  67. {urwid-2.6.9 → urwid-2.6.11}/.github/workflows/pythonpackage.yml +0 -0
  68. {urwid-2.6.9 → urwid-2.6.11}/.github/workflows/yamllint.yml +0 -0
  69. {urwid-2.6.9 → urwid-2.6.11}/.gitignore +0 -0
  70. {urwid-2.6.9 → urwid-2.6.11}/.pre-commit-config.yaml +0 -0
  71. {urwid-2.6.9 → urwid-2.6.11}/.yamllint.yml +0 -0
  72. {urwid-2.6.9 → urwid-2.6.11}/COPYING +0 -0
  73. {urwid-2.6.9 → urwid-2.6.11}/MANIFEST.in +0 -0
  74. {urwid-2.6.9 → urwid-2.6.11}/README.rst +0 -0
  75. {urwid-2.6.9 → urwid-2.6.11}/classifiers.txt +0 -0
  76. {urwid-2.6.9 → urwid-2.6.11}/docs/Makefile +0 -0
  77. {urwid-2.6.9 → urwid-2.6.11}/docs/changelog.rst +0 -0
  78. {urwid-2.6.9 → urwid-2.6.11}/docs/conf.py +0 -0
  79. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/bigtext.py +0 -0
  80. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/browse.py.xdotool +0 -0
  81. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/browse1.png +0 -0
  82. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/browse2.png +0 -0
  83. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/edit.py +0 -0
  84. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/edit.py.xdotool +0 -0
  85. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/edit_text.txt +0 -0
  86. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/graph.py.xdotool +0 -0
  87. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/graph1.png +0 -0
  88. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/graph2.png +0 -0
  89. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/index.rst +0 -0
  90. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/palette_test.py +0 -0
  91. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/palette_test.py.xdotool +0 -0
  92. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/palette_test1.png +0 -0
  93. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/palette_test2.png +0 -0
  94. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/pop_up.py +0 -0
  95. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/pop_up.py.xdotool +0 -0
  96. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/pop_up1.png +0 -0
  97. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/pop_up2.png +0 -0
  98. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/real_edit.py +0 -0
  99. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/subproc.py +0 -0
  100. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/subproc.py.xdotool +0 -0
  101. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/subproc1.png +0 -0
  102. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/subproc2.png +0 -0
  103. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/subproc2.py +0 -0
  104. {urwid-2.6.9 → urwid-2.6.11}/docs/examples/tour.py +0 -0
  105. {urwid-2.6.9 → urwid-2.6.11}/docs/index.rst +0 -0
  106. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/bright_combinations.py +0 -0
  107. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/bright_combinations.py.xdotool +0 -0
  108. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/bright_combinations1.png +0 -0
  109. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/canvascache.rst +0 -0
  110. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/displayattributes.rst +0 -0
  111. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/displaymodules.rst +0 -0
  112. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/encodings.rst +0 -0
  113. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/images/display_modules.png +0 -0
  114. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/images/introduction.png +0 -0
  115. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/images/urwid_widgets.svgz +0 -0
  116. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/images/urwid_widgets_1.png +0 -0
  117. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/images/urwid_widgets_1.xcf +0 -0
  118. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/images/urwid_widgets_2.png +0 -0
  119. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/images/urwid_widgets_2.xcf +0 -0
  120. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/images/widget_layout.png +0 -0
  121. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/index.rst +0 -0
  122. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/mainloop.rst +0 -0
  123. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/overview.rst +0 -0
  124. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/safe_combinations.py +0 -0
  125. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/safe_combinations.py.xdotool +0 -0
  126. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/safe_combinations1.png +0 -0
  127. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/textlayout.rst +0 -0
  128. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/userinput.rst +0 -0
  129. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/wanat.py +0 -0
  130. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/wanat_multi.py +0 -0
  131. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/wcur1.py +0 -0
  132. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/wcur2.py +0 -0
  133. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/widgets.rst +0 -0
  134. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/wmod.py +0 -0
  135. {urwid-2.6.9 → urwid-2.6.11}/docs/manual/wsel.py +0 -0
  136. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/attrspec.rst +0 -0
  137. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/canvas.rst +0 -0
  138. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/command_map.rst +0 -0
  139. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/constants.rst +0 -0
  140. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/deprecated.rst +0 -0
  141. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/display_modules.rst +0 -0
  142. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/exceptions.rst +0 -0
  143. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/global_settings.rst +0 -0
  144. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/index.rst +0 -0
  145. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/list_walkers.rst +0 -0
  146. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/main_loop.rst +0 -0
  147. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/meta.rst +0 -0
  148. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/signals.rst +0 -0
  149. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/text_layout.rst +0 -0
  150. {urwid-2.6.9 → urwid-2.6.11}/docs/reference/widget.rst +0 -0
  151. {urwid-2.6.9 → urwid-2.6.11}/docs/tools/compile_pngs.sh +0 -0
  152. {urwid-2.6.9 → urwid-2.6.11}/docs/tools/screenshots.sh +0 -0
  153. {urwid-2.6.9 → urwid-2.6.11}/docs/tools/static/.placeholder +0 -0
  154. {urwid-2.6.9 → urwid-2.6.11}/docs/tools/templates/indexcontent.html +0 -0
  155. {urwid-2.6.9 → urwid-2.6.11}/docs/tools/templates/indexsidebar.html +0 -0
  156. {urwid-2.6.9 → urwid-2.6.11}/docs/tools/templates/localtoc.html +0 -0
  157. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/adventure.py +0 -0
  158. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/adventure.py.xdotool +0 -0
  159. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/adventure1.png +0 -0
  160. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/adventure2.png +0 -0
  161. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/adventure3.png +0 -0
  162. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/adventure4.png +0 -0
  163. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/cmenu.py +0 -0
  164. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/cmenu.py.xdotool +0 -0
  165. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/cmenu1.png +0 -0
  166. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/cmenu2.png +0 -0
  167. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/cmenu3.png +0 -0
  168. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/cmenu4.png +0 -0
  169. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/highcolors.py +0 -0
  170. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/highcolors.py.xdotool +0 -0
  171. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/highcolors1.png +0 -0
  172. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/hmenu.py +0 -0
  173. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/hmenu.py.xdotool +0 -0
  174. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/index.rst +0 -0
  175. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/input.py +0 -0
  176. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/input.py.xdotool +0 -0
  177. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/input1.png +0 -0
  178. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/input2.png +0 -0
  179. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/input3.png +0 -0
  180. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/input4.png +0 -0
  181. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/input5.png +0 -0
  182. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/menu25.png +0 -0
  183. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/minimal.py +0 -0
  184. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/minimal.py.xdotool +0 -0
  185. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/minimal1.png +0 -0
  186. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/multiple.py +0 -0
  187. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/multiple.py.xdotool +0 -0
  188. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/multiple1.png +0 -0
  189. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/multiple2.png +0 -0
  190. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/multiple3.png +0 -0
  191. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/multiple4.png +0 -0
  192. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/qa.py +0 -0
  193. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/qa.py.xdotool +0 -0
  194. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/qa1.png +0 -0
  195. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/qa2.png +0 -0
  196. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/qa3.png +0 -0
  197. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/sig.py +0 -0
  198. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/sig.py.xdotool +0 -0
  199. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/sig1.png +0 -0
  200. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/sig2.png +0 -0
  201. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/sig3.png +0 -0
  202. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/sig4.png +0 -0
  203. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/smenu.py +0 -0
  204. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/smenu.py.xdotool +0 -0
  205. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/smenu1.png +0 -0
  206. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/smenu2.png +0 -0
  207. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/smenu3.png +0 -0
  208. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/urwid_attr.py +0 -0
  209. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/urwid_attr.py.xdotool +0 -0
  210. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/urwid_attr1.png +0 -0
  211. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/urwid_attr2.png +0 -0
  212. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/urwid_attr3.png +0 -0
  213. {urwid-2.6.9 → urwid-2.6.11}/docs/tutorial/urwid_attr4.png +0 -0
  214. {urwid-2.6.9 → urwid-2.6.11}/docs/urwid-logo.png +0 -0
  215. {urwid-2.6.9 → urwid-2.6.11}/examples/asyncio_socket_server.py +0 -0
  216. {urwid-2.6.9 → urwid-2.6.11}/examples/bigtext.py +0 -0
  217. {urwid-2.6.9 → urwid-2.6.11}/examples/calc.py +0 -0
  218. {urwid-2.6.9 → urwid-2.6.11}/examples/edit.py +0 -0
  219. {urwid-2.6.9 → urwid-2.6.11}/examples/fib.py +0 -0
  220. {urwid-2.6.9 → urwid-2.6.11}/examples/input_test.py +0 -0
  221. {urwid-2.6.9 → urwid-2.6.11}/examples/lcd_cf635.py +0 -0
  222. {urwid-2.6.9 → urwid-2.6.11}/examples/palette_test.py +0 -0
  223. {urwid-2.6.9 → urwid-2.6.11}/examples/pop_up.py +0 -0
  224. {urwid-2.6.9 → urwid-2.6.11}/examples/subproc.py +0 -0
  225. {urwid-2.6.9 → urwid-2.6.11}/examples/subproc2.py +0 -0
  226. {urwid-2.6.9 → urwid-2.6.11}/examples/terminal.py +0 -0
  227. {urwid-2.6.9 → urwid-2.6.11}/examples/tour.py +0 -0
  228. {urwid-2.6.9 → urwid-2.6.11}/examples/treesample.py +0 -0
  229. {urwid-2.6.9 → urwid-2.6.11}/examples/twisted_serve_ssh.py +0 -0
  230. {urwid-2.6.9 → urwid-2.6.11}/examples/twisted_serve_ssh.tac +0 -0
  231. {urwid-2.6.9 → urwid-2.6.11}/isort-requirements.txt +0 -0
  232. {urwid-2.6.9 → urwid-2.6.11}/pylint-requirements.txt +0 -0
  233. {urwid-2.6.9 → urwid-2.6.11}/requirements.txt +0 -0
  234. {urwid-2.6.9 → urwid-2.6.11}/setup.cfg +0 -0
  235. {urwid-2.6.9 → urwid-2.6.11}/setup.py +0 -0
  236. {urwid-2.6.9 → urwid-2.6.11}/test_requirements.txt +0 -0
  237. {urwid-2.6.9 → urwid-2.6.11}/tests/__init__.py +0 -0
  238. {urwid-2.6.9 → urwid-2.6.11}/tests/test_canvas.py +0 -0
  239. {urwid-2.6.9 → urwid-2.6.11}/tests/test_columns.py +0 -0
  240. {urwid-2.6.9 → urwid-2.6.11}/tests/test_container.py +0 -0
  241. {urwid-2.6.9 → urwid-2.6.11}/tests/test_doctests.py +0 -0
  242. {urwid-2.6.9 → urwid-2.6.11}/tests/test_escapes.py +0 -0
  243. {urwid-2.6.9 → urwid-2.6.11}/tests/test_event_loops.py +0 -0
  244. {urwid-2.6.9 → urwid-2.6.11}/tests/test_filler.py +0 -0
  245. {urwid-2.6.9 → urwid-2.6.11}/tests/test_floatedit.py +0 -0
  246. {urwid-2.6.9 → urwid-2.6.11}/tests/test_font.py +0 -0
  247. {urwid-2.6.9 → urwid-2.6.11}/tests/test_frame.py +0 -0
  248. {urwid-2.6.9 → urwid-2.6.11}/tests/test_graphics.py +0 -0
  249. {urwid-2.6.9 → urwid-2.6.11}/tests/test_grid_flow.py +0 -0
  250. {urwid-2.6.9 → urwid-2.6.11}/tests/test_line_box.py +0 -0
  251. {urwid-2.6.9 → urwid-2.6.11}/tests/test_listbox.py +0 -0
  252. {urwid-2.6.9 → urwid-2.6.11}/tests/test_main_loop.py +0 -0
  253. {urwid-2.6.9 → urwid-2.6.11}/tests/test_moved_imports.py +0 -0
  254. {urwid-2.6.9 → urwid-2.6.11}/tests/test_overlay.py +0 -0
  255. {urwid-2.6.9 → urwid-2.6.11}/tests/test_padding.py +0 -0
  256. {urwid-2.6.9 → urwid-2.6.11}/tests/test_pile.py +0 -0
  257. {urwid-2.6.9 → urwid-2.6.11}/tests/test_raw_display.py +0 -0
  258. {urwid-2.6.9 → urwid-2.6.11}/tests/test_signals.py +0 -0
  259. {urwid-2.6.9 → urwid-2.6.11}/tests/test_str_util.py +0 -0
  260. {urwid-2.6.9 → urwid-2.6.11}/tests/test_text_layout.py +0 -0
  261. {urwid-2.6.9 → urwid-2.6.11}/tests/test_tree.py +0 -0
  262. {urwid-2.6.9 → urwid-2.6.11}/tests/test_util.py +0 -0
  263. {urwid-2.6.9 → urwid-2.6.11}/tests/test_vterm.py +0 -0
  264. {urwid-2.6.9 → urwid-2.6.11}/tests/test_widget.py +0 -0
  265. {urwid-2.6.9 → urwid-2.6.11}/tests/util.py +0 -0
  266. {urwid-2.6.9 → urwid-2.6.11}/urwid/__init__.py +0 -0
  267. {urwid-2.6.9 → urwid-2.6.11}/urwid/canvas.py +0 -0
  268. {urwid-2.6.9 → urwid-2.6.11}/urwid/command_map.py +0 -0
  269. {urwid-2.6.9 → urwid-2.6.11}/urwid/container.py +0 -0
  270. {urwid-2.6.9 → urwid-2.6.11}/urwid/decoration.py +0 -0
  271. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/__init__.py +0 -0
  272. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/_posix_raw_display.py +0 -0
  273. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/_raw_display_base.py +0 -0
  274. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/_web.css +0 -0
  275. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/_web.js +0 -0
  276. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/_win32.py +0 -0
  277. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/_win32_raw_display.py +0 -0
  278. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/common.py +0 -0
  279. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/curses.py +0 -0
  280. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/escape.py +0 -0
  281. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/html_fragment.py +0 -0
  282. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/lcd.py +0 -0
  283. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/raw.py +0 -0
  284. {urwid-2.6.9 → urwid-2.6.11}/urwid/display/web.py +0 -0
  285. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/__init__.py +0 -0
  286. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/abstract_loop.py +0 -0
  287. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/asyncio_loop.py +0 -0
  288. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/glib_loop.py +0 -0
  289. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/main_loop.py +0 -0
  290. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/select_loop.py +0 -0
  291. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/tornado_loop.py +0 -0
  292. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/trio_loop.py +0 -0
  293. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/twisted_loop.py +0 -0
  294. {urwid-2.6.9 → urwid-2.6.11}/urwid/event_loop/zmq_loop.py +0 -0
  295. {urwid-2.6.9 → urwid-2.6.11}/urwid/font.py +0 -0
  296. {urwid-2.6.9 → urwid-2.6.11}/urwid/graphics.py +0 -0
  297. {urwid-2.6.9 → urwid-2.6.11}/urwid/numedit.py +0 -0
  298. {urwid-2.6.9 → urwid-2.6.11}/urwid/signals.py +0 -0
  299. {urwid-2.6.9 → urwid-2.6.11}/urwid/split_repr.py +0 -0
  300. {urwid-2.6.9 → urwid-2.6.11}/urwid/str_util.py +0 -0
  301. {urwid-2.6.9 → urwid-2.6.11}/urwid/text_layout.py +0 -0
  302. {urwid-2.6.9 → urwid-2.6.11}/urwid/util.py +0 -0
  303. {urwid-2.6.9 → urwid-2.6.11}/urwid/vterm.py +0 -0
  304. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/__init__.py +0 -0
  305. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/attr_map.py +0 -0
  306. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/attr_wrap.py +0 -0
  307. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/bar_graph.py +0 -0
  308. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/big_text.py +0 -0
  309. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/box_adapter.py +0 -0
  310. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/columns.py +0 -0
  311. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/constants.py +0 -0
  312. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/container.py +0 -0
  313. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/divider.py +0 -0
  314. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/edit.py +0 -0
  315. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/filler.py +0 -0
  316. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/frame.py +0 -0
  317. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/grid_flow.py +0 -0
  318. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/line_box.py +0 -0
  319. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/overlay.py +0 -0
  320. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/pile.py +0 -0
  321. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/progress_bar.py +0 -0
  322. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/solid_fill.py +0 -0
  323. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/text.py +0 -0
  324. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/treetools.py +0 -0
  325. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/widget_decoration.py +0 -0
  326. {urwid-2.6.9 → urwid-2.6.11}/urwid/widget/wimp.py +0 -0
  327. {urwid-2.6.9 → urwid-2.6.11}/urwid/wimp.py +0 -0
  328. {urwid-2.6.9 → urwid-2.6.11}/urwid.egg-info/dependency_links.txt +0 -0
  329. {urwid-2.6.9 → urwid-2.6.11}/urwid.egg-info/not-zip-safe +0 -0
  330. {urwid-2.6.9 → urwid-2.6.11}/urwid.egg-info/requires.txt +0 -0
  331. {urwid-2.6.9 → urwid-2.6.11}/urwid.egg-info/top_level.txt +0 -0
@@ -0,0 +1,22 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ indent_style = space
7
+ insert_final_newline = true
8
+ trim_trailing_whitespace = true
9
+
10
+ [*.{py,pyi,pyx,pxd}]
11
+ indent_size = 4
12
+ max_line_length = 120
13
+
14
+ [*.{yml,yaml,json,ini,toml}]
15
+ indent_size = 2
16
+ max_line_length = 120
17
+
18
+ [*.{rst,md}]
19
+ indent_size = 2
20
+
21
+ [{Makefile,Makefile.in}]
22
+ indent_style = tab
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: urwid
3
- Version: 2.6.9
3
+ Version: 2.6.11
4
4
  Summary: A full-featured console (xterm et al.) user interface library
5
5
  Home-page: https://urwid.org/
6
6
  Author-email: Ian Ward <ian@excess.org>
@@ -0,0 +1 @@
1
+ black==24.4.0
@@ -0,0 +1,3 @@
1
+ windowsize --usehints $RXVTWINDOWID 39 21
2
+ key --window $RXVTWINDOWID Down Down Down Down Down Down Down Down Return
3
+ key --window $RXVTWINDOWID Up Up Up Return
Binary file
Binary file
Binary file
@@ -6,5 +6,5 @@ import os
6
6
 
7
7
  import real_browse
8
8
 
9
- os.chdir("/usr/share/doc/python")
9
+ os.chdir("/usr/share/doc/python3")
10
10
  real_browse.main()
Binary file
Binary file
@@ -209,8 +209,30 @@ class GraphView(urwid.WidgetWrap):
209
209
  bg = urwid.AttrMap(urwid.SolidFill("▒"), "screen edge")
210
210
  shadow = urwid.AttrMap(urwid.SolidFill(" "), "main shadow")
211
211
 
212
- bg = urwid.Overlay(shadow, bg, ("fixed left", 3), ("fixed right", 1), ("fixed top", 2), ("fixed bottom", 1))
213
- w = urwid.Overlay(w, bg, ("fixed left", 2), ("fixed right", 3), ("fixed top", 1), ("fixed bottom", 2))
212
+ bg = urwid.Overlay(
213
+ shadow,
214
+ bg,
215
+ align=urwid.LEFT,
216
+ width=urwid.RELATIVE_100,
217
+ valign=urwid.TOP,
218
+ height=urwid.RELATIVE_100,
219
+ left=3,
220
+ right=1,
221
+ top=2,
222
+ bottom=1,
223
+ )
224
+ w = urwid.Overlay(
225
+ w,
226
+ bg,
227
+ align=urwid.LEFT,
228
+ width=urwid.RELATIVE_100,
229
+ valign=urwid.TOP,
230
+ height=urwid.RELATIVE_100,
231
+ left=2,
232
+ right=3,
233
+ top=1,
234
+ bottom=2,
235
+ )
214
236
  return w
215
237
 
216
238
  def bar_graph(self, smooth=False):
@@ -288,10 +310,10 @@ class GraphView(urwid.WidgetWrap):
288
310
  def main_window(self):
289
311
  self.graph = self.bar_graph()
290
312
  self.graph_wrap = urwid.WidgetWrap(self.graph)
291
- vline = urwid.AttrMap(urwid.SolidFill("\u2502"), "line")
313
+ vline = urwid.AttrMap(urwid.SolidFill(""), "line")
292
314
  c = self.graph_controls()
293
315
  w = urwid.Columns([(urwid.WEIGHT, 2, self.graph_wrap), (1, vline), c], dividechars=1, focus_column=2)
294
- w = urwid.Padding(w, ("fixed left", 1), ("fixed right", 0))
316
+ w = urwid.Padding(w, urwid.LEFT, left=1)
295
317
  w = urwid.AttrMap(w, "body")
296
318
  w = urwid.LineBox(w)
297
319
  w = urwid.AttrMap(w, "line")
@@ -274,7 +274,14 @@ class DirectoryBrowser:
274
274
  self.listbox.offset_rows = 1
275
275
  self.footer = urwid.AttrMap(urwid.Text(self.footer_text), "foot")
276
276
  self.view = urwid.Frame(
277
- urwid.AttrMap(urwid.ScrollBar(self.listbox), "body"),
277
+ urwid.AttrMap(
278
+ urwid.ScrollBar(
279
+ self.listbox,
280
+ thumb_char=urwid.ScrollBar.Symbols.FULL_BLOCK,
281
+ trough_char=urwid.ScrollBar.Symbols.LITE_SHADE,
282
+ ),
283
+ "body",
284
+ ),
278
285
  header=urwid.AttrMap(self.header, "head"),
279
286
  footer=self.footer,
280
287
  )
@@ -379,9 +386,9 @@ def escape_filename_sh_ansic(name: str) -> str:
379
386
  SPLIT_RE = re.compile(r"[a-zA-Z]+|\d+")
380
387
 
381
388
 
382
- def alphabetize(s):
389
+ def alphabetize(s: str) -> list[str]:
383
390
  L = []
384
- for isdigit, group in itertools.groupby(SPLIT_RE.findall(s), key=lambda x: x.isdigit()):
391
+ for isdigit, group in itertools.groupby(SPLIT_RE.findall(s), key=str.isdigit):
385
392
  if isdigit:
386
393
  L.extend(("", int(n)) for n in group)
387
394
  else:
@@ -0,0 +1,2 @@
1
+ windowsize --usehints $RXVTWINDOWID 39 25
2
+ key --window $RXVTWINDOWID Return End
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -274,7 +274,14 @@ class DirectoryBrowser:
274
274
  self.listbox.offset_rows = 1
275
275
  self.footer = urwid.AttrMap(urwid.Text(self.footer_text), "foot")
276
276
  self.view = urwid.Frame(
277
- urwid.AttrMap(urwid.ScrollBar(self.listbox), "body"),
277
+ urwid.AttrMap(
278
+ urwid.ScrollBar(
279
+ self.listbox,
280
+ thumb_char=urwid.ScrollBar.Symbols.FULL_BLOCK,
281
+ trough_char=urwid.ScrollBar.Symbols.LITE_SHADE,
282
+ ),
283
+ "body",
284
+ ),
278
285
  header=urwid.AttrMap(self.header, "head"),
279
286
  footer=self.footer,
280
287
  )
@@ -379,9 +386,9 @@ def escape_filename_sh_ansic(name: str) -> str:
379
386
  SPLIT_RE = re.compile(r"[a-zA-Z]+|\d+")
380
387
 
381
388
 
382
- def alphabetize(s):
389
+ def alphabetize(s: str) -> list[str]:
383
390
  L = []
384
- for isdigit, group in itertools.groupby(SPLIT_RE.findall(s), key=lambda x: x.isdigit()):
391
+ for isdigit, group in itertools.groupby(SPLIT_RE.findall(s), key=str.isdigit):
385
392
  if isdigit:
386
393
  L.extend(("", int(n)) for n in group)
387
394
  else:
@@ -68,8 +68,8 @@ class DialogDisplay:
68
68
  w = self.frame
69
69
 
70
70
  # pad area around listbox
71
- w = urwid.Padding(w, ("fixed left", 2), ("fixed right", 2))
72
- w = urwid.Filler(w, ("fixed top", 1), ("fixed bottom", 1))
71
+ w = urwid.Padding(w, urwid.LEFT, left=2, right=2)
72
+ w = urwid.Filler(w, urwid.TOP, urwid.RELATIVE_100, top=1, bottom=1)
73
73
  w = urwid.AttrMap(w, "body")
74
74
 
75
75
  # "shadow" effect
@@ -209,8 +209,30 @@ class GraphView(urwid.WidgetWrap):
209
209
  bg = urwid.AttrMap(urwid.SolidFill("▒"), "screen edge")
210
210
  shadow = urwid.AttrMap(urwid.SolidFill(" "), "main shadow")
211
211
 
212
- bg = urwid.Overlay(shadow, bg, ("fixed left", 3), ("fixed right", 1), ("fixed top", 2), ("fixed bottom", 1))
213
- w = urwid.Overlay(w, bg, ("fixed left", 2), ("fixed right", 3), ("fixed top", 1), ("fixed bottom", 2))
212
+ bg = urwid.Overlay(
213
+ shadow,
214
+ bg,
215
+ align=urwid.LEFT,
216
+ width=urwid.RELATIVE_100,
217
+ valign=urwid.TOP,
218
+ height=urwid.RELATIVE_100,
219
+ left=3,
220
+ right=1,
221
+ top=2,
222
+ bottom=1,
223
+ )
224
+ w = urwid.Overlay(
225
+ w,
226
+ bg,
227
+ align=urwid.LEFT,
228
+ width=urwid.RELATIVE_100,
229
+ valign=urwid.TOP,
230
+ height=urwid.RELATIVE_100,
231
+ left=2,
232
+ right=3,
233
+ top=1,
234
+ bottom=2,
235
+ )
214
236
  return w
215
237
 
216
238
  def bar_graph(self, smooth=False):
@@ -288,10 +310,10 @@ class GraphView(urwid.WidgetWrap):
288
310
  def main_window(self):
289
311
  self.graph = self.bar_graph()
290
312
  self.graph_wrap = urwid.WidgetWrap(self.graph)
291
- vline = urwid.AttrMap(urwid.SolidFill("\u2502"), "line")
313
+ vline = urwid.AttrMap(urwid.SolidFill(""), "line")
292
314
  c = self.graph_controls()
293
315
  w = urwid.Columns([(urwid.WEIGHT, 2, self.graph_wrap), (1, vline), c], dividechars=1, focus_column=2)
294
- w = urwid.Padding(w, ("fixed left", 1), ("fixed right", 0))
316
+ w = urwid.Padding(w, urwid.LEFT, left=1)
295
317
  w = urwid.AttrMap(w, "body")
296
318
  w = urwid.LineBox(w)
297
319
  w = urwid.AttrMap(w, "line")
@@ -2,9 +2,9 @@
2
2
  # Minimum requirements for the build system to execute.
3
3
  # PEP 508 specifications for PEP 518.
4
4
  requires = [
5
- "setuptools >= 61.0.0",
6
- "setuptools_scm[toml]>=7.0",
7
- "wheel",
5
+ "setuptools >= 61.0.0",
6
+ "setuptools_scm[toml]>=7.0",
7
+ "wheel",
8
8
  ]
9
9
  build-backend="setuptools.build_meta"
10
10
 
@@ -179,7 +179,7 @@ extend-select = [
179
179
  ]
180
180
  extend-ignore = [
181
181
  "PLR6301", "E203",
182
- # refactor rules (too many statements/arguments/branches)
182
+ # refactor rules (too many statements/arguments/branches)
183
183
  "PLR0904", "PLR0911", "PLR0912", "PLR0913", "PLR0914", "PLR0915", "PLR0917", "PLR2004",
184
184
  "PLC0415", # We have a lot of imports outside of top-level
185
185
  "RET504", # Unnecessary variable assignment before return statement
@@ -0,0 +1 @@
1
+ ruff==0.4.1
@@ -1,10 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import string
4
+ import typing
4
5
  import unittest
5
6
 
6
7
  import urwid
7
8
 
9
+ if typing.TYPE_CHECKING:
10
+ from collections.abc import Iterable
11
+
8
12
  LGPL_HEADER = """
9
13
  Copyright (C) <year> <name of author>
10
14
 
@@ -264,15 +268,13 @@ class TestScrollBarListBox(unittest.TestCase):
264
268
 
265
269
  widget.keypress(reduced_size, "end")
266
270
 
267
- # Here we have ListBox issue: "end" really scroll not to the "dead end"
268
- # in case of the bottom focus position is multiline
269
271
  self.assertEqual(
270
272
  (
271
- "GNU Lesser General Public ",
272
273
  "License along with this library; if ",
273
274
  "not, write to the Free Software ",
274
275
  "Foundation, Inc., 51 Franklin Street, ",
275
- "Fifth Floor, Boston, MA 02110-1301",
276
+ "Fifth Floor, Boston, MA 02110-1301 ",
277
+ "USA █",
276
278
  ),
277
279
  widget.render(reduced_size).decoded_text,
278
280
  )
@@ -344,3 +346,54 @@ class TestScrollBarListBox(unittest.TestCase):
344
346
  widget.keypress(reduced_size, "down")
345
347
 
346
348
  self.assertEqual(pos_1_down_rendered, widget.render(reduced_size).decoded_text)
349
+
350
+ def test_hinted_len(self):
351
+ class HintedWalker(urwid.ListWalker):
352
+ def __init__(self, items: Iterable[str]) -> None:
353
+ self.items: tuple[str] = tuple(items)
354
+ self.focus = 0
355
+ self.requested_numbers: set[int] = set()
356
+
357
+ def __length_hint__(self) -> int:
358
+ return len(self.items)
359
+
360
+ def __getitem__(self, item: int) -> urwid.Text:
361
+ self.requested_numbers.add(item)
362
+ return urwid.Text(self.items[item])
363
+
364
+ def set_focus(self, item: int) -> None:
365
+ self.focus = item
366
+
367
+ def next_position(self, position: int) -> int:
368
+ if position + 1 < len(self.items):
369
+ return position + 1
370
+ raise IndexError
371
+
372
+ def prev_position(self, position: int) -> int:
373
+ if position - 1 >= 0:
374
+ return position - 1
375
+ raise IndexError
376
+
377
+ widget = urwid.ScrollBar(urwid.ListBox(HintedWalker((f"Line {idx:02}") for idx in range(1, 51))))
378
+ size = (10, 10)
379
+ widget.original_widget.focus_position = 19
380
+ self.assertEqual(
381
+ (
382
+ "Line 16 ",
383
+ "Line 17 ",
384
+ "Line 18 ",
385
+ "Line 19 █",
386
+ "Line 20 █",
387
+ "Line 21 ",
388
+ "Line 22 ",
389
+ "Line 23 ",
390
+ "Line 24 ",
391
+ "Line 25 ",
392
+ ),
393
+ widget.render(size).decoded_text,
394
+ )
395
+ self.assertNotIn(
396
+ 30,
397
+ widget.original_widget.body.requested_numbers,
398
+ "Requested index out of range [0, last shown]. This means not relative scroll bar built.",
399
+ )
@@ -7,8 +7,8 @@ usedevelop = true
7
7
  deps = -r {toxinidir}/test_requirements.txt
8
8
 
9
9
  commands =
10
- coverage run -m unittest discover -s tests -v
11
- coverage report
10
+ coverage run -m unittest discover -s tests -v
11
+ coverage report
12
12
 
13
13
  [testenv:readme]
14
14
  deps =
@@ -21,7 +21,7 @@ commands =
21
21
  [testenv:isort]
22
22
  skip_install = true
23
23
  deps =
24
- isort
24
+ isort
25
25
  commands =
26
26
  isort .
27
27
 
@@ -41,18 +41,18 @@ commands = ruff check .
41
41
 
42
42
  [testenv:docs]
43
43
  deps =
44
- -r {toxinidir}/test_requirements.txt
45
- PyGObject
46
- sphinx
47
- sphinx-github-changelog
44
+ -r {toxinidir}/test_requirements.txt
45
+ PyGObject
46
+ sphinx
47
+ sphinx-github-changelog
48
48
  commands = sphinx-build docs/ build/documentation
49
49
 
50
50
  [testenv:pylint]
51
51
  depends = black,isort
52
52
  deps =
53
- -r {toxinidir}/test_requirements.txt
54
- PyGObject
55
- pylint
53
+ -r {toxinidir}/test_requirements.txt
54
+ PyGObject
55
+ pylint
56
56
  commands = pylint urwid
57
57
 
58
58
  [testenv:refurb]
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '2.6.9'
16
- __version_tuple__ = version_tuple = (2, 6, 9)
15
+ __version__ = version = '2.6.11'
16
+ __version_tuple__ = version_tuple = (2, 6, 11)
@@ -20,6 +20,7 @@
20
20
 
21
21
  from __future__ import annotations
22
22
 
23
+ import operator
23
24
  import typing
24
25
  import warnings
25
26
  from collections.abc import Iterable, Sized
@@ -77,6 +78,18 @@ class ScrollSupportingBody(Protocol):
77
78
  def get_prev(self, position: _K) -> tuple[Widget, _K] | tuple[None, None]: ...
78
79
 
79
80
 
81
+ @runtime_checkable
82
+ class EstimatedSized(Protocol):
83
+ """Widget can estimate it's size.
84
+
85
+ PEP 424 defines API for memory-efficiency.
86
+ For the ListBox it's a sign of the limited body length.
87
+ The main use-case is lazy-load, where real length calculation is expensive.
88
+ """
89
+
90
+ def __length_hint__(self) -> int: ...
91
+
92
+
80
93
  class ListWalker(metaclass=signals.MetaSignals): # pylint: disable=no-member, unsubscriptable-object
81
94
  # mixin not named as mixin
82
95
  signals: typing.ClassVar[list[str]] = ["modified"]
@@ -431,11 +444,18 @@ class ListBox(Widget, WidgetContainerMixin):
431
444
  )
432
445
  self.body = body
433
446
 
434
- def __len__(self) -> int:
447
+ @property
448
+ def __len__(self) -> Callable[[], int]:
435
449
  if isinstance(self._body, Sized):
436
- return len(self._body)
450
+ return self._body.__len__
437
451
  raise AttributeError(f"{self._body.__class__.__name__} is not Sized")
438
452
 
453
+ @property
454
+ def __length_hint__(self) -> Callable[[], int]: # pylint: disable=invalid-length-hint-returned
455
+ if isinstance(self._body, (Sized, EstimatedSized)):
456
+ return lambda: operator.length_hint(self._body)
457
+ raise AttributeError(f'{self._body.__class__.__name__} is not Sized and do not implement "__length_hint__"')
458
+
439
459
  def calculate_visible(
440
460
  self,
441
461
  size: tuple[int, int],
@@ -577,9 +597,9 @@ class ListBox(Widget, WidgetContainerMixin):
577
597
  if not isinstance(self._body, ScrollSupportingBody):
578
598
  raise ListBoxError(f"{self} body do not implement methods required for scrolling protocol")
579
599
 
580
- if not isinstance(self._body, (Sized, TreeWalker)):
600
+ if not isinstance(self._body, (Sized, EstimatedSized, TreeWalker)):
581
601
  raise ListBoxError(
582
- f"{self} body is not a Sized and not a TreeWalker."
602
+ f"{self} body is not a Sized, can not estimate it's size and not a TreeWalker."
583
603
  f"Scroll is not allowed due to risk of infinite cycle of widgets load."
584
604
  )
585
605
 
@@ -643,7 +663,7 @@ class ListBox(Widget, WidgetContainerMixin):
643
663
 
644
664
  def require_relative_scroll(self, size: tuple[int, int], focus: bool = False) -> bool:
645
665
  """Widget require relative scroll due to performance limitations of real lines count calculation."""
646
- return isinstance(self._body, Sized) and (size[1] * 3 < len(self))
666
+ return isinstance(self._body, (Sized, EstimatedSized)) and (size[1] * 3 < operator.length_hint(self.body))
647
667
 
648
668
  def get_first_visible_pos(self, size: tuple[int, int], focus: bool = False) -> int:
649
669
  self._check_support_scrolling()
@@ -24,9 +24,9 @@ import typing
24
24
  import warnings
25
25
 
26
26
  if typing.TYPE_CHECKING:
27
- from collections.abc import Callable, Collection, Iterator
27
+ from collections.abc import Callable, Collection, Iterable, Iterator
28
28
 
29
- from typing_extensions import Concatenate, ParamSpec
29
+ from typing_extensions import Concatenate, ParamSpec, Self
30
30
 
31
31
  ArgSpec = ParamSpec("ArgSpec")
32
32
  Ret = typing.TypeVar("Ret")
@@ -88,23 +88,69 @@ class MonitoredList(typing.List[_T], typing.Generic[_T]):
88
88
  for item in self:
89
89
  yield None, item
90
90
 
91
- __add__ = _call_modified(list.__add__) # type: ignore[assignment] # magic like old __super__
92
- __delitem__ = _call_modified(list.__delitem__) # type: ignore[assignment] # magic like old __super__
93
-
94
- __iadd__ = _call_modified(list.__iadd__) # type: ignore[assignment] # magic like old __super__
95
- __imul__ = _call_modified(list.__imul__) # type: ignore[assignment] # magic like old __super__
96
- __rmul__ = _call_modified(list.__rmul__) # type: ignore[assignment] # magic like old __super__
97
- __setitem__ = _call_modified(list.__setitem__) # type: ignore[assignment] # magic like old __super__
98
-
99
- append = _call_modified(list.append) # type: ignore[assignment] # magic like old __super__
100
- extend = _call_modified(list.extend) # type: ignore[assignment] # magic like old __super__
101
- insert = _call_modified(list.insert) # type: ignore[assignment] # magic like old __super__
102
- pop = _call_modified(list.pop) # type: ignore[assignment] # magic like old __super__
103
- remove = _call_modified(list.remove) # type: ignore[assignment] # magic like old __super__
104
- reverse = _call_modified(list.reverse) # type: ignore[assignment] # magic like old __super__
105
- sort = _call_modified(list.sort) # type: ignore[assignment] # magic like old __super__
106
- if hasattr(list, "clear"):
107
- clear = _call_modified(list.clear) # type: ignore[assignment] # magic like old __super__
91
+ @_call_modified
92
+ def __add__(self, __value: list[_T]) -> Self:
93
+ return super().__add__(__value)
94
+
95
+ @_call_modified
96
+ def __delitem__(self, __key: typing.SupportsIndex | slice) -> None:
97
+ super().__delitem__(__key)
98
+
99
+ @_call_modified
100
+ def __iadd__(self, __value: Iterable[_T]) -> Self:
101
+ return super().__iadd__(__value)
102
+
103
+ @_call_modified
104
+ def __rmul__(self, __value: typing.SupportsIndex) -> Self:
105
+ return super().__rmul__(__value)
106
+
107
+ @_call_modified
108
+ def __imul__(self, __value: typing.SupportsIndex) -> Self:
109
+ return super().__imul__(__value)
110
+
111
+ @typing.overload
112
+ @_call_modified
113
+ def __setitem__(self, __key: typing.SupportsIndex, __value: _T) -> None: ...
114
+
115
+ @typing.overload
116
+ @_call_modified
117
+ def __setitem__(self, __key: slice, __value: Iterable[_T]) -> None: ...
118
+
119
+ @_call_modified
120
+ def __setitem__(self, __key: typing.SupportsIndex | slice, __value: _T | Iterable[_T]) -> None:
121
+ super().__setitem__(__key, __value)
122
+
123
+ @_call_modified
124
+ def append(self, __object: _T) -> None:
125
+ super().append(__object)
126
+
127
+ @_call_modified
128
+ def extend(self, __iterable: Iterable[_T]) -> None:
129
+ super().extend(__iterable)
130
+
131
+ @_call_modified
132
+ def pop(self, __index: typing.SupportsIndex = -1) -> _T:
133
+ return super().pop(__index)
134
+
135
+ @_call_modified
136
+ def insert(self, __index: typing.SupportsIndex, __object: _T) -> None:
137
+ super().insert(__index, __object)
138
+
139
+ @_call_modified
140
+ def remove(self, __value: _T) -> None:
141
+ super().remove(__value)
142
+
143
+ @_call_modified
144
+ def reverse(self) -> None:
145
+ super().reverse()
146
+
147
+ @_call_modified
148
+ def sort(self, *, key: Callable[[_T], typing.Any] | None = None, reverse: bool = False) -> None:
149
+ super().sort(key=key, reverse=reverse)
150
+
151
+ @_call_modified
152
+ def clear(self) -> None:
153
+ super().clear()
108
154
 
109
155
 
110
156
  class MonitoredFocusList(MonitoredList[_T], typing.Generic[_T]):
@@ -40,12 +40,14 @@ class Padding(WidgetDecoration[WrappedWidget], typing.Generic[WrappedWidget]):
40
40
  self,
41
41
  w: WrappedWidget,
42
42
  align: (
43
- Literal["left", "center", "right"] | Align | tuple[Literal["relative", WHSettings.RELATIVE], int]
43
+ Literal["left", "center", "right"]
44
+ | Align
45
+ | tuple[Literal["relative", WHSettings.RELATIVE, "fixed left", "fixed right"], int]
44
46
  ) = Align.LEFT,
45
47
  width: (
46
48
  int
47
49
  | Literal["pack", "clip", WHSettings.PACK, WHSettings.CLIP]
48
- | tuple[Literal["relative", WHSettings.RELATIVE], int]
50
+ | tuple[Literal["relative", WHSettings.RELATIVE, "fixed left", "fixed right"], int]
49
51
  ) = RELATIVE_100,
50
52
  min_width: int | None = None,
51
53
  left: int = 0,
@@ -24,7 +24,7 @@ import typing
24
24
 
25
25
  from urwid.canvas import CompositeCanvas
26
26
 
27
- from .constants import Sizing
27
+ from .constants import Align, Sizing, VAlign
28
28
  from .overlay import Overlay
29
29
  from .widget import delegate_to_widget_mixin
30
30
  from .widget_decoration import WidgetDecoration
@@ -86,8 +86,7 @@ class PopUpLauncher(delegate_to_widget_mixin("_original_widget"), WidgetDecorati
86
86
 
87
87
 
88
88
  class PopUpTarget(WidgetDecoration[WrappedWidget]):
89
- # FIXME: this whole class is a terrible hack and must be fixed
90
- # when layout and rendering are separated
89
+ # FIXME: this whole class is a terrible hack and must be fixed when layout and rendering are separated
91
90
  _sizing = frozenset((Sizing.BOX,))
92
91
  _selectable = True
93
92
 
@@ -105,19 +104,23 @@ class PopUpTarget(WidgetDecoration[WrappedWidget]):
105
104
  if self._pop_up != w:
106
105
  self._pop_up = w
107
106
  self._current_widget = Overlay(
108
- w,
109
- self._original_widget,
110
- ("fixed left", left),
111
- overlay_width,
112
- ("fixed top", top),
113
- overlay_height,
107
+ top_w=w,
108
+ bottom_w=self._original_widget,
109
+ align=Align.LEFT,
110
+ width=overlay_width,
111
+ valign=VAlign.TOP,
112
+ height=overlay_height,
113
+ left=left,
114
+ top=top,
114
115
  )
115
116
  else:
116
117
  self._current_widget.set_overlay_parameters(
117
- ("fixed left", left),
118
- overlay_width,
119
- ("fixed top", top),
120
- overlay_height,
118
+ align=Align.LEFT,
119
+ width=overlay_width,
120
+ valign=VAlign.TOP,
121
+ height=overlay_height,
122
+ left=left,
123
+ top=top,
121
124
  )
122
125
  else:
123
126
  self._pop_up = None