urwid 3.0.3__py3-none-any.whl → 3.0.5__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.
@@ -38,7 +38,7 @@ class ProgressBar(Widget):
38
38
  If satt is ``None`` then no smoothing will be done.
39
39
 
40
40
  >>> from urwid import LineBox
41
- >>> pb = ProgressBar('a', 'b')
41
+ >>> pb = ProgressBar("a", "b")
42
42
  >>> pb
43
43
  <ProgressBar flow widget>
44
44
  >>> print(pb.get_text())
@@ -48,18 +48,18 @@ class ProgressBar(Widget):
48
48
  34 %
49
49
  >>> class CustomProgressBar(ProgressBar):
50
50
  ... def get_text(self):
51
- ... return u'Foobar'
52
- >>> cpb = CustomProgressBar('a', 'b')
51
+ ... return "Foobar"
52
+ >>> cpb = CustomProgressBar("a", "b")
53
53
  >>> print(cpb.get_text())
54
54
  Foobar
55
55
  >>> for x in range(101):
56
56
  ... cpb.set_completion(x)
57
- ... s = cpb.render((10, ))
58
- >>> cpb2 = CustomProgressBar('a', 'b', satt='c')
57
+ ... s = cpb.render((10,))
58
+ >>> cpb2 = CustomProgressBar("a", "b", satt="c")
59
59
  >>> for x in range(101):
60
60
  ... cpb2.set_completion(x)
61
- ... s = cpb2.render((10, ))
62
- >>> pb = ProgressBar('a', 'b', satt='c')
61
+ ... s = cpb2.render((10,))
62
+ >>> pb = ProgressBar("a", "b", satt="c")
63
63
  >>> pb.set_completion(34.56)
64
64
  >>> print(LineBox(pb).render((20,)))
65
65
  ┌──────────────────┐
@@ -22,7 +22,7 @@ class SolidFill(Widget):
22
22
  :param fill_char: character to fill area with
23
23
  :type fill_char: bytes or unicode
24
24
 
25
- >>> SolidFill(u'8')
25
+ >>> SolidFill("8")
26
26
  <SolidFill box widget '8'>
27
27
  """
28
28
  super().__init__()
@@ -39,9 +39,9 @@ class SolidFill(Widget):
39
39
  """
40
40
  Render the Fill as a canvas and return it.
41
41
 
42
- >>> SolidFill().render((4,2)).text # ... = b in Python 3
42
+ >>> SolidFill().render((4, 2)).text # ... = b in Python 3
43
43
  [...' ', ...' ']
44
- >>> SolidFill('#').render((5,3)).text
44
+ >>> SolidFill("#").render((5, 3)).text
45
45
  [...'#####', ...'#####', ...'#####']
46
46
  """
47
47
  maxcol, maxrow = size
urwid/widget/text.py CHANGED
@@ -61,9 +61,9 @@ class Text(Widget):
61
61
  :param layout: defaults to a shared :class:`StandardTextLayout` instance
62
62
  :type layout: text layout instance
63
63
 
64
- >>> Text(u"Hello")
64
+ >>> Text("Hello")
65
65
  <Text fixed/flow widget 'Hello'>
66
- >>> t = Text(('bold', u"stuff"), 'right', 'any')
66
+ >>> t = Text(("bold", "stuff"), "right", "any")
67
67
  >>> t
68
68
  <Text fixed/flow widget 'stuff' align='right' wrap='any'>
69
69
  >>> print(t.text)
@@ -73,6 +73,7 @@ class Text(Widget):
73
73
  """
74
74
  super().__init__()
75
75
  self._cache_maxcol: int | None = None
76
+ self._layout: text_layout.TextLayout = layout or text_layout.default_layout
76
77
  self.set_text(markup)
77
78
  self.set_layout(align, wrap, layout)
78
79
 
@@ -108,13 +109,13 @@ class Text(Widget):
108
109
  :param markup: see :class:`Text` for description.
109
110
  :type markup: text markup
110
111
 
111
- >>> t = Text(u"foo")
112
+ >>> t = Text("foo")
112
113
  >>> print(t.text)
113
114
  foo
