Решение состояло в том, чтобы исправить метод cmdloop
, чтобы сделать его осведомленным об асинхронности.
Этот код является копией функции cmdloop класса Cmd Python 3.7.2, которую вы получаете, если установить
raw_input
установлен на True
- поставить
await
перед строкой чтения
Результаты в этом коде ( aoicmd.py доступен как гист ):
async def adapter_cmdloop(self, intro=None):
"""Repeatedly issue a prompt, accept input, parse an initial prefix
off the received input, and dispatch to action methods, passing them
the remainder of the line as argument.
"""
self.preloop()
#This is the same code as the Python 3.7.2 Cmd class, with the
#following changes
# - Remove dead code caused by forcing use_rawinput=False.
# - Added a readline in front of readline()
if intro is not None:
self.intro = intro
if self.intro:
self.stdout.write(str(self.intro)+"\n")
stop = None
while not stop:
if self.cmdqueue:
line = self.cmdqueue.pop(0)
else:
self.stdout.write(self.prompt)
self.stdout.flush()
line = await self.stdin.readline()
if not len(line):
line = 'EOF'
else:
line = line.rstrip('\r\n')
line = self.precmd(line)
stop = self.onecmd(line)
stop = self.postcmd(stop, line)
self.postloop()
Если вам нужно использовать производный класс Cmd, например MyShell
, создайте новый класс с именем MyAsyncShell
во время выполнения:
#Patch the shell with async aware cmdloop
MyAsyncShell = type('MyAsyncSHell', (MyShell,), {
'cmdloop' :aiocmd.adapter_cmdloop,
'use_rawinput':False,
})
Реализация write
и flush
, как вы считаете нужным, но ваша readline должна выглядеть так:
async def readline(self):
return await my_implementation_of_readline()