urwid 4.2.5__tar.gz → 5.0.0__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 (131) hide show
  1. {urwid-4.2.5 → urwid-5.0.0}/.github/workflows/documentation.yml +1 -1
  2. {urwid-4.2.5 → urwid-5.0.0}/.github/workflows/isolated_mypy.yml +4 -3
  3. {urwid-4.2.5 → urwid-5.0.0}/.github/workflows/isolated_pylint.yml +3 -2
  4. urwid-5.0.0/.github/workflows/isolated_pyrefly.yml +28 -0
  5. {urwid-4.2.5 → urwid-5.0.0}/.github/workflows/pythonpackage.yml +54 -13
  6. {urwid-4.2.5 → urwid-5.0.0}/.github/workflows/yamllint.yml +1 -1
  7. {urwid-4.2.5 → urwid-5.0.0}/.pre-commit-config.yaml +2 -2
  8. {urwid-4.2.5/urwid.egg-info → urwid-5.0.0}/PKG-INFO +21 -19
  9. {urwid-4.2.5 → urwid-5.0.0}/README.rst +17 -11
  10. {urwid-4.2.5 → urwid-5.0.0}/classifiers.txt +0 -2
  11. {urwid-4.2.5 → urwid-5.0.0}/conftest.py +9 -12
  12. urwid-5.0.0/mypy-requirements.txt +2 -0
  13. urwid-5.0.0/pylint-requirements.txt +1 -0
  14. {urwid-4.2.5 → urwid-5.0.0}/pyproject.toml +202 -151
  15. urwid-5.0.0/pyrefly-requirements.txt +2 -0
  16. urwid-5.0.0/pytest_requirements.txt +4 -0
  17. urwid-5.0.0/requirements.txt +3 -0
  18. {urwid-4.2.5 → urwid-5.0.0}/tox.ini +49 -8
  19. {urwid-4.2.5 → urwid-5.0.0}/urwid/__init__.py +36 -13
  20. urwid-5.0.0/urwid/_deprecation.py +74 -0
  21. urwid-5.0.0/urwid/_selectors.py +66 -0
  22. {urwid-4.2.5 → urwid-5.0.0}/urwid/ansi_parser.py +404 -116
  23. {urwid-4.2.5 → urwid-5.0.0}/urwid/canvas.py +226 -265
  24. {urwid-4.2.5 → urwid-5.0.0}/urwid/command_map.py +55 -4
  25. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/__init__.py +6 -0
  26. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/_posix_raw_display.py +43 -36
  27. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/_raw_display_base.py +575 -166
  28. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/_web.js +15 -6
  29. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/_win32_raw_display.py +115 -44
  30. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/common.py +396 -99
  31. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/curses.py +33 -118
  32. urwid-5.0.0/urwid/display/escape.py +1307 -0
  33. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/html_fragment.py +37 -22
  34. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/lcd.py +8 -9
  35. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/web.py +38 -24
  36. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/abstract_loop.py +11 -13
  37. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/asyncio_loop.py +42 -64
  38. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/glib_loop.py +42 -23
  39. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/main_loop.py +101 -43
  40. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/select_loop.py +28 -29
  41. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/tornado_loop.py +15 -10
  42. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/trio_loop.py +152 -28
  43. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/twisted_loop.py +35 -21
  44. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/zmq_loop.py +44 -30
  45. {urwid-4.2.5 → urwid-5.0.0}/urwid/font.py +202 -43
  46. {urwid-4.2.5 → urwid-5.0.0}/urwid/graphics.py +1 -18
  47. {urwid-4.2.5 → urwid-5.0.0}/urwid/numedit.py +66 -27
  48. {urwid-4.2.5 → urwid-5.0.0}/urwid/signals.py +16 -23
  49. {urwid-4.2.5 → urwid-5.0.0}/urwid/split_repr.py +31 -21
  50. {urwid-4.2.5 → urwid-5.0.0}/urwid/str_util.py +32 -23
  51. urwid-5.0.0/urwid/testing.py +513 -0
  52. {urwid-4.2.5 → urwid-5.0.0}/urwid/text_layout.py +27 -17
  53. {urwid-4.2.5 → urwid-5.0.0}/urwid/util.py +227 -57
  54. {urwid-4.2.5 → urwid-5.0.0}/urwid/version.py +3 -3
  55. {urwid-4.2.5 → urwid-5.0.0}/urwid/vterm.py +904 -222
  56. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/__init__.py +11 -2
  57. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/ansi_text.py +34 -22
  58. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/attr_map.py +14 -5
  59. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/attr_wrap.py +18 -38
  60. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/bar_graph.py +41 -22
  61. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/box_adapter.py +0 -33
  62. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/columns.py +188 -385
  63. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/constants.py +19 -12
  64. urwid-5.0.0/urwid/widget/container.py +372 -0
  65. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/deque_walker.py +111 -10
  66. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/divider.py +1 -1
  67. urwid-5.0.0/urwid/widget/drop_down.py +243 -0
  68. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/edit.py +232 -41
  69. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/filler.py +24 -43
  70. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/frame.py +134 -231
  71. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/grid_flow.py +80 -184
  72. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/line_box.py +34 -15
  73. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/list_walker.py +89 -18
  74. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/listbox.py +354 -139
  75. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/monitored_deque.py +125 -63
  76. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/monitored_list.py +167 -35
  77. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/overlay.py +60 -35
  78. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/padding.py +41 -15
  79. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/pile.py +167 -249
  80. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/popup.py +142 -18
  81. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/progress_bar.py +40 -22
  82. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/scrollable.py +473 -93
  83. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/text.py +17 -4
  84. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/treetools.py +148 -40
  85. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/widget.py +158 -46
  86. urwid-5.0.0/urwid/widget/widget_decoration.py +275 -0
  87. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/wimp.py +68 -17
  88. {urwid-4.2.5 → urwid-5.0.0/urwid.egg-info}/PKG-INFO +21 -19
  89. {urwid-4.2.5 → urwid-5.0.0}/urwid.egg-info/SOURCES.txt +6 -0
  90. {urwid-4.2.5 → urwid-5.0.0}/urwid.egg-info/requires.txt +3 -7
  91. {urwid-4.2.5 → urwid-5.0.0}/urwid.egg-info/scm_file_list.json +29 -3
  92. urwid-5.0.0/urwid.egg-info/scm_version.json +8 -0
  93. urwid-4.2.5/mypy-requirements.txt +0 -1
  94. urwid-4.2.5/pylint-requirements.txt +0 -1
  95. urwid-4.2.5/pytest_requirements.txt +0 -5
  96. urwid-4.2.5/requirements.txt +0 -2
  97. urwid-4.2.5/urwid/display/escape.py +0 -842
  98. urwid-4.2.5/urwid/widget/container.py +0 -199
  99. urwid-4.2.5/urwid/widget/widget_decoration.py +0 -160
  100. urwid-4.2.5/urwid.egg-info/scm_version.json +0 -8
  101. {urwid-4.2.5 → urwid-5.0.0}/.devcontainer/dev.dockerfile +0 -0
  102. {urwid-4.2.5 → urwid-5.0.0}/.devcontainer/devcontainer.json +0 -0
  103. {urwid-4.2.5 → urwid-5.0.0}/.dockerignore +0 -0
  104. {urwid-4.2.5 → urwid-5.0.0}/.editorconfig +0 -0
  105. {urwid-4.2.5 → urwid-5.0.0}/.github/CODE_OF_CONDUCT.md +0 -0
  106. {urwid-4.2.5 → urwid-5.0.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  107. {urwid-4.2.5 → urwid-5.0.0}/.github/ISSUE_TEMPLATE/docs.md +0 -0
  108. {urwid-4.2.5 → urwid-5.0.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  109. {urwid-4.2.5 → urwid-5.0.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  110. {urwid-4.2.5 → urwid-5.0.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  111. {urwid-4.2.5 → urwid-5.0.0}/.github/dependabot.yml +0 -0
  112. {urwid-4.2.5 → urwid-5.0.0}/.github/labeler.yml +0 -0
  113. {urwid-4.2.5 → urwid-5.0.0}/.github/release.yml +0 -0
  114. {urwid-4.2.5 → urwid-5.0.0}/.github/workflows/labels.yml +0 -0
  115. {urwid-4.2.5 → urwid-5.0.0}/.gitignore +0 -0
  116. {urwid-4.2.5 → urwid-5.0.0}/.yamllint.yml +0 -0
  117. {urwid-4.2.5 → urwid-5.0.0}/COPYING +0 -0
  118. {urwid-4.2.5 → urwid-5.0.0}/MANIFEST.in +0 -0
  119. {urwid-4.2.5 → urwid-5.0.0}/SECURITY.md +0 -0
  120. {urwid-4.2.5 → urwid-5.0.0}/setup.cfg +0 -0
  121. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/_web.css +0 -0
  122. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/_win32.py +0 -0
  123. {urwid-4.2.5 → urwid-5.0.0}/urwid/display/raw.py +0 -0
  124. {urwid-4.2.5 → urwid-5.0.0}/urwid/event_loop/__init__.py +0 -0
  125. {urwid-4.2.5 → urwid-5.0.0}/urwid/py.typed +0 -0
  126. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/big_text.py +0 -0
  127. {urwid-4.2.5 → urwid-5.0.0}/urwid/widget/solid_fill.py +0 -0
  128. {urwid-4.2.5 → urwid-5.0.0}/urwid.egg-info/dependency_links.txt +0 -0
  129. {urwid-4.2.5 → urwid-5.0.0}/urwid.egg-info/not-zip-safe +0 -0
  130. {urwid-4.2.5 → urwid-5.0.0}/urwid.egg-info/top_level.txt +0 -0
  131. {urwid-4.2.5 → urwid-5.0.0}/yamllint-requirements.txt +0 -0
@@ -27,7 +27,7 @@ jobs:
27
27
  with:
28
28
  fetch-depth: 0 # need for setuptools_scm
29
29
  - name: Install uv
30
- uses: astral-sh/setup-uv@v10.2.0
30
+ uses: astral-sh/setup-uv@v10.3.2
31
31
  - name: Create virtual environment
32
32
  run: uv venv
33
33
  - name: Install python dependencies
@@ -17,12 +17,13 @@ jobs:
17
17
  steps:
18
18
  - uses: actions/checkout@v7
19
19
  - name: Install uv
20
- uses: astral-sh/setup-uv@v10.2.0
20
+ uses: astral-sh/setup-uv@v10.3.2
21
21
  - name: Create virtual environment
22
- run: uv venv
22
+ run: uv venv --python 3.14
23
23
  - name: Install package with all extras
24
24
  run: uv pip install -e ".[curses,serial,tornado,trio,twisted,zmq]"
25
25
  - name: Install dependencies
26
26
  run: uv pip install --upgrade -r mypy-requirements.txt
27
+ # tests other than tests/type_checks are not checked, see [tool.ruff] extend-exclude in pyproject.toml
27
28
  - name: Type check with mypy
28
- run: uv run --no-project mypy urwid
29
+ run: uv run --no-project mypy urwid examples tests/type_checks
@@ -17,12 +17,13 @@ jobs:
17
17
  steps:
18
18
  - uses: actions/checkout@v7
19
19
  - name: Install uv
20
- uses: astral-sh/setup-uv@v10.2.0
20
+ uses: astral-sh/setup-uv@v10.3.2
21
21
  - name: Create virtual environment
22
- run: uv venv
22
+ run: uv venv --python 3.14
23
23
  - name: Install package with all extras
24
24
  run: uv pip install -e ".[curses,serial,tornado,trio,twisted,zmq]"
25
25
  - name: Install dependencies
26
26
  run: uv pip install --upgrade -r pylint-requirements.txt
27
+ # tests are not checked, see [tool.ruff] extend-exclude in pyproject.toml
27
28
  - name: Lint with pylint
28
29
  run: uv run --no-project pylint --output-format=github urwid
@@ -0,0 +1,28 @@
1
+ name: Isolated Pyrefly check
2
+
3
+ on:
4
+ pull_request:
5
+ paths:
6
+ - "pyrefly-requirements.txt"
7
+ - ".github/workflows/isolated_pyrefly.yml"
8
+
9
+ concurrency:
10
+ group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}"
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ Pyrefly:
15
+ name: Check with Pyrefly
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v7
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v10.3.2
21
+ - name: Create virtual environment
22
+ run: uv venv --python 3.14
23
+ - name: Install package with all extras
24
+ run: uv pip install -e ".[curses,serial,tornado,trio,twisted,zmq]"
25
+ - name: Install dependencies
26
+ run: uv pip install --upgrade -r pyrefly-requirements.txt
27
+ - name: Type check with Pyrefly
28
+ run: uv run --no-project pyrefly check --output-format full-text-with-github
@@ -53,13 +53,14 @@ jobs:
53
53
  steps:
54
54
  - uses: actions/checkout@v7
55
55
  - name: Install uv
56
- uses: astral-sh/setup-uv@v10.2.0
56
+ uses: astral-sh/setup-uv@v10.3.2
57
57
  - name: Create virtual environment
58
- run: uv venv
58
+ run: uv venv --python 3.14
59
59
  - name: Install package with all extras
60
60
  run: uv pip install -e ".[curses,serial,tornado,trio,twisted,zmq]"
61
61
  - name: Install dependencies
62
62
  run: uv pip install --upgrade -r pylint-requirements.txt
63
+ # tests are not checked, see [tool.ruff] extend-exclude in pyproject.toml
63
64
  - name: Lint with pylint
64
65
  run: uv run --no-project pylint --output-format=github urwid
65
66
 
@@ -69,26 +70,56 @@ jobs:
69
70
  steps:
70
71
  - uses: actions/checkout@v7
71
72
  - name: Install uv
72
- uses: astral-sh/setup-uv@v10.2.0
73
+ uses: astral-sh/setup-uv@v10.3.2
73
74
  - name: Create virtual environment
74
- run: uv venv
75
+ run: uv venv --python 3.14
75
76
  - name: Install package with all extras
76
77
  run: uv pip install -e ".[curses,serial,tornado,trio,twisted,zmq]"
77
78
  - name: Install dependencies
78
79
  run: uv pip install --upgrade -r mypy-requirements.txt
80
+ # tests other than tests/type_checks are not checked, see [tool.ruff] extend-exclude in pyproject.toml
79
81
  - name: Type check with mypy
80
- run: uv run --no-project mypy urwid
82
+ run: uv run --no-project mypy urwid examples tests/type_checks
83
+
84
+ Pyrefly:
85
+ name: Check with Pyrefly
86
+ runs-on: ubuntu-latest
87
+ steps:
88
+ - uses: actions/checkout@v7
89
+ - name: Install uv
90
+ uses: astral-sh/setup-uv@v10.3.2
91
+ - name: Create virtual environment
92
+ run: uv venv --python 3.14
93
+ - name: Install package with all extras
94
+ run: uv pip install -e ".[curses,serial,tornado,trio,twisted,zmq]"
95
+ - name: Install dependencies
96
+ run: uv pip install --upgrade -r pyrefly-requirements.txt
97
+ - name: Type check with Pyrefly
98
+ run: uv run --no-project pyrefly check --output-format full-text-with-github
81
99
 
82
100
  Test:
83
- needs: [ Ruff-format, Ruff, PyLint, Mypy ]
101
+ needs: [ Ruff-format, Ruff, PyLint, Mypy, Pyrefly ]
84
102
  runs-on: ${{ matrix.os }}
85
103
  strategy:
86
104
  max-parallel: 6
87
105
  matrix:
88
106
  os: [ "ubuntu-latest", "windows-latest" ]
89
- # , "macos-latest"
90
- # enable macOS only if OS specific branch will be added
91
- python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13", "3.14" ]
107
+ # A "t" suffix selects the free-threaded (PEP 703, --disable-gil) build.
108
+ python-version: [ "3.11", "3.12", "3.13", "3.14", "3.15", "3.13t", "3.14t", "3.15t", "pypy3.11" ]
109
+ exclude:
110
+ # trio needs cffi on Windows, which publishes no 3.13t wheel and refuses to build for it.
111
+ - os: "windows-latest"
112
+ python-version: "3.13t"
113
+ # urwid has no macOS-specific code: macOS runs the POSIX paths Linux covers, so the oldest and newest
114
+ # CPython, plus the newest free-threaded build, are enough to catch selector (kqueue) and other POSIX
115
+ # differences.
116
+ include:
117
+ - os: "macos-latest"
118
+ python-version: "3.11"
119
+ - os: "macos-latest"
120
+ python-version: "3.15"
121
+ - os: "macos-latest"
122
+ python-version: "3.15t"
92
123
 
93
124
  steps:
94
125
  - uses: actions/checkout@v7
@@ -100,13 +131,23 @@ jobs:
100
131
  python-version: ${{ matrix.python-version }}
101
132
  allow-prereleases: true
102
133
  - name: Install uv
103
- uses: astral-sh/setup-uv@v10.2.0
134
+ uses: astral-sh/setup-uv@v10.3.2
104
135
  - name: Create virtual environment
105
136
  run: uv venv --python-preference only-system --python ${{ matrix.python-version }}
106
137
  - name: Install dependencies
107
138
  run: uv pip install -r pytest_requirements.txt
108
139
  - name: Install package with all extras
109
- run: uv pip install -e ".[curses,serial,tornado,trio,twisted,zmq]"
140
+ # pyzmq (zmq) and windows-curses (curses) publish no free-threaded wheels for every supported version.
141
+ # windows-curses publishes no 3.15 wheel and no sdist; the curses extra is empty outside Windows.
142
+ # The PyPy extras match the pypy3 tox environment.
143
+ run: >-
144
+ uv pip install -e ".[${{ startsWith(matrix.python-version, 'pypy')
145
+ && 'serial,tornado,trio'
146
+ || endsWith(matrix.python-version, 't')
147
+ && 'serial,tornado,trio,twisted'
148
+ || matrix.python-version == '3.15'
149
+ && 'serial,tornado,trio,twisted,zmq'
150
+ || 'curses,serial,tornado,trio,twisted,zmq' }}]"
110
151
  - name: Test