114
- >>> t.set_text(u"bar")
115
+ >>> t.set_text("bar")
115
116
  >>> print(t.text)
116
117
  bar
117
- >>> t.text = u"baz" # not supported because text stores text but set_text() takes markup
118
+ >>> t.text = "baz" # not supported because text stores text but set_text() takes markup
118
119
  Traceback (most recent call last):
119
120
  AttributeError: can't set attribute
120
121
  """
@@ -132,11 +133,11 @@ class Text(Widget):
132
133
  run length encoded display attributes for *text*, eg.
133
134
  ``[('attr1', 10), ('attr2', 5)]``
134
135
 
135
- >>> Text(u"Hello").get_text() # ... = u in Python 2
136
+ >>> Text("Hello").get_text() # ... = u in Python 2
136
137
  (...'Hello', [])
137
- >>> Text(('bright', u"Headline")).get_text()
138
+ >>> Text(("bright", "Headline")).get_text()
138
139
  (...'Headline', [('bright', 8)])
139
- >>> Text([('a', u"one"), u"two", ('b', u"three")]).get_text()
140
+ >>> Text([("a", "one"), "two", ("b", "three")]).get_text()
140
141
  (...'onetwothree', [('a', 3), (None, 3), ('b', 5)])
141
142
  """
142
143
  return self._text, self._attrib
@@ -165,16 +166,16 @@ class Text(Widget):
165
166
  :param mode: typically ``'left'``, ``'center'`` or ``'right'``
166
167
  :type mode: text alignment mode
167
168
 
168
- >>> t = Text(u"word")
169
- >>> t.set_align_mode('right')
169
+ >>> t = Text("word")
170
+ >>> t.set_align_mode("right")
170
171
  >>> t.align
171
172
  'right'
172
- >>> t.render((10,)).text # ... = b in Python 3
173
+ >>> t.render((10,)).text # ... = b in Python 3
173
174
  [...' word']
174
- >>> t.align = 'center'
175
+ >>> t.align = "center"
175
176
  >>> t.render((10,)).text
176
177
  [...' word ']
177
- >>> t.align = 'somewhere'
178
+ >>> t.align = "somewhere"
178
179
  Traceback (most recent call last):
179
180
  TextError: Alignment mode 'somewhere' not supported.
180
181
  """
@@ -191,18 +192,18 @@ class Text(Widget):
191
192
  :param mode: typically ``'space'``, ``'any'``, ``'clip'`` or ``'ellipsis'``
192
193
  :type mode: text wrapping mode
193
194
 
194
- >>> t = Text(u"some words")
195
- >>> t.render((6,)).text # ... = b in Python 3
195
+ >>> t = Text("some words")
196
+ >>> t.render((6,)).text # ... = b in Python 3
196
197
  [...'some ', ...'words ']
197
- >>> t.set_wrap_mode('clip')
198
+ >>> t.set_wrap_mode("clip")
198
199
  >>> t.wrap
199
200
  'clip'
200
201
  >>> t.render((6,)).text
201
202
  [...'some w']
202
- >>> t.wrap = 'any' # Urwid 0.9.9 or later
203
+ >>> t.wrap = "any" # Urwid 0.9.9 or later
203
204
  >>> t.render((6,)).text
204
205
  [...'some w', ...'ords ']
205
- >>> t.wrap = 'somehow'
206
+ >>> t.wrap = "somehow"
206
207
  Traceback (most recent call last):
207
208
  TextError: Wrap mode 'somehow' not supported.
208
209
  """
@@ -227,8 +228,8 @@ class Text(Widget):
227
228
  :param layout: defaults to a shared :class:`StandardTextLayout` instance
228
229
  :type layout: text layout instance
229
230
 
230
- >>> t = Text(u"hi")
231
- >>> t.set_layout('right', 'clip')
231
+ >>> t = Text("hi")
232
+ >>> t.set_layout("right", "clip")
232
233
  >>> t
233
234
  <Text fixed/flow widget 'hi' align='right' wrap='clip'>
