urwid 2.6.11__py3-none-any.whl → 2.6.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

urwid/canvas.py CHANGED
@@ -935,7 +935,7 @@ def shard_body_row(sbody):
935
935
  else: # noqa: PLR5501 # pylint: disable=else-if-used # readability
936
936
  # need to skip this unchanged canvas
937
937
  if row and isinstance(row[-1], int):
938
- row[-1] = row[-1] + cview[2]
938
+ row[-1] += cview[2]
939
939
  else:
940
940
  row.append(cview[2])
941
941
 
@@ -544,9 +544,7 @@ class Screen(BaseScreen, RealTerminal):
544
544
  def is_blank_row(row: list[tuple[object, Literal["0", "U"] | None], bytes]) -> bool:
545
545
  if len(row) > 1:
546
546
  return False
547
- if row[0][2].strip():
548
- return False
549
- return True
547
+ return not row[0][2].strip()
550
548
 
551
549
  def attr_to_escape(a: AttrSpec | str | None) -> str:
552
550
  if a in self._pal_escape:
@@ -684,7 +682,7 @@ class Screen(BaseScreen, RealTerminal):
684
682
  if isinstance(inserttext, bytes):
685
683
  inserttext = inserttext.decode(encoding)
686
684
 
687
- output.extend(("\x08" * back, ias))
685
+ output.extend(("\x08" * back, ias)) # pylint: disable=used-before-assignment # defined in `if row`
688
686
 
689
687
  if encoding != "utf-8":
690
688
  if cs is None:
urwid/display/common.py CHANGED
@@ -39,9 +39,6 @@ if typing.TYPE_CHECKING:
39
39
 
40
40
  IS_WINDOWS = sys.platform == "win32"
41
41
 
42
- if not IS_WINDOWS:
43
- import termios
44
-
45
42
  # for replacing unprintable bytes with '?'
46
43
  UNPRINTABLE_TRANS_TABLE = b"?" * 32 + bytes(range(32, 256))
47
44
 
@@ -941,6 +938,8 @@ class RealTerminal:
941
938
  is called.
942
939
  """
943
940
 
941
+ import termios
942
+
944
943
  if fileno is None:
945
944
  fileno = sys.stdin.fileno()
946
945
  if not os.isatty(fileno):
urwid/display/curses.py CHANGED
@@ -62,7 +62,7 @@ if IS_WINDOWS:
62
62
  )
63
63
 
64
64
  def initscr():
65
- import curses # pylint: disable=redefined-outer-name,reimported # special case for monkeypatch
65
+ import curses # noqa: I001 # pylint: disable=redefined-outer-name,reimported # special case for monkeypatch
66
66
 
67
67
  import _curses
68
68
 
@@ -666,7 +666,7 @@ class _test:
666
666
  r.text = ([t.ljust(cols) for t in text] + [""] * rows)[:rows]
667
667
  r.attr = (attr + [[] for _ in range(rows)])[:rows]
668
668
  self.ui.draw_screen((cols, rows), r)
669
- keys, raw = self.ui.get_input(raw_keys=True) # pylint: disable=unpacking-non-sequence
669
+ keys, raw = self.ui.get_input(raw_keys=True)
670
670
  if "window resize" in keys:
671
671
  cols, rows = self.ui.get_cols_rows()
672
672
  if not keys:
@@ -26,13 +26,16 @@ Trio library is required.
26
26
  from __future__ import annotations
27
27
 
28
28
  import logging
29
+ import sys
29
30
  import typing
30
31
 
31
- import exceptiongroup
32
32
  import trio
33
33
 
34
34
  from .abstract_loop import EventLoop, ExitMainLoop
35
35
 
36
+ if sys.version_info < (3, 11):
37
+ from exceptiongroup import BaseExceptionGroup # pylint: disable=redefined-builtin # backport
38
+
36
39
  if typing.TYPE_CHECKING:
37
40
  import io
38
41
  from collections.abc import Awaitable, Callable, Hashable, Mapping
@@ -156,8 +159,10 @@ class TrioEventLoop(EventLoop):
156
159
 
157
160
  emulate_idle_callbacks = _TrioIdleCallbackInstrument(self._idle_callbacks)
158
161
 
159
- with exceptiongroup.catch({BaseException: self._handle_main_loop_exception}):
162
+ try:
160
163
  trio.run(self._main_task, instruments=[emulate_idle_callbacks])
164
+ except BaseException as exc:
165
+ self._handle_main_loop_exception(exc)
161
166
 
162
167
  async def run_async(self) -> None:
163
168
  """Starts the main loop and blocks asynchronously until the main loop exits.