111
152
  run: uv run --no-project python -m pytest --cov-report=term --cov-report=xml
112
153
  - name: Coveralls Parallel
@@ -137,7 +178,7 @@ jobs:
137
178
  fetch-depth: 0 # need for setuptools_scm
138
179
 
139
180
  - name: Install uv
140
- uses: astral-sh/setup-uv@v10.2.0
181
+ uses: astral-sh/setup-uv@v10.3.2
141
182
 
142
183
  - name: Build dist
143
184
  run: uv build
@@ -161,7 +202,7 @@ jobs:
161
202
  steps:
162
203
  - uses: actions/checkout@v7
163
204
  - name: Install uv
164
- uses: astral-sh/setup-uv@v10.2.0
205
+ uses: astral-sh/setup-uv@v10.3.2
165
206
  - uses: actions/download-artifact@v8
166
207
  with:
167
208
  # unpacks default artifact into dist/
@@ -17,7 +17,7 @@ jobs:
17
17
  steps:
18
18
  - uses: actions/checkout@v7
19
19
  - name: Install uv
20
- uses: astral-sh/setup-uv@v10.2.0
20
+ uses: astral-sh/setup-uv@v10.3.2
21
21
  - name: Lint YAML files
22
22
  run: uv run --no-project --with-requirements yamllint-requirements.txt yamllint . -f github