234
235
  """
@@ -255,9 +256,9 @@ class Text(Widget):
255
256
 
256
257
  See :meth:`Widget.render` for parameter details.
257
258
 
258
- >>> Text(u"important things").render((18,)).text
259
+ >>> Text("important things").render((18,)).text
259
260
  [b'important things ']
260
- >>> Text(u"important things").render((11,)).text
261
+ >>> Text("important things").render((11,)).text
261
262
  [b'important ', b'things ']
262
263
  >>> Text("demo text").render(()).text
263
264
  [b'demo text']
@@ -277,9 +278,9 @@ class Text(Widget):
277
278
 
278
279
  See :meth:`Widget.rows` for parameter details.
279
280
 
280
- >>> Text(u"important things").rows((18,))
281
+ >>> Text("important things").rows((18,))
281
282
  1
282
- >>> Text(u"important things").rows((11,))
283
+ >>> Text("important things").rows((11,))
283
284
  2
284
285
  """
285
286
  (maxcol,) = size
@@ -332,14 +333,25 @@ class Text(Widget):
332
333
  :param focus: widget is focused on
333
334
  :type focus: bool
334
335
 
335
- >>> Text(u"important things").pack()
336
+ >>> Text("important things").pack()
336
337
  (16, 1)
337
- >>> Text(u"important things").pack((15,))
338
+ >>> Text("important things").pack((15,))
338
339
  (9, 2)
339
- >>> Text(u"important things").pack((8,))
340
+ >>> Text("important things").pack((8,))
340
341
  (8, 2)
341
- >>> Text(u"important things").pack(())
342
+ >>> Text("important things").pack(())
342
343
  (16, 1)
