LINUX.ORG.RU

Urwid+asyncio: как правильно завершить работу?

 ,


0

2

Допустим, есть дочерний процесс, работа с которым контролируется asyncio, и к этому делу я хочу прикрутить TUI из виджетов Urwid. В результате, насколько я понимаю, рабочий цикл asyncio недоволен тем, что для выхода бросается urwid.ExitMainLoop(). Я пытаюсь делать это так:

import asyncio
import urwid
from functools import partial

txt = urwid.Text('...')
fill = urwid.Filler(txt, 'middle')

loop = asyncio.get_event_loop()

msg = ''
class Proto(asyncio.SubprocessProtocol):
    def __init__(self, done_future):
        self.done = done_future

    def connection_made(self, transport):
        self.transport = transport

    def pipe_data_received(self, fd, data):
        global msg
        msg += data.decode()
        txt.set_text(msg)

    def process_exited(self):
        self.done.set_result(self.transport.get_returncode())

async def job():
    done = asyncio.Future(loop=loop)
    transport, protocol = await loop.subprocess_exec(partial(Proto, done), 'echo', 'Hello there!')
    await done
    transport.close()
    await asyncio.sleep(5)
    raise urwid.ExitMainLoop()

loop.create_task(job())
urwid_loop = urwid.MainLoop(fill, event_loop=urwid.AsyncioEventLoop(loop=loop))
urwid_loop.run()

...и на выходе получаю это:

Exception ignored in: <bound method BaseEventLoop.__del__ of <_UnixSelectorEventLoop running=False closed=True debug=False>>
Traceback (most recent call last):
  File "/usr/lib64/python3.5/asyncio/base_events.py", line 511, in __del__
  File "/usr/lib64/python3.5/asyncio/unix_events.py", line 65, in close
  File "/usr/lib64/python3.5/asyncio/unix_events.py", line 146, in remove_signal_handler
  File "/usr/lib64/python3.5/signal.py", line 47, in signal
TypeError: signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object

Как это делается правильно?

Ответ на: комментарий от anonymous

и где же ты его вовращаешьхто их фукнкцип твоей т от корутина обж

ОК, допустим здесь имеется в виду объект Task. Если мы его удерживаем,

task = loop.create_task(job())
то urwid_loop не завершается даже после бросания urwid.ExitMainLoop(). Ничего не понимаю.

Zeta_Gundam ()

Похоже что в конце просто не хватало loop.close(). Event loop без этого подчистить за собой не мог? Мистика.

Zeta_Gundam ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.