23
23
 
@@ -12,14 +12,14 @@ repos:
12
12
  - id: check-merge-conflict
13
13
 
14
14
  - repo: https://github.com/astral-sh/ruff-pre-commit
15
- rev: v0.16.9
15
+ rev: v0.17.0
16
16
  hooks:
17
17
  - id: ruff-check
18
18
  args: [ --show-fixes, --fix ]
19
19
  - id: ruff-format
20
20
 
21
21
  - repo: https://github.com/tox-dev/pyproject-fmt
22
- rev: v2.26.0
22
+ rev: v2.30.3
23
23
  hooks:
24
24
  - id: pyproject-fmt
25
25
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: urwid
3
- Version: 4.2.5
3
+ Version: 5.0.0
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
@@ -22,8 +22,6 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
22
  Classifier: Topic :: Software Development :: User Interfaces
23
23
  Classifier: Topic :: Software Development :: Widget Sets
24
24
  Classifier: Programming Language :: Python :: 3
25
- Classifier: Programming Language :: Python :: 3.9
26
- Classifier: Programming Language :: Python :: 3.10
27
25
  Classifier: Programming Language :: Python :: 3.11
28
26
  Classifier: Programming Language :: Python :: 3.12
29
27
  Classifier: Programming Language :: Python :: 3.13