344
+ >>> not_common_separated_text = "Line feed\\nLine Separator\\u2028Paragraph Separator\\u2029"
345
+ >>> # \u2028 (Line Separator) and \u2029 (Paragraph Separator) are not splitted by StandardTextLayout
346
+ >>> not_common_separated = Text(not_common_separated_text)
347
+
348
+ >>> not_common_separated.pack()
349
+ (33, 2)
350
+ >>> not_common_separated_canv = not_common_separated.render(())
351
+ >>> not_common_separated_canv.cols()
352
+ 33
353
+ >>> not_common_separated_canv.rows()
354
+ 2
343
355
  """
344
356
  text, attr = self.get_text()
345
357
 
@@ -356,8 +368,10 @@ class Text(Widget):
356
368
  if isinstance(text, bytes):
357
369
  text = text.decode(get_encoding())
358
370
 
371
+ split_text = text.split("\n")
372
+
359
373
  return (
360
- max(calc_width(line, 0, len(line)) for line in text.splitlines(keepends=False)),
361
- text.count("\n") + 1,
374
+ max(calc_width(line, 0, len(line)) for line in split_text),
375
+ len(split_text),
362
376
  )
363
377
  return 0, 1
urwid/widget/widget.py CHANGED
@@ -678,12 +678,12 @@ class WidgetWrap(delegate_to_widget_mixin("_wrapped_widget"), typing.Generic[Wra
678
678
  only by subclasses.
679
679
 
680
680
  >>> size = (10,)
681
- >>> ww = WidgetWrap(Edit("hello? ","hi"))
682
- >>> ww.render(size).text # ... = b in Python 3
681
+ >>> ww = WidgetWrap(Edit("hello? ", "hi"))
682
+ >>> ww.render(size).text # ... = b in Python 3
683
683
  [...'hello? hi ']
684
684
  >>> ww.selectable()
685
685
  True
686
- >>> ww._w = Text("goodbye") # calls _set_w()
686
+ >>> ww._w = Text("goodbye") # calls _set_w()
687
687
  >>> ww.render(size).text
688
688
  [...'goodbye ']
689
689
  >>> ww.selectable()
@@ -698,12 +698,12 @@ class WidgetWrap(delegate_to_widget_mixin("_wrapped_widget"), typing.Generic[Wra
698
698
  only by subclasses.
699
699
  >>> from urwid import Edit, Text
700
700
  >>> size = (10,)
701
- >>> ww = WidgetWrap(Edit("hello? ","hi"))
702
- >>> ww.render(size).text # ... = b in Python 3
701
+ >>> ww = WidgetWrap(Edit("hello? ", "hi"))
702
+ >>> ww.render(size).text # ... = b in Python 3
703
703
  [...'hello? hi ']
704
704
  >>> ww.selectable()
705
705
  True
706
- >>> ww._w = Text("goodbye") # calls _set_w()
706
+ >>> ww._w = Text("goodbye") # calls _set_w()
707
707
  >>> ww.render(size).text
708
708
  [...'goodbye ']
709
709
  >>> ww.selectable()
@@ -37,7 +37,7 @@ class WidgetDecoration(Widget, typing.Generic[WrappedWidget]): # pylint: disabl
37
37
  Don't actually do this -- use a WidgetDecoration subclass instead, these are not real widgets:
38
38
 
39
39
  >>> from urwid import Text
40
- >>> WidgetDecoration(Text(u"hi"))
40
+ >>> WidgetDecoration(Text("hi"))
41
41
  <WidgetDecoration fixed/flow widget <Text fixed/flow widget 'hi'>>
42
42
 
43
43
  .. Warning:
@@ -79,7 +79,7 @@ class WidgetDecoration(Widget, typing.Generic[WrappedWidget]): # pylint: disabl
79
79
  If there is only one Decoration, then this is the same as original_widget.
80
80
 
81
81
  >>> from urwid import Text
82
- >>> t = Text('hello')
82
+ >>> t = Text("hello")
83
83
  >>> wd1 = WidgetDecoration(t)
84
84
  >>> wd2 = WidgetDecoration(wd1)
85
85
  >>> wd3 = WidgetDecoration(wd2)
urwid/widget/wimp.py CHANGED
@@ -84,7 +84,7 @@ class SelectableIcon(Text):
84
84
  Render the text content of this widget with a cursor when
85
85
  in focus.
86
86
 
87
- >>> si = SelectableIcon(u"[!]")
87
+ >>> si = SelectableIcon("[!]")
88
88
  >>> si
89
89
  <SelectableIcon selectable fixed/flow widget '[!]'>
90
90
  >>> si.render((4,), focus=True).cursor
@@ -170,10 +170,10 @@ class CheckBox(WidgetWrap[Columns]):
170
170
  def __init__(
171
171
  self,
172
172
  label: str | tuple[Hashable, str] | list[str | tuple[Hashable, str]],
173
- state: bool = False,
174
- has_mixed: typing.Literal[False] = False,
175
- on_state_change: Callable[[Self, bool], typing.Any] | None = None,
176
- user_data: None = None,
173
+ state: typing.Literal["mixed"] | bool = False,
174
+ has_mixed: typing.Literal[True] = True,
175
+ on_state_change: Callable[[Self, bool | typing.Literal["mixed"], _T], typing.Any] | None = None,
176
+ user_data: _T = ...,
177
177
  checked_symbol: str | None = ...,
178
178
  ) -> None: ...
179
179
 
@@ -181,10 +181,10 @@ class CheckBox(WidgetWrap[Columns]):
181
181
  def __init__(
182
182
  self,
183
183
  label: str | tuple[Hashable, str] | list[str | tuple[Hashable, str]],
184
- state: typing.Literal["mixed"] | bool = False,
185
- has_mixed: typing.Literal[True] = True,
186
- on_state_change: Callable[[Self, bool | typing.Literal["mixed"], _T], typing.Any] | None = None,
187
- user_data: _T = ...,
184
+ state: bool = False,
185
+ has_mixed: typing.Literal[False] = False,
186
+ on_state_change: Callable[[Self, bool], typing.Any] | None = None,
187
+ user_data: None = None,
188
188
  checked_symbol: str | None = ...,
189
189
  ) -> None: ...
190
190
 
@@ -206,8 +206,8 @@ class CheckBox(WidgetWrap[Columns]):
206
206
  has_mixed: typing.Literal[False, True] = False, # MyPy issue: Literal[True, False] is not equal `bool`
207
207
  on_state_change: (
208
208
  Callable[[Self, bool, _T], typing.Any]
209
- | Callable[[Self, bool], typing.Any]
210
209
  | Callable[[Self, bool | typing.Literal["mixed"], _T], typing.Any]
210
+ | Callable[[Self, bool], typing.Any]
211
211
  | Callable[[Self, bool | typing.Literal["mixed"]], typing.Any]
212
212
  | None
213
213
  ) = None,
@@ -228,12 +228,12 @@ class CheckBox(WidgetWrap[Columns]):
228
228
 
229
229
  Register signal handler with::
230
230
 
231
- urwid.connect_signal(check_box, 'change', callback, user_data)
231
+ urwid.connect_signal(check_box, "change", callback, user_data)
232
232
 
233
233
  where callback is callback(check_box, new_state [,user_data])
234
234
  Unregister signal handlers with::
235
235
 
236
- urwid.disconnect_signal(check_box, 'change', callback, user_data)
236
+ urwid.disconnect_signal(check_box, "change", callback, user_data)
237
237
 
238
238
  >>> CheckBox("Confirm")
239
239
  <CheckBox selectable fixed/flow widget 'Confirm' state=False>
@@ -303,10 +303,10 @@ class CheckBox(WidgetWrap[Columns]):
303
303
  label -- markup for label. See Text widget for description
304
304
  of text markup.
305
305
 
306
- >>> cb = CheckBox(u"foo")
306
+ >>> cb = CheckBox("foo")
307
307
  >>> cb
308
308
  <CheckBox selectable fixed/flow widget 'foo' state=False>
309
- >>> cb.set_label(('bright_attr', u"bar"))
309
+ >>> cb.set_label(("bright_attr", "bar"))
310
310
  >>> cb
311
311
  <CheckBox selectable fixed/flow widget 'bar' state=False>
312
312
  """
