urwid 2.6.15__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.
Files changed (62) hide show
  1. urwid/__init__.py +30 -20
  2. urwid/canvas.py +34 -53
  3. urwid/command_map.py +6 -4
  4. urwid/container.py +1 -1
  5. urwid/decoration.py +1 -1
  6. urwid/display/__init__.py +53 -48
  7. urwid/display/_posix_raw_display.py +20 -8
  8. urwid/display/_raw_display_base.py +21 -16
  9. urwid/display/_win32_raw_display.py +16 -17
  10. urwid/display/common.py +45 -74
  11. urwid/display/curses.py +3 -5
  12. urwid/display/escape.py +28 -13
  13. urwid/display/lcd.py +8 -10
  14. urwid/display/web.py +11 -16
  15. urwid/event_loop/asyncio_loop.py +35 -15
  16. urwid/event_loop/main_loop.py +18 -23
  17. urwid/event_loop/tornado_loop.py +4 -5
  18. urwid/event_loop/trio_loop.py +1 -1
  19. urwid/font.py +19 -22
  20. urwid/numedit.py +65 -65
  21. urwid/signals.py +19 -27
  22. urwid/split_repr.py +9 -3
  23. urwid/str_util.py +105 -60
  24. urwid/text_layout.py +14 -13
  25. urwid/util.py +8 -19
  26. urwid/version.py +22 -4
  27. urwid/vterm.py +20 -47
  28. urwid/widget/__init__.py +0 -6
  29. urwid/widget/attr_map.py +10 -10
  30. urwid/widget/attr_wrap.py +11 -13
  31. urwid/widget/bar_graph.py +3 -8
  32. urwid/widget/big_text.py +8 -9
  33. urwid/widget/box_adapter.py +6 -6
  34. urwid/widget/columns.py +52 -83
  35. urwid/widget/container.py +29 -75
  36. urwid/widget/divider.py +6 -6
  37. urwid/widget/edit.py +50 -50
  38. urwid/widget/filler.py +14 -14
  39. urwid/widget/frame.py +31 -40
  40. urwid/widget/grid_flow.py +25 -110
  41. urwid/widget/line_box.py +31 -18
  42. urwid/widget/listbox.py +16 -51
  43. urwid/widget/monitored_list.py +75 -49
  44. urwid/widget/overlay.py +4 -37
  45. urwid/widget/padding.py +31 -68
  46. urwid/widget/pile.py +179 -158
  47. urwid/widget/popup.py +2 -2
  48. urwid/widget/progress_bar.py +17 -18
  49. urwid/widget/scrollable.py +26 -34
  50. urwid/widget/solid_fill.py +3 -3
  51. urwid/widget/text.py +44 -30
  52. urwid/widget/treetools.py +27 -48
  53. urwid/widget/widget.py +13 -130
  54. urwid/widget/widget_decoration.py +6 -35
  55. urwid/widget/wimp.py +61 -61
  56. urwid/wimp.py +1 -1
  57. {urwid-2.6.15.dist-info → urwid-3.0.5.dist-info}/METADATA +24 -24
  58. urwid-3.0.5.dist-info/RECORD +74 -0
  59. {urwid-2.6.15.dist-info → urwid-3.0.5.dist-info}/WHEEL +1 -1
  60. urwid-2.6.15.dist-info/RECORD +0 -74
  61. {urwid-2.6.15.dist-info → urwid-3.0.5.dist-info/licenses}/COPYING +0 -0
  62. {urwid-2.6.15.dist-info → urwid-3.0.5.dist-info}/top_level.txt +0 -0
urwid/display/web.py CHANGED
@@ -21,6 +21,7 @@
21
21
  """
22
22
  Urwid web application display module
23
23
  """
24
+
24
25
  from __future__ import annotations
25
26
 
26
27
  import dataclasses
@@ -216,7 +217,7 @@ class Screen(BaseScreen):
216
217
  sys.stdout.write("Status: 503 Sever Busy\r\n\r\n")
217
218
  sys.exit(0)
218
219
 
219
- urwid_id = f"{random.randrange(10 ** 9):09d}{random.randrange(10 ** 9):09d}" # noqa: S311
220
+ urwid_id = f"{random.randrange(10**9):09d}{random.randrange(10**9):09d}" # noqa: S311
220
221
  self.pipe_name = os.path.join(_prefs.pipe_dir, f"urwid{urwid_id}")