@@ -179,12 +184,14 @@ class TrioEventLoop(EventLoop):
179
184
 
180
185
  emulate_idle_callbacks = _TrioIdleCallbackInstrument(self._idle_callbacks)
181
186
 
182
- with exceptiongroup.catch({BaseException: self._handle_main_loop_exception}):
187
+ try:
183
188
  trio.lowlevel.add_instrument(emulate_idle_callbacks)
184
189
  try:
185
190
  await self._main_task()
186
191
  finally:
187
192
  trio.lowlevel.remove_instrument(emulate_idle_callbacks)
193
+ except BaseException as exc:
194
+ self._handle_main_loop_exception(exc)
188
195
 
189
196
  def watch_file(
190
197
  self,
@@ -225,12 +232,11 @@ class TrioEventLoop(EventLoop):
225
232
  """Handles exceptions raised from the main loop, catching ExitMainLoop
226
233
  instead of letting it propagate through.
227
234
 
228
- Note that since Trio may collect multiple exceptions from tasks into a
229
- Trio MultiError, we cannot simply use a try..catch clause, we need a
230
- helper function like this.
235
+ Note that since Trio may collect multiple exceptions from tasks into an ExceptionGroup,
236
+ we cannot simply use a try..catch clause, we need a helper function like this.
231
237
  """
232
238
  self._idle_callbacks.clear()
233
- if isinstance(exc, exceptiongroup.BaseExceptionGroup) and len(exc.exceptions) == 1:
239
+ if isinstance(exc, BaseExceptionGroup) and len(exc.exceptions) == 1:
234
240
  exc = exc.exceptions[0]
235
241
 
236
242
  if isinstance(exc, ExitMainLoop):
@@ -250,17 +250,17 @@ class ZMQEventLoop(EventLoop):
250
250
  """
251
251
  A single iteration of the event loop.
252
252
  """
253
+ state = "wait" # default state not expecting any action
253
254
  if self._alarms or self._did_something:
254
255
  timeout = 0
255
256
  if self._alarms:
256
257
  state = "alarm"
257
- timeout = max(0, self._alarms[0][0] - time.time())
258
+ timeout = max(0.0, self._alarms[0][0] - time.time())
258
259
  if self._did_something and (not self._alarms or (self._alarms and timeout > 0)):
259
260
  state = "idle"
260
261
  timeout = 0
261
262
  ready = dict(self._poller.poll(timeout * 1000))
262
263
  else:
263
- state = "wait"
264
264
  ready = dict(self._poller.poll())
265
265
 
266
266
  if not ready:
urwid/version.py CHANGED
@@ -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.11'
16
- __version_tuple__ = version_tuple = (2, 6, 11)
15
+ __version__ = version = '2.6.13'
16
+ __version_tuple__ = version_tuple = (2, 6, 13)
urwid/widget/bar_graph.py CHANGED
@@ -380,7 +380,7 @@ class BarGraph(Widget, metaclass=BarGraphMeta):
380
380
  row_combine_last(count, row)
381
381
  y_count -= count # noqa: PLW2901
382
382
  r += count
383
- r = r % 8
383
+ r %= 8
384
384
  if not y_count:
385
385
  continue
386
386
  if r != 0:
@@ -508,7 +508,7 @@ def calculate_bargraph_display(bardata, top: float, bar_widths: list[int], maxro
508
508
 
509
509
  for r in rows:
510
510
  if r is None:
511
- y_count = y_count + 1
511
+ y_count += 1
512
512
  continue
513
513
  if y_count:
514
514
  rowsets.append((y_count, last))
@@ -137,6 +137,17 @@ class SupportsRelativeScroll(WidgetProto, Protocol):
137
137
  def get_visible_amount(self, size: tuple[int, int], focus: bool = False) -> int: ...
138
138
 
139
139
 
140
+ def orig_iter(w: Widget) -> Iterator[Widget]:
141
+ visited = {w}
142
+ yield w
143
+ while hasattr(w, "original_widget"):
144
+ w = w.original_widget
145
+ if w in visited:
146
+ break
147
+ visited.add(w)
148
+ yield w
149
+
150
+
140
151
  class Scrollable(WidgetDecoration[WrappedWidget]):
141
152
  def sizing(self) -> frozenset[Sizing]:
142
153
  return frozenset((Sizing.BOX,))
@@ -481,7 +492,8 @@ class ScrollBar(WidgetDecoration[WrappedWidget]):
481
492
  """
482
493
  if Sizing.BOX not in widget.sizing():
483
494
  raise ValueError(f"Not a box widget: {widget!r}")
484
- if not isinstance(widget, SupportsScroll):
495
+
496
+ if not any(isinstance(w, SupportsScroll) for w in orig_iter(widget)):
485
497
  raise TypeError(f"Not a scrollable widget: {widget!r}")
486
498
 
487
499
  super().__init__(widget)
@@ -552,10 +564,10 @@ class ScrollBar(WidgetDecoration[WrappedWidget]):
552
564
  thumb_weight = min(1.0, maxrow / max(1, ow_rows_max))
553
565
 
554
566
  # Thumb shrinks/grows according to the ratio of <number of visible lines> / <number of total lines>
555
- thumb_height = max(1, round(thumb_weight * maxrow))
567
+ thumb_height = max(1, round(thumb_weight * maxrow)) # pylint: disable=possibly-used-before-assignment
556
568
 
557
569
  # Thumb may only touch top/bottom if the first/last row is visible
558
- top_weight = float(pos) / max(1, posmax)
570
+ top_weight = float(pos) / max(1, posmax) # pylint: disable=possibly-used-before-assignment
559
571
  top_height = int((maxrow - thumb_height) * top_weight)
560
572
  if top_height == 0 and top_weight > 0:
561
573
  top_height = 1
@@ -579,7 +591,10 @@ class ScrollBar(WidgetDecoration[WrappedWidget]):
579
591
  ),
580
592
  )
581
593
 
582
- combinelist = [(ow_canv, None, True, ow_size[0]), (sb_canv, None, False, sb_width)]
594
+ combinelist = [
595
+ (ow_canv, None, True, ow_size[0]), # pylint: disable=possibly-used-before-assignment
596
+ (sb_canv, None, False, sb_width),
597
+ ]
583
598
 
584
599
  if self._scrollbar_side != SCROLLBAR_LEFT:
585
600
  return canvas.CanvasJoin(combinelist)
@@ -612,12 +627,6 @@ class ScrollBar(WidgetDecoration[WrappedWidget]):
612
627
  def scrolling_base_widget(self) -> SupportsScroll | SupportsRelativeScroll:
613
628
  """Nearest `original_widget` that is compatible with the scrolling API"""
614
629
 
615
- def orig_iter(w: Widget) -> Iterator[Widget]:
616
- while hasattr(w, "original_widget"):
617
- w = w.original_widget
618
- yield w
619
- yield w
620
-
621
630
  w = self
622
631
 
623
632
  for w in orig_iter(self):
@@ -105,9 +105,13 @@ class WidgetDecoration(Widget, typing.Generic[WrappedWidget]): # pylint: disabl
105
105
  >>> wd3.base_widget is t
106
106
  True
107
107
  """
108
+ visited = {self}
108
109
  w = self
109
110
  while hasattr(w, "_original_widget"):
110
111
  w = w._original_widget
112
+ if w in visited:
113
+ break
114
+ visited.add(w)
111
115
  return w
112
116
 
113
117
  def _get_base_widget(self) -> Widget:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: urwid
3
- Version: 2.6.11
3
+ Version: 2.6.13
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>
@@ -1,5 +1,5 @@
1
1
  urwid/__init__.py,sha256=UMQZuTCtUPN9jHAEJ35lasW7IbBYRXy7NiRAKvyz4iE,8041
2
- urwid/canvas.py,sha256=6f3pSAJqg2pPsVaqcHfYx5robqvJ2JBX7xP_NQV8fqo,46750
2
+ urwid/canvas.py,sha256=8awQrNgD6zewFAzPOYcjyiKUC8mv8yDZme7_hVpKnSE,46741
3
3
  urwid/command_map.py,sha256=M_OjrGY4yKn0jU3MEF9UOhBo2R6y_zZ-qo3LVIKNT_g,4310
4
4
  urwid/container.py,sha256=mikK50qN_Cu-8VlBRqQZzU4DcOvz8P_5CfozyyoIf3Q,1589
5
5
  urwid/decoration.py,sha256=sKfCe8SdSWZ4V0Ed_G4aumLxwwhnjoVvF70vlAhoXBE,1772
@@ -11,18 +11,18 @@ urwid/split_repr.py,sha256=pXzuddzQ4RnfIl537Gvoe8PVaBRHCPnxgdYvKK0qm8k,3899
11
11
  urwid/str_util.py,sha256=1ss-LHAhjXTynTVBcoSgYWIpBeN_RirqHYhP7fq7MrA,10844
12
12
  urwid/text_layout.py,sha256=lHiGfo7clmwHt5dMl_AaQSs2ov9IbY9JySTATZBm7h0,22821
13
13
  urwid/util.py,sha256=pGXnma03_IBx3v6_qN9cDWPXPj_YjkhQ9IxLjm_0TpU,15747
14
- urwid/version.py,sha256=xlDSe3Xh6QX74LV4NLD5AhuGgpD8erExdJU0ZVYLBLM,413
14
+ urwid/version.py,sha256=T8eL9nv6DS-11fVwa1nS-rwGvQm8s4HSJKRd2eJV19g,413
15
15
  urwid/vterm.py,sha256=q9-8dxJpVr_7a0Bj_z_FYDiRgzos3IS17BjhYcy1RDw,58410
16
16
  urwid/wimp.py,sha256=o1YsjL_tBLXba8ZRr1MTHH0poLSlXT_atY3-uD_Ualg,567
17
17
  urwid/display/__init__.py,sha256=y90WbHPNRHlimPrXhzsSfFsBbBHy8QErmB1y4Xza-xo,1732
18
18
  urwid/display/_posix_raw_display.py,sha256=EkywAUNhhqgLquknP4tyicoo6QMdKG6uH6LApRmjoW8,14501
19
- urwid/display/_raw_display_base.py,sha256=dTpsLqNkaP7kPCfhPUMbEPgXhUhjzidq-uO_cWgZyow,33581
19
+ urwid/display/_raw_display_base.py,sha256=JSkF_HcPsto5YxF7NWm2vYLb6nE72AlS7SOCah8woZw,33600
20
20
  urwid/display/_web.css,sha256=6HarEsIspH2egt51HSrgI8Yl2lGi-DbziWOdS4RHNlk,359
21
21
  urwid/display/_web.js,sha256=aWEOQ4EsADsiNgdw-zHEUMCRD2bnfR8M1mu4dOc2Tqk,12947
22
22
  urwid/display/_win32.py,sha256=hD4hytElpfIv5qxGNTMSa2QeBNByqJDNVpmiiQSj6CM,5401
23
23
  urwid/display/_win32_raw_display.py,sha256=0PuHEhqJRl8uQmaWSOWceM1aEuolPZ-1MbHYN7s9yRY,9248
24
- urwid/display/common.py,sha256=_WiwXtt6KULEVLGeZvRIwmNcSfL92BPFv-uhb0_w2d0,39528
25
- urwid/display/curses.py,sha256=poYvs4iGPzl1jXpi8UUNyrTX2Ap9qxXPVhSu_zE4IuY,22800
24
+ urwid/display/common.py,sha256=iPz9uqPtjSYHo7Thj1G8nTiPdoC8Vbl5mGP0aHFYYE0,39517
25
+ urwid/display/curses.py,sha256=LA8Jglr7HRqQLYhN4wcWuvacoX_1LNjBQUbm8x0_GVo,22772
26
26
  urwid/display/escape.py,sha256=rG7x82_S91SRdfKXOEzkawDFtmVk5_KiKIY4Bh2mf7s,17826
27
27
  urwid/display/html_fragment.py,sha256=lQRqr-hTrknQyZTtzPDp9zr-TWOT4NcuSsusS-LXIOU,8547
28
28
  urwid/display/lcd.py,sha256=qXfuyZcicarrZM-O-ccPFBPjflD3_bLMv3IQzmYI43E,17607
@@ -35,13 +35,13 @@ urwid/event_loop/glib_loop.py,sha256=GFoLAenoWKm-13rTBKzCF2JdCEryJKpMo25aidZ7BWs
35
35
  urwid/event_loop/main_loop.py,sha256=gR2jGmqg1-CXFdNDlt-NizdS5AA7EZfmp6sW-nXwa18,26000
36
36
  urwid/event_loop/select_loop.py,sha256=5ZkIPqyIVJdWRTC89Ca5h8ub_-jpqXjFZaKqiWhdkDg,7534
37
37
  urwid/event_loop/tornado_loop.py,sha256=VNgXW2gO4edcYDjyEGb86yOHrE0NNXQUPXIOfJyZnAk,7100
38
- urwid/event_loop/trio_loop.py,sha256=46uFQ1O-AM8EaJETCsXzECDNviYMyzOsDKQoJgMHQSk,10468
38
+ urwid/event_loop/trio_loop.py,sha256=RicEe56BDFmIE5dbMvuqrGhUFIGSx4RliIryNF_62XQ,10593
39
39
  urwid/event_loop/twisted_loop.py,sha256=CtpWBzxNp_y7LHejnXIS67B-iboM3irb_MuI_FtXzc0,9219
40
- urwid/event_loop/zmq_loop.py,sha256=wt4lE0hnDODTVaAMuB5wCSAD5yQ6D9pj8_G_7iNGBUI,9074
40
+ urwid/event_loop/zmq_loop.py,sha256=YK_AkfLf8tayWrpCgQtKwWYuj-F1uMBluUJxPQLagNs,9114
41
41
  urwid/widget/__init__.py,sha256=lEFAuQKYnGKS9-dhUggItnnm9Bvbbuk7RAKvzrs8xkI,4683
42
42
  urwid/widget/attr_map.py,sha256=L6svBcabtXeSaU2cNrgDv4Nne6QYk-nvVbr88sA4WnY,6205
43
43
  urwid/widget/attr_wrap.py,sha256=pJQHVNlwcX5IgpdSmTqYOt63EX-p5hA0mJfXtWXJ6wg,4830
44
- urwid/widget/bar_graph.py,sha256=Ui2Z-DJ7Try9rkAQ14rK__-oSGfsWncpJH-AxSF00bk,21615
44
+ urwid/widget/bar_graph.py,sha256=1xQPKKVczMw_lDG4UBk5urUTAgtINN6SgEkVyZkaIU4,21603
45
45
  urwid/widget/big_text.py,sha256=Zvjbkdh4H1Wv9ZTdCbX23vfNyeybO8au-kUssE58Bbs,2393
46
46
  urwid/widget/box_adapter.py,sha256=uOFlZUaCK9A4H8Pmw6-OoS9QTYi9nn-LhlSa-JpC9Iw,4276
47
47
  urwid/widget/columns.py,sha256=Jz-0oR27uAoUV8LdhPWuCrkMgSHSYTxciNjxDCXPTbs,46508
@@ -60,15 +60,15 @@ urwid/widget/padding.py,sha256=pBXQsnkySV1GXgveg2Ivm6SCqHiGa2YkYSjXaoCUIHk,21334
60
60
  urwid/widget/pile.py,sha256=aIzKYNrSQtbHVk_bn2PElHUiSdsO_NKnL4mTu-sXm4I,38628
61
61
  urwid/widget/popup.py,sha256=vw9_S1UC6UMy5Roc4qK8NXgH5_dDGxoHmpDAi_u9wsI,5974
62
62
  urwid/widget/progress_bar.py,sha256=HRnIu2V2_4wgsnAdrhK-GVVToyLaXRH0gtlkWllA4Mo,4767
63
- urwid/widget/scrollable.py,sha256=yB3S3k5dOdZ-wrQMlgxQH-1AZONSf5X6Y2accIa9tpk,24279
63
+ urwid/widget/scrollable.py,sha256=UjUsBABcgJZxS5DlzqjPh2mXMHk1x_vu4ga1KAgmo4g,24540
64
64
  urwid/widget/solid_fill.py,sha256=NZRDSRK0lP4r7gXcKDgVaKEoeOcWvtrY5k2aueQEEL4,1260
65
65
  urwid/widget/text.py,sha256=jy15hL6rCBoJdZviq2jJ-i9eO6vEcxvzCIVAZs12AUw,12187
66
66
  urwid/widget/treetools.py,sha256=5s3Dnp2PCz4wQccutmdvsTTbAROJMLehXe4moB5POY0,17387
67
67
  urwid/widget/widget.py,sha256=A0ZjvDjLqhdzelPFC96Ozo1voIoGkxftNmJh8X1IyNI,29557
68
- urwid/widget/widget_decoration.py,sha256=aHP9Y7JKVCI2dw2OdRrzMj9p--C1pMIbxSJskWBLIgc,5633
68
+ urwid/widget/widget_decoration.py,sha256=6eEPvtF7wk2n1csIBWrnXAosprFl2pZiQ7SoCpwKnJM,5736
69
69
  urwid/widget/wimp.py,sha256=4wfzTQBLMbhicSlL64hBPb-1W5FAFrIKfb43i10MKSY,27305
70
- urwid-2.6.11.dist-info/COPYING,sha256=NrbT-keRaUP9X-wxPFhHhJRgR-wTN6eLRA5ZkstZX4k,26434
71
- urwid-2.6.11.dist-info/METADATA,sha256=BdPqGaA0WgGq3ISj7YQYEMzmQKAGoFn6OBAVpJE1Fl0,11043
72
- urwid-2.6.11.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
73
- urwid-2.6.11.dist-info/top_level.txt,sha256=AwxQA43kNkjHbhYELXHBKrQ01X5CR2KnDzU07cVqilY,6
74
- urwid-2.6.11.dist-info/RECORD,,
70
+ urwid-2.6.13.dist-info/COPYING,sha256=NrbT-keRaUP9X-wxPFhHhJRgR-wTN6eLRA5ZkstZX4k,26434
71
+ urwid-2.6.13.dist-info/METADATA,sha256=ccL9AgWkfyCrgHxDpQ2LbzJ-_nB4F4DdJggInGiXOeY,11043
72
+ urwid-2.6.13.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
73
+ urwid-2.6.13.dist-info/top_level.txt,sha256=AwxQA43kNkjHbhYELXHBKrQ01X5CR2KnDzU07cVqilY,6
74
+ urwid-2.6.13.dist-info/RECORD,,
File without changes