@@ -318,12 +318,12 @@ class CheckBox(WidgetWrap[Columns]):
318
318
  """
319
319
  Return label text.
320
320
 
321
- >>> cb = CheckBox(u"Seriously")
321
+ >>> cb = CheckBox("Seriously")
322
322
  >>> print(cb.get_label())
323
323
  Seriously
324
324
  >>> print(cb.label)
325
325
  Seriously
326
- >>> cb.set_label([('bright_attr', u"flashy"), u" normal"])
326
+ >>> cb.set_label([("bright_attr", "flashy"), " normal"])
327
327
  >>> print(cb.label) # only text is returned
328
328
  flashy normal
329
329
  """
@@ -348,20 +348,20 @@ class CheckBox(WidgetWrap[Columns]):
348
348
  ... changes.append("A %r %r" % (state, user_data))
349
349
  >>> def callback_b(cb, state):
350
350
  ... changes.append("B %r" % state)
351
- >>> cb = CheckBox('test', False, False)
352
- >>> key1 = connect_signal(cb, 'change', callback_a, user_args=("user_a",))
353
- >>> key2 = connect_signal(cb, 'change', callback_b)
354
- >>> cb.set_state(True) # both callbacks will be triggered
351
+ >>> cb = CheckBox("test", False, False)
352
+ >>> key1 = connect_signal(cb, "change", callback_a, user_args=("user_a",))
353
+ >>> key2 = connect_signal(cb, "change", callback_b)
354
+ >>> cb.set_state(True) # both callbacks will be triggered
355
355
  >>> cb.state
356
356
  True
357
- >>> disconnect_signal(cb, 'change', callback_a, user_args=("user_a",))
357
+ >>> disconnect_signal(cb, "change", callback_a, user_args=("user_a",))
358
358
  >>> cb.state = False
359
359
  >>> cb.state
360
360
  False
361
361
  >>> cb.set_state(True)
362
362
  >>> cb.state
363
363
  True
364
- >>> cb.set_state(False, False) # don't send signal
364
+ >>> cb.set_state(False, False) # don't send signal
365
365
  >>> changes
366
366
  ["A True 'user_a'", 'B True', 'B False', 'B True']
367
367
  """
@@ -392,16 +392,16 @@ class CheckBox(WidgetWrap[Columns]):
392
392
  """
393
393
  Toggle state on 'activate' command.
394
394
 