221
222
  os.mkfifo(f"{self.pipe_name}.in", 0o600)
222
223
  signal.signal(signal.SIGTERM, self._cleanup_pipe)
@@ -224,11 +225,7 @@ class Screen(BaseScreen):
224
225
  self.input_fd = os.open(f"{self.pipe_name}.in", os.O_NONBLOCK | os.O_RDONLY)
225
226
  self.input_tail = ""
226
227
  self.content_head = (
227
- "Content-type: "
228
- "multipart/x-mixed-replace;boundary=ZZ\r\n"
229
- "X-Urwid-ID: " + urwid_id + "\r\n"
230
- "\r\n\r\n"
231
- "--ZZ\r\n"
228
+ f"Content-type: multipart/x-mixed-replace;boundary=ZZ\r\nX-Urwid-ID: {urwid_id}\r\n\r\n\r\n--ZZ\r\n"
232
229
  )
233
230
  if self.update_method == "polling":
234
231
  self.content_head = f"Content-type: text/plain\r\nX-Urwid-ID: {urwid_id}\r\n\r\n\r\n"
@@ -328,8 +325,8 @@ class Screen(BaseScreen):
328
325
  if y == cy:
329
326
  sig = (*sig, cx)
330
327
  new_screen[sig] = [*new_screen.get(sig, []), y]
331
- old_line_numbers = self.last_screen.get(sig, None)
332
- if old_line_numbers is not None:
328
+
329
+ if (old_line_numbers := self.last_screen.get(sig, None)) is not None:
333
330
  if y in old_line_numbers:
334
331
  old_line = y
335
332
  else:
@@ -459,7 +456,7 @@ class Screen(BaseScreen):
459
456
  return pending_input
460
457
 
461
458
 
462
- def code_span(s, fg, bg, cursor=-1) -> str:
459
+ def code_span(s: str, fg: str, bg: str, cursor: int = -1) -> str:
463
460
  code_fg = _code_colours[fg]
464
461
  code_bg = _code_colours[bg]
465
462
 
@@ -495,8 +492,8 @@ def is_web_request() -> bool:
495
492
  def handle_short_request() -> bool:
496
493
  """
497
494
  Handle short requests such as passing keystrokes to the application
498
- or sending the initial html page. If returns True, then this
499
- function recognised and handled a short request, and the calling
495
+ or sending the initial HTML page. If returns True, then this
496
+ function recognized and handled a short request, and the calling
500
497
  script should immediately exit.
501
498
 
502
499
  web_display.set_preferences(..) should be called before calling this
@@ -609,20 +606,18 @@ def daemonize(errfile: str) -> None:
609
606
  """
610
607
  Detach process and become a daemon.
