Search code examples
pythonasynchronouspexpect

Pexpect: async expect with several connection



I'm trying to write script for gathering some information from network devices using Pexpect async expect(python 3.5.1 and pexpect from github) and get some strange thing: all works fine with several devices and doesn't work with some more (usually > 5-6). I wrote this simple script for testing:

@asyncio.coroutine
def test_ssh_expect_async(num):
    print('Task #{0} start'.format(num))
    p = pexpect.spawn('ssh localhost', encoding='utf8')
    #p.logfile = sys.stdout
    yield from p.expect('password', async=True)
    p.sendline('***')
    yield from p.expect(r'@self-VirtualBox\:', async=True)
    p.sendline('uptime')
    yield from p.expect(r'@self-VirtualBox\:', async=True)
    p.sendline('uname -a')
    yield from p.expect(r'@self-VirtualBox\:', async=True)
    p.sendline('ll')
    yield from p.expect(r'@self-VirtualBox\:', async=True)
    print('Task #{0} end'.format(num))

@asyncio.coroutine
def test_loop():
    tasks = []
    for i in range(1, 5):
        tasks.append(test_ssh_expect_async(i))
    yield from asyncio.wait(tasks)
    print('All Tasks done')


print('--------------Async--------------------')

loop = asyncio.get_event_loop()
loop.run_until_complete(test_loop())

If i try to use range(1,3) as example i get this:

self@self-VirtualBox:/media/sf_netdev$ python3 simple-test.py 
--------------Async--------------------
Task #3 running
Task #1 running
Task #2 running
Task #3 closed
Task #1 closed
Task #2 closed
All Tasks done

But if i increase upper limit i get some errors:

self@self-VirtualBox:/media/sf_netdev$ python3 simple-test.py 
--------------Async--------------------
Task #3 running
Task #1 running
Task #4 running
Task #2 running
Exception in callback BaseSelectorEventLoop.add_reader(11, <bound method...d=11 polling>>)
handle: <Handle BaseSelectorEventLoop.add_reader(11, <bound method...d=11 polling>>)>
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/selector_events.py", line 234, in add_reader
    key = self._selector.get_key(fd)
  File "/usr/lib/python3.5/selectors.py", line 191, in get_key
    raise KeyError("{!r} is not registered".format(fileobj)) from None
KeyError: '11 is not registered'

During handling of the above exception, another exception occurred:
...

Why it happens? How to write working script with async pexpect?

---------------Answer------------

It was a bug https://github.com/pexpect/pexpect/issues/347. Now pexpect command fixed it.


Solution

  • It was a bug https://github.com/pexpect/pexpect/issues/347. Now pexpect command fixed it.