395
- >>> assert CheckBox._command_map[' '] == 'activate'
396
- >>> assert CheckBox._command_map['enter'] == 'activate'
395
+ >>> assert CheckBox._command_map[" "] == "activate"
396
+ >>> assert CheckBox._command_map["enter"] == "activate"
397
397
  >>> size = (10,)
398
- >>> cb = CheckBox('press me')
398
+ >>> cb = CheckBox("press me")
399
399
  >>> cb.state
400
400
  False
401
- >>> cb.keypress(size, ' ')
401
+ >>> cb.keypress(size, " ")
402
402
  >>> cb.state
403
403
  True
404
- >>> cb.keypress(size, ' ')
404
+ >>> cb.keypress(size, " ")
405
405
  >>> cb.state
406
406
  False
407
407
  """
@@ -446,7 +446,7 @@ class CheckBox(WidgetWrap[Columns]):
446
446
  >>> cb = CheckBox("clickme")
447
447
  >>> cb.state
448
448
  False
449
- >>> cb.mouse_event(size, 'mouse press', 1, 2, 0, True)
449
+ >>> cb.mouse_event(size, "mouse press", 1, 2, 0, True)
450
450
  True
451
451
  >>> cb.state
452
452
  True
@@ -510,23 +510,23 @@ class RadioButton(CheckBox):
510
510
 
511
511
  Register signal handler with::
512
512
 
513
- urwid.connect_signal(radio_button, 'change', callback, user_data)
513
+ urwid.connect_signal(radio_button, "change", callback, user_data)
514
514
 
515
515
  where callback is callback(radio_button, new_state [,user_data])
516
516
  Unregister signal handlers with::
517
517
 
518
- urwid.disconnect_signal(radio_button, 'change', callback, user_data)
518
+ urwid.disconnect_signal(radio_button, "change", callback, user_data)
519
519
 
520
- >>> bgroup = [] # button group
521
- >>> b1 = RadioButton(bgroup, u"Agree")
522
- >>> b2 = RadioButton(bgroup, u"Disagree")
520
+ >>> bgroup = [] # button group
521
+ >>> b1 = RadioButton(bgroup, "Agree")
522
+ >>> b2 = RadioButton(bgroup, "Disagree")
523
523
  >>> len(bgroup)
524
524
  2
525
525
  >>> b1
526
526
  <RadioButton selectable fixed/flow widget 'Agree' state=True>
527
527
  >>> b2
528
528
  <RadioButton selectable fixed/flow widget 'Disagree' state=False>
529
- >>> b2.render((15,), focus=True).text # ... = b in Python 3
529
+ >>> b2.render((15,), focus=True).text # ... = b in Python 3
530
530
  [...'( ) Disagree ']
531
531
  """
532
532
  if state == "first True":
@@ -547,21 +547,21 @@ class RadioButton(CheckBox):
547
547
  If state is True all other radio buttons in the same button
548
548
  group will be set to False.
549
549
 
550
- >>> bgroup = [] # button group
551
- >>> b1 = RadioButton(bgroup, u"Agree")
552
- >>> b2 = RadioButton(bgroup, u"Disagree")
553
- >>> b3 = RadioButton(bgroup, u"Unsure")
550
+ >>> bgroup = [] # button group
551
+ >>> b1 = RadioButton(bgroup, "Agree")
552
+ >>> b2 = RadioButton(bgroup, "Disagree")
553
+ >>> b3 = RadioButton(bgroup, "Unsure")
554
554
  >>> b1.state, b2.state, b3.state
555
555
  (True, False, False)
556
556
  >>> b2.set_state(True)
557
557
  >>> b1.state, b2.state, b3.state
558
558
  (False, True, False)
559
559
  >>> def relabel_button(radio_button, new_state):
560
- ... radio_button.set_label(u"Think Harder!")
561
- >>> key = connect_signal(b3, 'change', relabel_button)
560
+ ... radio_button.set_label("Think Harder!")
561
+ >>> key = connect_signal(b3, "change", relabel_button)
562
562
  >>> b3
563
563
  <RadioButton selectable fixed/flow widget 'Unsure' state=False>
564
- >>> b3.set_state(True) # this will trigger the callback
564
+ >>> b3.set_state(True) # this will trigger the callback
565
565
  >>> b3
566
566
  <RadioButton selectable fixed/flow widget 'Think Harder!' state=True>
567
567
  """
@@ -586,7 +586,7 @@ class RadioButton(CheckBox):
586
586
  """
587
587
  Set state to True.
588
588
 
589
- >>> bgroup = [] # button group
589
+ >>> bgroup = [] # button group
590
590
  >>> b1 = RadioButton(bgroup, "Agree")
591
591
  >>> b2 = RadioButton(bgroup, "Disagree")
592
592
  >>> b1.state, b2.state
@@ -659,25 +659,25 @@ class Button(WidgetWrap[Columns]):
659
659
 
660
660
  Register signal handler with::
661
661
 
662
- urwid.connect_signal(button, 'click', callback, user_data)
662
+ urwid.connect_signal(button, "click", callback, user_data)
663
663
 
664
664
  where callback is callback(button [,user_data])
665
665
  Unregister signal handlers with::
666
666
 
667
- urwid.disconnect_signal(button, 'click', callback, user_data)
667
+ urwid.disconnect_signal(button, "click", callback, user_data)
668
668
 
669
669
  >>> from urwid.util import set_temporary_encoding
670
- >>> Button(u"Ok")
670
+ >>> Button("Ok")
671
671
  <Button selectable fixed/flow widget 'Ok'>
672
672
  >>> b = Button("Cancel")
673
- >>> b.render((15,), focus=True).text # ... = b in Python 3
673
+ >>> b.render((15,), focus=True).text # ... = b in Python 3
674
674
  [b'< Cancel >']
675
675
  >>> aligned_button = Button("Test", align=Align.CENTER)
676
676
  >>> aligned_button.render((10,), focus=True).text
677
677
  [b'< Test >']
678
678
  >>> wrapped_button = Button("Long label", wrap=WrapMode.ELLIPSIS)
679
679
  >>> with set_temporary_encoding("utf-8"):
680
- ... wrapped_button.render((7,), focus=False).text[0].decode('utf-8')
680
+ ... wrapped_button.render((7,), focus=False).text[0].decode("utf-8")
681
681
  '< Lo… >'
682
682
  """
683
683
  self._label = SelectableIcon(label, 0, align=align, wrap=wrap, layout=layout)
@@ -719,7 +719,7 @@ class Button(WidgetWrap[Columns]):
719
719
  label -- markup for button label
720
720
 
721
721
  >>> b = Button("Ok")
722
- >>> b.set_label(u"Yup yup")
722
+ >>> b.set_label("Yup yup")
723
723
  >>> b
724
724
  <Button selectable fixed/flow widget 'Yup yup'>
725
725
  """
@@ -729,7 +729,7 @@ class Button(WidgetWrap[Columns]):
729
729
  """
730
730
  Return label text.
731
731
 
732
- >>> b = Button(u"Ok")
732
+ >>> b = Button("Ok")
733
733
  >>> print(b.get_label())
734
734
  Ok
735
735
  >>> print(b.label)
@@ -743,17 +743,17 @@ class Button(WidgetWrap[Columns]):
743
743
  """
744
744
  Send 'click' signal on 'activate' command.
745
745
 
746
- >>> assert Button._command_map[' '] == 'activate'
747
- >>> assert Button._command_map['enter'] == 'activate'
746
+ >>> assert Button._command_map[" "] == "activate"
747
+ >>> assert Button._command_map["enter"] == "activate"
748
748
  >>> size = (15,)
749
- >>> b = Button(u"Cancel")
749
+ >>> b = Button("Cancel")
750
750
  >>> clicked_buttons = []
751
751
  >>> def handle_click(button):
752
752
  ... clicked_buttons.append(button.label)
753
- >>> key = connect_signal(b, 'click', handle_click)
754
- >>> b.keypress(size, 'enter')
755
- >>> b.keypress(size, ' ')
756
- >>> clicked_buttons # ... = u in Python 2
753
+ >>> key = connect_signal(b, "click", handle_click)
754
+ >>> b.keypress(size, "enter")
755
+ >>> b.keypress(size, " ")
756
+ >>> clicked_buttons # ... = u in Python 2
757
757
  [...'Cancel', ...'Cancel']