@@ -35,11 +33,11 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
35
33
  Classifier: Programming Language :: Python :: Implementation :: GraalPy
36
34
  Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
37
35
  Classifier: Typing :: Typed
38
- Requires-Python: >=3.9.0
36
+ Requires-Python: >=3.11.0
39
37
  Description-Content-Type: text/x-rst
40
38
  License-File: COPYING
41
39
  Requires-Dist: wcwidth!=0.9.0,!=0.9.1,>=0.4
42
- Requires-Dist: typing-extensions
40
+ Requires-Dist: typing_extensions>=4.5.0; python_version < "3.13"
43
41
  Provides-Extra: curses
44
42
  Requires-Dist: windows-curses; sys_platform == "win32" and extra == "curses"
45
43
  Provides-Extra: glib
@@ -47,11 +45,9 @@ Requires-Dist: pygobject; extra == "glib"
47
45
  Provides-Extra: tornado
48
46
  Requires-Dist: tornado>=6.5.8; extra == "tornado"
49
47
  Provides-Extra: trio
50
- Requires-Dist: exceptiongroup; python_version < "3.11" and extra == "trio"
51
48
  Requires-Dist: trio>=0.31.0; extra == "trio"
52
49
  Provides-Extra: twisted
53
- Requires-Dist: twisted>=24.7.0; extra == "twisted"
54
- Requires-Dist: twisted>=26.4.0; python_full_version >= "3.9.12" and extra == "twisted"
50
+ Requires-Dist: twisted>=26.4.0; extra == "twisted"
55
51
  Provides-Extra: zmq