611
608
  """
612
- pid = os.fork()
613
- if pid:
609
+ if os.fork():
614
610
  os._exit(0)
615
611
 
616
612
  os.setsid()
617
613
  signal.signal(signal.SIGHUP, signal.SIG_IGN)
618
614
  os.umask(0)
619
615
 
620
- pid = os.fork()
621
- if pid:
616
+ if os.fork():
622
617
  os._exit(0)
623
618
 
624
619
  os.chdir("/")
625
- for fd in range(0, 20):
620
+ for fd in range(20):
626
621
  with suppress(OSError):
627
622
  os.close(fd)
628
623
 
@@ -41,7 +41,6 @@ if typing.TYPE_CHECKING:
41
41
  _T = typing.TypeVar("_T")
42
42
 
43
43
  __all__ = ("AsyncioEventLoop",)
44
- IS_WINDOWS = sys.platform == "win32"
45
44
 
46
45
 
47
46
  class AsyncioEventLoop(EventLoop):
@@ -67,20 +66,39 @@ class AsyncioEventLoop(EventLoop):
67
66
  def __init__(self, *, loop: asyncio.AbstractEventLoop | None = None, **kwargs) -> None:
68
67
  super().__init__()
69
68
  self.logger = logging.getLogger(__name__).getChild(self.__class__.__name__)
70
- if loop:
71
- self._loop: asyncio.AbstractEventLoop = loop
69
+
70
+ if sys.version_info[:2] < (3, 11):
72
71
  self._event_loop_policy_altered: bool = False
73
72
  self._original_event_loop_policy: asyncio.AbstractEventLoopPolicy | None = None
74
- else:
75
- self._original_event_loop_policy = asyncio.get_event_loop_policy()
76
- if IS_WINDOWS and not isinstance(self._original_event_loop_policy, asyncio.WindowsSelectorEventLoopPolicy):
77
- self.logger.debug("Set WindowsSelectorEventLoopPolicy as asyncio event loop policy")
78
- asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
79
- self._event_loop_policy_altered = True
73
+
74
+ if loop:
75
+ self._loop: asyncio.AbstractEventLoop = loop
80
76
  else:
81
- self._event_loop_policy_altered = False
77
+ self._original_event_loop_policy = asyncio.get_event_loop_policy()
78
+ if sys.platform == "win32" and not isinstance(
79
+ self._original_event_loop_policy, asyncio.WindowsSelectorEventLoopPolicy
80
+ ):
81
+ self.logger.debug("Set WindowsSelectorEventLoopPolicy as asyncio event loop policy")
82
+ asyncio.set_event_loop_policy(
83
+ asyncio.WindowsSelectorEventLoopPolicy() # pylint: disable=deprecated-class
84
+ )
85
+ self._event_loop_policy_altered = True
86
+ else:
87
+ self._event_loop_policy_altered = False
88
+
89
+ self._loop = asyncio.get_event_loop()
82
90
 
83
- self._loop = asyncio.get_event_loop()
91
+ else:
92
+ self._runner: asyncio.Runner | None = None
93
+
94
+ if loop:
95
+ self._loop: asyncio.AbstractEventLoop = loop
96
+ else:
97
+ try:
98
+ self._loop = asyncio.get_running_loop()
99
+ except RuntimeError:
100
+ self._runner = asyncio.Runner(loop_factory=asyncio.SelectorEventLoop)
101
+ self._loop = self._runner.get_loop()
84
102
 
85
103
  self._exc: BaseException | None = None
86
104
 
@@ -89,8 +107,11 @@ class AsyncioEventLoop(EventLoop):
89
107
  self._idle_callbacks: dict[int, Callable[[], typing.Any]] = {}
90
108
 
91
109
  def __del__(self) -> None:
92
- if self._event_loop_policy_altered:
93
- asyncio.set_event_loop_policy(self._original_event_loop_policy) # Restore default event loop policy
110
+ if sys.version_info[:2] < (3, 11):
111
+ if self._event_loop_policy_altered:
112
+ asyncio.set_event_loop_policy(self._original_event_loop_policy) # Restore default event loop policy
113
+ elif self._runner is not None:
114
+ self._runner.close()
94
115
 
95
116
  def _also_call_idle(self, callback: Callable[_Spec, _T]) -> Callable[_Spec, _T]:
96
117
  """
@@ -205,8 +226,7 @@ class AsyncioEventLoop(EventLoop):
205
226
  return True
206
227
 
207
228
  def _exception_handler(self, loop: asyncio.AbstractEventLoop, context):
208
- exc = context.get("exception")
209
- if exc:
229
+ if exc := context.get("exception"):
210
230
  loop.stop()
211
231
 
212
232
  if self._idle_asyncio_handle:
@@ -172,7 +172,8 @@ class MainLoop:
172
172
  def _set_widget(self, widget: Widget) -> None:
173
173
  warnings.warn(
174
174
  f"method `{self.__class__.__name__}._set_widget` is deprecated, "
175
- f"please use `{self.__class__.__name__}.widget` property",
175
+ f"please use `{self.__class__.__name__}.widget` property."
176
+ "API will be removed in version 4.0.",
176
177
  DeprecationWarning,
177
178
  stacklevel=2,
178
179
  )
@@ -193,7 +194,8 @@ class MainLoop:
193
194
  def _set_pop_ups(self, pop_ups: bool) -> None:
194
195
  warnings.warn(
195
196
  f"method `{self.__class__.__name__}._set_pop_ups` is deprecated, "
196
- f"please use `{self.__class__.__name__}.pop_ups` property",
197
+ f"please use `{self.__class__.__name__}.pop_ups` property."
198
+ "API will be removed in version 4.0.",
197
199
  DeprecationWarning,
198
200
  stacklevel=2,
199
201
  )
@@ -338,7 +340,7 @@ class MainLoop:
338
340
 
339
341
  def _test_run(self):
