31866a0f0ba1 draft — Alain Leufroy 1 year, 4 months ago
wip py3.11
4 files changed, 9 insertions(+), 66 deletions(-)

M lairucrem/controler.py
M lairucrem/patch_urwid.py
M lairucrem/process.py
M lairucrem/widgets/dialog.py
M lairucrem/controler.py +2 -1
@@ 13,11 13,12 @@ from pathlib import Path
 import urwid
 
 from . import config, mixin, open_popup, process, widgets
+from .exceptions import CriticalError
 from .mixin import ensurable, multilist, paginatedlist, waitable
 from .utils import (ParseError, ensure_one, nodestr, parse_colored_line,
                     popup_error, shelvestr)
 from .widgets import attrwrap, dialog, mainwidget
-from .exceptions import CriticalError
+
 
 class _multiwalker(
         ensurable, waitable, multilist, urwid.SimpleFocusListWalker):

          
M lairucrem/patch_urwid.py +0 -58
@@ 1,67 1,9 @@ 
 """fix urwid bug."""
-import sys
 
-from urwid import ExitMainLoop
 from urwid.canvas import (LayoutSegment, TextCanvas, apply_target_encoding,
                           rle_append_modify, rle_join_modify, rle_len,
                           trim_line)
 
-try:
-    from urwid.event_loop import AsyncioEventLoop
-except ImportError:
-    from urwid.main_loop import AsyncioEventLoop
-
-from urwid.raw_display import Screen
-
-from .utils import monkeypatch
-
-# # https://github.com/urwid/urwid/issues/221
-# @monkeypatch(Screen, 'hook_event_loop')
-# def fix_issue_221(self, event_loop, callback):
-#     """
-#     Register the given callback with the event loop, to be called with new
-#     input whenever it's available.  The callback should be passed a list of
-#     processed keys and a list of unprocessed keycodes.
-
-#     Subclasses may wish to use parse_input to wrap the callback.
-#     """
-#     if hasattr(self, 'get_input_nonblocking'):
-#         wrapper = self._make_legacy_input_wrapper(event_loop, callback)
-#     else:
-#         wrapper = lambda: self.parse_input(
-#             event_loop, callback, self.get_available_raw_input())
-#     fds = self.get_input_descriptors()
-#     handles = [
-#         event_loop.watch_file(fd, wrapper)
-#         for fd in fds]
-#     self._current_event_loop_handles = handles
-
-# Fix exception handling
-# https://github.com/urwid/urwid/pull/92 exists but not merged
-
-
-@monkeypatch(AsyncioEventLoop)
-def _exception_handler(self, loop, context):
-    exc = context.get('exception')
-    if exc:
-        if not isinstance(exc, ExitMainLoop):
-            self._exc = exc
-        else:
-            loop.default_exception_handler(context)
-        loop.stop()
-
-
-@monkeypatch(AsyncioEventLoop)
-def run(self):
-    """
-    Start the event loop.  Exit the loop when any callback raises
-    an exception.  If ExitMainLoop is raised, exit cleanly.
-    """
-    self._loop.set_exception_handler(self._exception_handler)
-    self._loop.run_forever()
-    if getattr(self, '_exc', None):
-        raise self._exc
-
 
 def apply_text_layout(text, attr, ls, maxcol):
     t = []

          
M lairucrem/process.py +7 -6
@@ 12,7 12,7 @@ import sys
 from sys import version_info
 from typing import AsyncIterable
 
-from . import config, get_extension_path, interrupt_mainloop
+from . import config, get_extension_path, get_main_loop, interrupt_mainloop
 from .config import get_hg
 from .exceptions import CriticalError, HgNotFoundError, RepositoryNotFound
 

          
@@ 85,9 85,6 @@ class hg:
                 )
             except FileNotFoundError as exc:
                 raise HgNotFoundError() from exc
-        trans = self.proc._transport.get_pipe_transport(1)
-        if trans._loop is None:  # asyncio forgets to set the loop :/
-            trans._loop = asyncio.get_event_loop()
         return self.proc
 
     async def __aiter__(self) -> AsyncIterable:

          
@@ 95,7 92,11 @@ class hg:
             await self.start()
         val = await self._read_stdout_line()
         while val:
+            # Unlock the mainloop to allow screen redrawing.
+            asyncio.get_event_loop().call_later(
+                0, get_main_loop().entering_idle)
             yield val.decode('utf-8', 'replace')
+
             val = await self._read_stdout_line()
         await self.stop()
 

          
@@ 118,9 119,9 @@ class hg:
             msg = exc.strerror or str(exc)
             if msg:
                 if 'abort: no repository' in msg:
-                    raise RepositoryNotFound(str(exc))
+                    raise RepositoryNotFound(str(exc)) from exc
                 if 'abort:' in msg:
-                    raise CriticalError(msg)
+                    raise CriticalError(msg) from exc
             if not (self._killed and exc.errno == -9):
                 raise
         self.proc = None

          
M lairucrem/widgets/dialog.py +0 -1
@@ 373,7 373,6 @@ async def async_choices(tasks):
     tasks.append(asyncio.tasks.Task(diag.__await__()))
     while tasks:
         # consum tasks
-        config.logger.error(repr(tasks))
         dones, tasks = await asyncio.wait(tasks, return_when=FIRST_COMPLETED)
         if diag.done():  # user already answered ⇒ ignore new actions
             break