56
52
  Requires-Dist: pyzmq>=26.0.0; extra == "zmq"
57
53
  Provides-Extra: serial
@@ -81,7 +77,7 @@ It includes many features useful for text console application developers includi
81
77
  - Display modules include raw, curses, and experimental LCD and web displays
82
78
  - Support for UTF-8, simple 8-bit and CJK encodings
83
79
  - 24-bit (true color), 256 color, and 88 color mode support
84
- - Compatible with Python 3.9+ and PyPy
80
+ - Compatible with Python 3.11+ and PyPy
85
81
 
86
82
  Home Page:
87
83
  http://urwid.org/
@@ -142,10 +138,10 @@ To test code in all Python versions:
142
138
  .. code:: bash
143
139
 
144
140
  tox # Test all versions specified in tox.ini
145
- tox -e py39 # Test Python 3.9 only
141
+ tox -e py311 # Test Python 3.11 only
146
142
  tox -e py313t # Test Python 3.13 with free-threading
147
- tox -e pypy3 # Test PyPy3
148
- tox -e py39,py310,pypy3 # Test specific versions
143
+ tox -e pypy311 # Test PyPy 3.11
144
+ tox -e py311,py312,pypy311 # Test specific versions
149
145
 
150
146
  Testing different Python implementations
151
147
  ----------------------------------------
@@ -168,13 +164,14 @@ Tests with compatible extras (tornado, trio, twisted, serial). Excludes C extens
168
164
  tox -e py314t # Python 3.14 free-threaded
169
165
  tox -e py315t # Python 3.15 free-threaded
170
166
 
171
- **PyPy3**
167
+ **PyPy**
172
168
 
173
169
  Tests with compatible extras (tornado, trio, serial). Excludes problematic C extensions.
174
170
 
175
171
  .. code:: bash
176
172
 
177
- tox -e pypy3
173
+ tox -e pypy311 # PyPy 3.11
174
+ tox -e pypy312 # PyPy 3.12
178
175
 
179
176
  **GraalPy**
180
177
 
@@ -186,18 +183,18 @@ so its tests are skipped rather than run.
186
183
 
187
184
  .. code:: bash
188
185
 
189
- tox -e graalpy311 # GraalPy 3.11
190
186
  tox -e graalpy312 # GraalPy 3.12
187
+ tox -e graalpy313 # GraalPy 3.13
191
188
 
192
189
  Supported Python versions
193
190
  =========================
194
191
 
195
192
  Urwid supports:
196
193
 
197
- - CPython 3.9, 3.10, 3.11, 3.12, 3.13, 3.14, 3.15
194
+ - CPython 3.11, 3.12, 3.13, 3.14, 3.15
198
195
  - CPython 3.13+ with free-threading (PEP 703 ``--disable-gil``)
199
- - PyPy 3.x
200
- - GraalPy 3.11, 3.12 (experimental)
196
+ - PyPy 3.11
197
+ - GraalPy 3.12, 3.13 (experimental)
201
198
 
202
199
  Python implementation notes
203
200
  ===========================
@@ -205,12 +202,13 @@ Python implementation notes
205
202
  **CPython (standard Python)**
206
203
 
207
204
  Full support for all optional features. All extras (``curses``, ``glib``, ``serial``, ``tornado``, ``trio``, ``twisted``, ``zmq``) can be installed.
205
+ On Windows, the ``curses`` extra cannot be installed on Python 3.15 yet: ``windows-curses`` publishes no 3.15 wheel.
208
206
 
209
207
  **CPython with Free-Threading (3.13, 3.14, 3.15+)**
210
208
 
211
209
  Urwid core and pure-Python event loops are fully supported. Some extras require C extensions that may not have free-threading wheels available:
212
210
 
213
- - ✅ Supported: core, tornado, trio, twisted (24.10.0+), serial, lcd
211
+ - ✅ Supported: core, tornado, trio, twisted, serial, lcd
214
212
  - ❌ Unsupported: glib, zmq (require C extensions with free-threading wheel support)
215
213
 
216
214
  For free-threading Python, install with compatible extras:
@@ -226,6 +224,8 @@ Urwid core is fully supported. Some extras may have compatibility issues:
226
224
  - ✅ Supported: core, tornado, trio, serial, lcd
227
225
  - ⚠️ Limited: twisted (may have issues, test before using)
228
226
  - ❌ Unsupported: glib, zmq (C extensions with limited PyPy support)
227
+ - ❌ Unsupported: curses on Windows (PyPy for Windows ships no ``_curses`` module and ``windows-curses`` publishes
228
+ no PyPy wheels)
229
229
 
230
230
  **GraalPy (experimental)**
231
231
 
@@ -236,6 +236,8 @@ modules, and the Terminal widget are not:
236
236
  - ❌ Unsupported: curses (GraalPy ships no ``_curses`` module), glib, zmq, twisted, trio (no C
237
237
  extension support, or known compatibility issues), Terminal widget/``urwid.vterm`` (like on
238
238
  Windows, ``fcntl``/``pty`` usage doesn't work on GraalPy)
239
+ - ❌ Unsupported: GraalPy 3.11 (GraalPy 24), whose ``os`` module has no ``O_NOFOLLOW`` and whose ASCII and Latin-1
240
+ codecs ignore registered error handlers
239
241
 
240
242
  Authors
241
243
  =======
@@ -19,7 +19,7 @@ It includes many features useful for text console application developers includi
19
19
  - Display modules include raw, curses, and experimental LCD and web displays
20
20
  - Support for UTF-8, simple 8-bit and CJK encodings
21
21
  - 24-bit (true color), 256 color, and 88 color mode support
22
- - Compatible with Python 3.9+ and PyPy
22
+ - Compatible with Python 3.11+ and PyPy
23
23
 
24
24
  Home Page:
25
25
  http://urwid.org/
@@ -80,10 +80,10 @@ To test code in all Python versions:
80
80
  .. code:: bash
81
81
 
82
82
  tox # Test all versions specified in tox.ini
83
- tox -e py39 # Test Python 3.9 only
83
+ tox -e py311 # Test Python 3.11 only
84
84
  tox -e py313t # Test Python 3.13 with free-threading
85
- tox -e pypy3 # Test PyPy3
86
- tox -e py39,py310,pypy3 # Test specific versions
85
+ tox -e pypy311 # Test PyPy 3.11
86
+ tox -e py311,py312,pypy311 # Test specific versions
87
87
 
88
88
  Testing different Python implementations
89
89
  ----------------------------------------
@@ -106,13 +106,14 @@ Tests with compatible extras (tornado, trio, twisted, serial). Excludes C extens
106
106
  tox -e py314t # Python 3.14 free-threaded
107
107
  tox -e py315t # Python 3.15 free-threaded
108
108
 
109
- **PyPy3**
109
+ **PyPy**
110
110
 
111
111
  Tests with compatible extras (tornado, trio, serial). Excludes problematic C extensions.
112
112
 
113
113
  .. code:: bash
114
114
 
115
- tox -e pypy3
115
+ tox -e pypy311 # PyPy 3.11
116
+ tox -e pypy312 # PyPy 3.12
116
117
 
117
118
  **GraalPy**
118
119
 
@@ -124,18 +125,18 @@ so its tests are skipped rather than run.
124
125
 
125
126
  .. code:: bash
126
127
 
127
- tox -e graalpy311 # GraalPy 3.11
128
128
  tox -e graalpy312 # GraalPy 3.12
129
+ tox -e graalpy313 # GraalPy 3.13
129
130
 
130
131
  Supported Python versions
131
132
  =========================
132
133
 
133
134
  Urwid supports:
134
135
 
135
- - CPython 3.9, 3.10, 3.11, 3.12, 3.13, 3.14, 3.15
136
+ - CPython 3.11, 3.12, 3.13, 3.14, 3.15
136
137
  - CPython 3.13+ with free-threading (PEP 703 ``--disable-gil``)
137
- - PyPy 3.x
138
- - GraalPy 3.11, 3.12 (experimental)
138
+ - PyPy 3.11
139
+ - GraalPy 3.12, 3.13 (experimental)
139
140
 
140
141
  Python implementation notes
141
142
  ===========================
@@ -143,12 +144,13 @@ Python implementation notes
143
144
  **CPython (standard Python)**
144
145
 
145
146
  Full support for all optional features. All extras (``curses``, ``glib``, ``serial``, ``tornado``, ``trio``, ``twisted``, ``zmq``) can be installed.
147
+ On Windows, the ``curses`` extra cannot be installed on Python 3.15 yet: ``windows-curses`` publishes no 3.15 wheel.
146
148
 
147
149
  **CPython with Free-Threading (3.13, 3.14, 3.15+)**
148
150
 
149
151
  Urwid core and pure-Python event loops are fully supported. Some extras require C extensions that may not have free-threading wheels available:
150
152
 
151
- - ✅ Supported: core, tornado, trio, twisted (24.10.0+), serial, lcd
153
+ - ✅ Supported: core, tornado, trio, twisted, serial, lcd
152
154
  - ❌ Unsupported: glib, zmq (require C extensions with free-threading wheel support)
153
155
 
154
156
  For free-threading Python, install with compatible extras:
@@ -164,6 +166,8 @@ Urwid core is fully supported. Some extras may have compatibility issues:
164
166
  - ✅ Supported: core, tornado, trio, serial, lcd
165
167
  - ⚠️ Limited: twisted (may have issues, test before using)
166
168
  - ❌ Unsupported: glib, zmq (C extensions with limited PyPy support)
169
+ - ❌ Unsupported: curses on Windows (PyPy for Windows ships no ``_curses`` module and ``windows-curses`` publishes
170
+ no PyPy wheels)
167
171
 
168
172
  **GraalPy (experimental)**
169
173
 
@@ -174,6 +178,8 @@ modules, and the Terminal widget are not:
174
178
  - ❌ Unsupported: curses (GraalPy ships no ``_curses`` module), glib, zmq, twisted, trio (no C
175
179
  extension support, or known compatibility issues), Terminal widget/``urwid.vterm`` (like on
176
180
  Windows, ``fcntl``/``pty`` usage doesn't work on GraalPy)
181
+ - ❌ Unsupported: GraalPy 3.11 (GraalPy 24), whose ``os`` module has no ``O_NOFOLLOW`` and whose ASCII and Latin-1
182
+ codecs ignore registered error handlers
177
183
 
178
184
  Authors
179
185
  =======
@@ -10,8 +10,6 @@ Topic :: Software Development :: Libraries :: Python Modules
10
10
  Topic :: Software Development :: User Interfaces
11
11
  Topic :: Software Development :: Widget Sets
12
12
  Programming Language :: Python :: 3
13
- Programming Language :: Python :: 3.9
14
- Programming Language :: Python :: 3.10
15
13
  Programming Language :: Python :: 3.11
16
14
  Programming Language :: Python :: 3.12
17
15
  Programming Language :: Python :: 3.13
@@ -10,7 +10,6 @@ if typing.TYPE_CHECKING:
10
10
  from pathlib import Path
11
11
 
12
12
  IS_WINDOWS = sys.platform == "win32"
13
- IS_GRAALPY = sys.implementation.name == "graalpy"
14
13
 
15
14
  # Modules that import only on one platform. Urwid picks between them at runtime
16
15
  # (see `urwid/display/raw.py` and the `sys.platform` guards in `urwid/__init__.py`),
@@ -36,21 +35,19 @@ _OPTIONAL_BACKEND: typing.Final[dict[str, str]] = {
36
35
  "zmq_loop.py": "zmq",
37
36
  }
38
37
 
39
- # GraalPy ships a pure-Python `curses` package (so `find_spec("curses")` succeeds) but no compiled
40
- # `_curses` extension backing it, so importing `curses` itself raises
41
- # ModuleNotFoundError for `_curses` rather than failing to resolve up front. Treated as always
42
- # unavailable there rather than probed with `find_spec`, since a partial/shim module on a
43
- # non-CPython interpreter is not reliable evidence either way.
44
- _UNAVAILABLE_ON_GRAALPY: typing.Final[frozenset[str]] = frozenset({"_curses"})
45
-
46
38
 
47
39
  def _backend_available(name: str) -> bool:
48
- if IS_GRAALPY and name in _UNAVAILABLE_ON_GRAALPY:
49
- return False
40
+ """Return whether the module *name* can be imported.
41
+
42
+ Importing is the only reliable probe.
43
+ GraalPy and PyPy for Windows ship an ``_curses`` stub that ``find_spec`` resolves,
44
+ but the stub raises ``ModuleNotFoundError`` on import.
45
+ """
50
46
  try:
51
- return importlib.util.find_spec(name) is not None
52
- except (ImportError, ValueError):
47
+ importlib.import_module(name)
48
+ except ImportError:
53
49
  return False
50
+ return True
54
51
 
55
52
 
56
53
  def pytest_ignore_collect(collection_path: Path) -> bool | None:
@@ -0,0 +1,2 @@
1
+ mypy==2.4.0
2
+ types-pyserial==3.5.0.20260712
@@ -0,0 +1 @@
1
+ pylint==4.1.3