340
342
  """
341
- >>> w = _refl("widget") # _refl prints out function calls
343
+ >>> w = _refl("widget") # _refl prints out function calls
342
344
  >>> w.render_rval = "fake canvas" # *_rval is used for return values
343
345
  >>> scr = _refl("screen")
344
346
  >>> scr.get_input_descriptors_rval = [42]
@@ -349,7 +351,7 @@ class MainLoop:
349
351
  >>> evl.enter_idle_rval = 1
350
352
  >>> evl.watch_file_rval = 2
351
353
  >>> ml = MainLoop(w, [], scr, event_loop=evl)
352
- >>> ml.run() # doctest:+ELLIPSIS
354
+ >>> ml.run() # doctest:+ELLIPSIS
353
355
  screen.start()
354
356
  screen.set_mouse_tracking()
355
357
  screen.unhook_event_loop(...)
@@ -359,7 +361,7 @@ class MainLoop:
359
361
  event_loop.remove_enter_idle(1)
360
362
  screen.unhook_event_loop(...)
361
363
  screen.stop()
362
- >>> ml.draw_screen() # doctest:+ELLIPSIS
364
+ >>> ml.draw_screen() # doctest:+ELLIPSIS
363
365
  screen.get_cols_rows()
364
366
  widget.render((20, 10), focus=True)
365
367
  screen.draw_screen((20, 10), 'fake canvas')
@@ -452,7 +454,7 @@ class MainLoop:
452
454
  >>> evl = _refl("event_loop")
453
455
  >>> ml = MainLoop(w, [], scr, event_loop=evl)
454
456
  >>> ml._input_timeout = "old timeout"
455
- >>> ml._update(['y'], [121]) # doctest:+ELLIPSIS
457
+ >>> ml._update(["y"], [121]) # doctest:+ELLIPSIS
456
458
  screen.get_cols_rows()
457
459
  widget.selectable()
458
460
  widget.keypress((15, 5), 'y')
@@ -460,9 +462,7 @@ class MainLoop:
460
462
  widget.mouse_event((15, 5), 'mouse press', 1, 5, 4, focus=True)
461
463
  >>> ml._update([], [])
462
464
  """
463
- keys = self.input_filter(keys, raw)
464
-
465
- if keys:
465
+ if keys := self.input_filter(keys, raw):
466
466
  self.process_input(keys)
467
467
  if "window resize" in keys:
468
468
  self.screen_size = None
@@ -493,19 +493,14 @@ class MainLoop:
493
493
  else:
494
494
  self.screen.set_input_timeouts(None)
495
495
  keys, raw = self.screen.get_input(True)
496
- if not keys and next_alarm:
497
- sec = next_alarm[0] - time.time()
498
- if sec <= 0:
499
- break
500
-
501
- keys = self.input_filter(keys, raw)
496
+ if not keys and next_alarm and next_alarm[0] - time.time() <= 0:
497
+ break
502
498
 
503
- if keys:
499
+ if keys := self.input_filter(keys, raw):
504
500
  self.process_input(keys)
505
501
 
506
502
  while next_alarm:
507
- sec = next_alarm[0] - time.time()
508
- if sec > 0:
503
+ if (next_alarm[0] - time.time()) > 0:
509
504
  break
510
505
  _tm, _tie_break, callback = next_alarm
511
506
  callback()
@@ -563,13 +558,13 @@ class MainLoop:
563
558
 
564
559
  if isinstance(key, str):
565
560
  if self._topmost_widget.selectable():
566
- handled_key = self._topmost_widget.keypress(self.screen_size, key)
567
- if not handled_key:
561
+ if handled_key := self._topmost_widget.keypress(self.screen_size, key):
562
+ key = handled_key # noqa: PLW2901
563
+
564
+ else:
568
565
  something_handled = True
569
566
  continue
570
567
 
571
- key = handled_key # noqa: PLW2901
572
-
573
568
  elif is_mouse_event(key):
574
569
  event, button, col, row = key