758
758
  """
759
759
  if self._command_map[key] != Command.ACTIVATE:
@@ -767,16 +767,16 @@ class Button(WidgetWrap[Columns]):
767
767
  Send 'click' signal on button 1 press.
768
768
 
769
769
  >>> size = (15,)
770
- >>> b = Button(u"Ok")
770
+ >>> b = Button("Ok")
771
771
  >>> clicked_buttons = []
772
772
  >>> def handle_click(button):
773
773
  ... clicked_buttons.append(button.label)
774
- >>> key = connect_signal(b, 'click', handle_click)
775
- >>> b.mouse_event(size, 'mouse press', 1, 4, 0, True)
774
+ >>> key = connect_signal(b, "click", handle_click)
775
+ >>> b.mouse_event(size, "mouse press", 1, 4, 0, True)
776
776
  True
777
- >>> b.mouse_event(size, 'mouse press', 2, 4, 0, True) # ignored
777
+ >>> b.mouse_event(size, "mouse press", 2, 4, 0, True) # ignored
778
778
  False
779
- >>> clicked_buttons # ... = u in Python 2
779
+ >>> clicked_buttons # ... = u in Python 2
780
780
  [...'Ok']
781
781
  """
782
782
  if button != 1 or not is_mouse_press(event):
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: urwid
3
- Version: 3.0.3
3
+ Version: 3.0.5
4
4
  Summary: A full-featured console (xterm et al.) user interface library
5
5
  Author-email: Ian Ward <ian@excess.org>
6
- License: LGPL-2.1-only
6
+ License-Expression: LGPL-2.1-only
7
7
  Project-URL: Homepage, https://urwid.org/
8
8
  Project-URL: Documentation, https://urwid.org/manual/index.html
9
9
  Project-URL: Repository, https://github.com/urwid/urwid
@@ -14,7 +14,6 @@ Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Environment :: Console
15
15
  Classifier: Environment :: Console :: Curses
16
16
  Classifier: Intended Audience :: Developers
17
- Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
18
17
  Classifier: Operating System :: POSIX
19
18
  Classifier: Operating System :: Unix
20
19
  Classifier: Operating System :: MacOS :: MacOS X
@@ -27,13 +26,14 @@ Classifier: Programming Language :: Python :: 3.10
27
26
  Classifier: Programming Language :: Python :: 3.11
28
27
  Classifier: Programming Language :: Python :: 3.12
29
28
  Classifier: Programming Language :: Python :: 3.13
29
+ Classifier: Programming Language :: Python :: 3.14
30
30
  Classifier: Programming Language :: Python :: 3 :: Only
31
31
  Classifier: Programming Language :: Python :: Implementation :: CPython
32
32
  Classifier: Programming Language :: Python :: Implementation :: PyPy
33
33
  Requires-Python: >=3.9.0
34
34
  Description-Content-Type: text/x-rst
35
35
  License-File: COPYING
36
- Requires-Dist: wcwidth
36
+ Requires-Dist: wcwidth>=0.4
37
37
  Provides-Extra: curses
38
38
  Requires-Dist: windows-curses; sys_platform == "win32" and extra == "curses"
39
39
  Provides-Extra: glib
@@ -74,7 +74,7 @@ It includes many features useful for text console application developers includi
74
74
  - Display modules include raw, curses, and experimental LCD and web displays
75
75
  - Support for UTF-8, simple 8-bit and CJK encodings
76
76
  - 24-bit (true color), 256 color, and 88 color mode support
77
- - Compatible with Python 3.7+ and PyPy
77
+ - Compatible with Python 3.9+ and PyPy
78
78
 
79
79
  Home Page:
80
80
  http://urwid.org/
@@ -147,6 +147,7 @@ Supported Python versions
147
147
  - 3.11
148
148
  - 3.12
149
149
  - 3.13
150
+ - 3.14
150
151
  - pypy3
151
152
 
152
153
  Authors