575
570
  if hasattr(self._topmost_widget, "mouse_event") and self._topmost_widget.mouse_event(
@@ -604,7 +599,7 @@ class MainLoop:
604
599
  >>> scr = _refl("screen")
605
600
  >>> scr.get_cols_rows_rval = (10, 5)
606
601
  >>> ml = MainLoop(w, [], scr)
607
- >>> ml.process_input(['enter', ('mouse drag', 1, 14, 20)])
602
+ >>> ml.process_input(["enter", ("mouse drag", 1, 14, 20)])
608
603
  screen.get_cols_rows()
609
604
  widget.selectable()
610
605
  widget.keypress((10, 5), 'enter')
@@ -155,12 +155,11 @@ class TornadoEventLoop(EventLoop):
155
155
  return handle
156
156
 
157
157
  def remove_watch_file(self, handle: int) -> bool:
158
- fd = self._watch_handles.pop(handle, None)
159
- if fd is None:
160
- return False
158
+ if (fd := self._watch_handles.pop(handle, None)) is not None:
159
+ self._loop.remove_handler(fd)
160
+ return True
161
161
 
162
- self._loop.remove_handler(fd)
163
- return True
162
+ return False
164
163
 
165
164
  def enter_idle(self, callback: Callable[[], typing.Any]) -> int:
166
165
  """
@@ -261,7 +261,7 @@ class TrioEventLoop(EventLoop):
261
261
  """
262
262
  for task, scope, args in self._pending_tasks:
263
263
  self._nursery.start_soon(task, scope, *args)
264
- del self._pending_tasks[:]
264
+ self._pending_tasks.clear()
265
265
 
266
266
  def _start_task(
267
267
  self,
urwid/font.py CHANGED
@@ -24,12 +24,14 @@ import typing
24
24
  import warnings
25
25
  from pprint import pformat
26
26
 
27
+ import wcwidth
28
+
27
29
  from urwid.canvas import CanvasError, TextCanvas
28
30
  from urwid.display.escape import SAFE_ASCII_DEC_SPECIAL_RE
29
- from urwid.util import apply_target_encoding, str_util
31
+ from urwid.util import apply_target_encoding
30
32
 
31
33
  if typing.TYPE_CHECKING:
32
- from collections.abc import Iterable, Iterator, Sequence
34
+ from collections.abc import Iterator, Sequence
33
35
 
34
36
  from typing_extensions import Literal
35
37
 
@@ -60,7 +62,7 @@ def separate_glyphs(gdata: str, height: int) -> tuple[dict[str, tuple[int, list[
60
62
  character = key_line[key_index]
61
63
 
62
64
  if key_index < len(key_line) and key_line[key_index] == character:
63
- end_col += str_util.get_char_width(character)
65
+ end_col += wcwidth.width(character, control_codes="ignore")
64
66
  key_index += 1
65
67
  continue
66
68
 
@@ -76,7 +78,7 @@ def separate_glyphs(gdata: str, height: int) -> tuple[dict[str, tuple[int, list[
76
78
  if j >= len(line):
77
79
  fill = end_col - start_col - y
78
80
  break
79
- y += str_util.get_char_width(line[j])
81
+ y += wcwidth.width(line[j], control_codes="ignore")
80
82
  j += 1
81
83
  if y + fill != end_col - start_col:
82
84
  raise ValueError(repr((y, fill, end_col)))
@@ -139,7 +141,7 @@ class FontRegistry(type):
139
141
  3
140
142
  >>> with set_temporary_encoding("utf-8"):
141
143
  ... canvas: TextCanvas = font.render("+")
142
- >>> b'\\n'.join(canvas.text).decode('utf-8')
144
+ >>> b"\\n".join(canvas.text).decode("utf-8")
143
145
  ' \\n ┼\\n '
144
146
  """
145
147
  return mcs.__registered.get(item)
@@ -192,9 +194,9 @@ class Font(metaclass=FontRegistry):
192
194
 
193
195
  __slots__ = ("canvas", "char", "utf8_required")
194
196
 
195
- height: int
196
- data: Sequence[str]
197
- name: str
197
+ height: int # pylint: disable=declare-non-slot
198
+ data: Sequence[str] # pylint: disable=declare-non-slot
199
+ name: str # pylint: disable=declare-non-slot
198
200
 
199
201
  def __init__(self) -> None:
200
202
  if not self.height:
@@ -206,12 +208,10 @@ class Font(metaclass=FontRegistry):
206
208
  self.canvas: dict[str, TextCanvas] = {}
207
209
  self.utf8_required = False
208
210
  if isinstance(self.data, str):
209
- self.add_glyphs(self._to_text(self.data))
211
+ self.add_glyphs(self.data)
210
212
 
211
213
  else:
212
- data: Iterable[str] = (self._to_text(block) for block in self.data)
213
-
214
- for gdata in data:
214
+ for gdata in self.data:
215
215
  self.add_glyphs(gdata)
216
216
 
217
217
  def __repr__(self) -> str:
@@ -223,22 +223,19 @@ class Font(metaclass=FontRegistry):
223
223
 
224
224
  @staticmethod
225
225
  def _to_text(
226
- obj: str | bytes,
226
+ obj: str,
227
227
  encoding: str = "utf-8",
228
228
  errors: Literal["strict", "ignore", "replace"] = "strict",
229
229
  ) -> str:
230
+ warnings.warn(
231
+ "_to_text is deprecated: only text fonts are supported. API will be removed in version 4.0.",
232
+ DeprecationWarning,
233
+ stacklevel=3,
234
+ )
230
235
  if isinstance(obj, str):
231
236
  return obj
232
237
 
233
- if isinstance(obj, bytes):
234
- warnings.warn(
235
- "Bytes based fonts are deprecated, please switch to the text one",
236
- DeprecationWarning,
237
- stacklevel=3,
238
- )
239
- return obj.decode(encoding, errors)
240
-
241
- raise TypeError(f"{obj!r} is not str|bytes")
238
+ raise TypeError(f"{obj!r} is not str")
242
239
 
243
240
  def add_glyphs(self, gdata: str) -> None:
244
241
  d, utf8_required = separate_glyphs(gdata, self.height)
urwid/numedit.py CHANGED
@@ -88,28 +88,28 @@ class NumEdit(Edit):
88
88
  Handle editing keystrokes. Remove leading zeros.
89
89
 
90
90
  >>> e, size = NumEdit("0123456789", "", "5002"), (10,)
91
- >>> e.keypress(size, 'home')
92
- >>> e.keypress(size, 'delete')
91
+ >>> e.keypress(size, "home")
92
+ >>> e.keypress(size, "delete")
93
93
  >>> assert e.edit_text == "002"
94
- >>> e.keypress(size, 'end')
94
+ >>> e.keypress(size, "end")
95
95
  >>> assert e.edit_text == "2"
96
96
  >>> # binary only
97
97
  >>> e, size = NumEdit("01", "", ""), (10,)
98
98
  >>> assert e.edit_text == ""
99
- >>> e.keypress(size, '1')
100
- >>> e.keypress(size, '0')
101
- >>> e.keypress(size, '1')
99
+ >>> e.keypress(size, "1")
100
+ >>> e.keypress(size, "0")
101
+ >>> e.keypress(size, "1")
102
102
  >>> assert e.edit_text == "101"
103
103
  >>> e, size = NumEdit("0123456789", "", "", allow_negative=True), (10,)
104
104
  >>> e.keypress(size, "-")
105
- >>> e.keypress(size, '1')
105
+ >>> e.keypress(size, "1")
106
106
  >>> e.edit_text
107
107
  '-1'
108
- >>> e.keypress(size, 'home')
109
- >>> e.keypress(size, 'delete')
108
+ >>> e.keypress(size, "home")
109
+ >>> e.keypress(size, "delete")
110
110
  >>> e.edit_text
111
111
  '1'
112
- >>> e.keypress(size, 'end')
112
+ >>> e.keypress(size, "end")
113
113
  >>> e.keypress(size, "-")
114
114
  '-'
115
115
  >>> e.edit_text
@@ -141,52 +141,52 @@ class IntegerEdit(NumEdit):
141
141
  caption -- caption markup
142
142
  default -- default edit value
143
143
 
144
- >>> IntegerEdit(u"", 42)
144
+ >>> IntegerEdit("", 42)
145
145
  <IntegerEdit selectable flow widget '42' edit_pos=2>
146
- >>> e, size = IntegerEdit(u"", "5002"), (10,)
147
- >>> e.keypress(size, 'home')
148
- >>> e.keypress(size, 'delete')
146
+ >>> e, size = IntegerEdit("", "5002"), (10,)
147
+ >>> e.keypress(size, "home")
148
+ >>> e.keypress(size, "delete")
149
149
  >>> assert e.edit_text == "002"
150
- >>> e.keypress(size, 'end')
150
+ >>> e.keypress(size, "end")
151
151
  >>> assert e.edit_text == "2"
152
- >>> e.keypress(size, '9')
153
- >>> e.keypress(size, '0')
152
+ >>> e.keypress(size, "9")
153
+ >>> e.keypress(size, "0")
154
154
  >>> assert e.edit_text == "290"
155
155
  >>> e, size = IntegerEdit("", ""), (10,)
156
156
  >>> assert e.value() is None
157
157
  >>> # binary
158
- >>> e, size = IntegerEdit(u"", "1010", base=2), (10,)
159
- >>> e.keypress(size, 'end')
160
- >>> e.keypress(size, '1')
158
+ >>> e, size = IntegerEdit("", "1010", base=2), (10,)
159
+ >>> e.keypress(size, "end")
160
+ >>> e.keypress(size, "1")
161
161
  >>> assert e.edit_text == "10101"
162
162
  >>> assert e.value() == Decimal("21")
163
163
  >>> # HEX
164
- >>> e, size = IntegerEdit(u"", "10", base=16), (10,)
165
- >>> e.keypress(size, 'end')
166
- >>> e.keypress(size, 'F')
167
- >>> e.keypress(size, 'f')
164
+ >>> e, size = IntegerEdit("", "10", base=16), (10,)
165
+ >>> e.keypress(size, "end")
166
+ >>> e.keypress(size, "F")
167
+ >>> e.keypress(size, "f")
168
168
  >>> assert e.edit_text == "10Ff"
169
- >>> assert e.keypress(size, 'G') == 'G' # unhandled key
169
+ >>> assert e.keypress(size, "G") == "G" # unhandled key
170
170
  >>> assert e.edit_text == "10Ff"
171
171
  >>> # keep leading 0's when not base 10
172
- >>> e, size = IntegerEdit(u"", "10FF", base=16), (10,)
172
+ >>> e, size = IntegerEdit("", "10FF", base=16), (10,)
173
173
  >>> assert e.edit_text == "10FF"
174
174
  >>> assert e.value() == Decimal("4351")
175
- >>> e.keypress(size, 'home')
176
- >>> e.keypress(size, 'delete')
177
- >>> e.keypress(size, '0')
175
+ >>> e.keypress(size, "home")
176
+ >>> e.keypress(size, "delete")
177
+ >>> e.keypress(size, "0")
178
178
  >>> assert e.edit_text == "00FF"
179
179
  >>> # test exception on incompatible value for base
180
- >>> e, size = IntegerEdit(u"", "10FG", base=16), (10,)
180
+ >>> e, size = IntegerEdit("", "10FG", base=16), (10,)
181
181
  Traceback (most recent call last):
182
182
  ...
183
183
  ValueError: invalid value: 10FG for base 16
184
184
  >>> # test exception on float init value
185
- >>> e, size = IntegerEdit(u"", 10.0), (10,)
185
+ >>> e, size = IntegerEdit("", 10.0), (10,)
186
186
  Traceback (most recent call last):
187
187
  ...
188
188
  ValueError: default: Only 'str', 'int', 'long' or Decimal input allowed
189
- >>> e, size = IntegerEdit(u"", Decimal("10.0")), (10,)
189
+ >>> e, size = IntegerEdit("", Decimal("10.0")), (10,)
190
190
  Traceback (most recent call last):
191
191
  ...
192
192
  ValueError: not an 'integer Decimal' instance
@@ -226,8 +226,8 @@ class IntegerEdit(NumEdit):
226
226
  Return the numeric value of self.edit_text.
227
227
 
228
228
  >>> e, size = IntegerEdit(), (10,)
229
- >>> e.keypress(size, '5')
230
- >>> e.keypress(size, '1')
229
+ >>> e.keypress(size, "5")
230
+ >>> e.keypress(size, "1")
231
231
  >>> assert e.value() == 51
232
232
  """
233
233
  if self.edit_text:
@@ -240,9 +240,9 @@ class IntegerEdit(NumEdit):
240
240
 
241
241
  >>> e, size = IntegerEdit(allow_negative=True), (10,)
242
242
  >>> assert int(e) == 0
243
- >>> e.keypress(size, '-')
244
- >>> e.keypress(size, '4')
245
- >>> e.keypress(size, '2')
243
+ >>> e.keypress(size, "-")
244
+ >>> e.keypress(size, "4")
245
+ >>> e.keypress(size, "2")
246
246
  >>> assert int(e) == -42
247
247
  """
248
248
  if self.edit_text:
@@ -270,46 +270,46 @@ class FloatEdit(NumEdit):
270
270
  preserve_significance -- return value has the same signif. as default
271
271
  decimal_separator -- use '.' as separator by default, optionally a ','
272
272
 
273
- >>> FloatEdit(u"", "1.065434")
273
+ >>> FloatEdit("", "1.065434")
274
274
  <FloatEdit selectable flow widget '1.065434' edit_pos=8>
275
- >>> e, size = FloatEdit(u"", "1.065434"), (10,)
276
- >>> e.keypress(size, 'home')
277
- >>> e.keypress(size, 'delete')
275
+ >>> e, size = FloatEdit("", "1.065434"), (10,)
276
+ >>> e.keypress(size, "home")
277
+ >>> e.keypress(size, "delete")
278
278
  >>> assert e.edit_text == ".065434"
279
- >>> e.keypress(size, 'end')
280
- >>> e.keypress(size, 'backspace')
279
+ >>> e.keypress(size, "end")
280
+ >>> e.keypress(size, "backspace")
281
281
  >>> assert e.edit_text == ".06543"
282
282
  >>> e, size = FloatEdit(), (10,)
283
- >>> e.keypress(size, '5')
284
- >>> e.keypress(size, '1')
285
- >>> e.keypress(size, '.')
286
- >>> e.keypress(size, '5')
287
- >>> e.keypress(size, '1')
283
+ >>> e.keypress(size, "5")
284
+ >>> e.keypress(size, "1")
285
+ >>> e.keypress(size, ".")
286
+ >>> e.keypress(size, "5")
287
+ >>> e.keypress(size, "1")
288
288
  >>> assert e.value() == Decimal("51.51"), e.value()
289
289
  >>> e, size = FloatEdit(decimal_separator=":"), (10,)
290
290
  Traceback (most recent call last):
291
291
  ...
292
292
  ValueError: invalid decimal separator: :
293
293
  >>> e, size = FloatEdit(decimal_separator=","), (10,)
294
- >>> e.keypress(size, '5')
295
- >>> e.keypress(size, '1')
296
- >>> e.keypress(size, ',')
297
- >>> e.keypress(size, '5')
298
- >>> e.keypress(size, '1')
294
+ >>> e.keypress(size, "5")
295
+ >>> e.keypress(size, "1")
296
+ >>> e.keypress(size, ",")
297
+ >>> e.keypress(size, "5")
298
+ >>> e.keypress(size, "1")
299
299
  >>> assert e.edit_text == "51,51"
300
300
  >>> e, size = FloatEdit("", "3.1415", preserve_significance=True), (10,)
301
- >>> e.keypress(size, 'end')
302
- >>> e.keypress(size, 'backspace')
303
- >>> e.keypress(size, 'backspace')
301
+ >>> e.keypress(size, "end")
302
+ >>> e.keypress(size, "backspace")
303
+ >>> e.keypress(size, "backspace")
304
304
  >>> assert e.edit_text == "3.14"
305
305
  >>> assert e.value() == Decimal("3.1400")
306
- >>> e.keypress(size, '1')
307
- >>> e.keypress(size, '5')
308
- >>> e.keypress(size, '9')
306
+ >>> e.keypress(size, "1")
307
+ >>> e.keypress(size, "5")
308
+ >>> e.keypress(size, "9")
309
309
  >>> assert e.value() == Decimal("3.1416"), e.value()
310
310
  >>> e, size = FloatEdit("", ""), (10,)
311
311
  >>> assert e.value() is None
312
- >>> e, size = FloatEdit(u"", 10.0), (10,)
312
+ >>> e, size = FloatEdit("", 10.0), (10,)
313
313
  Traceback (most recent call last):
314
314
  ...
315
315
  ValueError: default: Only 'str', 'int', 'long' or Decimal input allowed
@@ -368,11 +368,11 @@ class FloatEdit(NumEdit):
368
368
  """Enforced float value return.
369
369
 
370
370
  >>> e, size = FloatEdit(allow_negative=True), (10,)
371
- >>> assert float(e) == 0.
372
- >>> e.keypress(size, '-')
373
- >>> e.keypress(size, '4')
374
- >>> e.keypress(size, '.')
375
- >>> e.keypress(size, '2')
371
+ >>> assert float(e) == 0.0
372
+ >>> e.keypress(size, "-")
373
+ >>> e.keypress(size, "4")
374
+ >>> e.keypress(size, ".")
375
+ >>> e.keypress(size, "2")
376
376
  >>> assert float(e) == -4.2
377
377
  """
378
378
  if self.edit_text: