pexpect
pexpect is a pure Python module for spawning child applications; controlling them; and responding to expected patterns in their output. Pexpect works like Don Libes’ Expect. Pexpect allows your script to spawn a child application and control it as if a human were typing commands.
Installation⚑
pip install pexpect
Usage⚑
import pexpect
child = pexpect.spawn('ftp ftp.openbsd.org')
child.expect('Name .*: ')
child.sendline('anonymous')
If you're using it to spawn a program that asks something and then ends, you can catch the end with .expect_exact(pexpect.EOF)
.
tui = pexpect.spawn("python source.py", timeout=5)
tui.expect("Give me .*")
tui.sendline("HI")
tui.expect_exact(pexpect.EOF)
The timeout=5
is useful if the pexpect
interaction is not well defined, so that the script is not hung forever.
Send key presses⚑
To simulate key presses, you can use prompt_toolkit keys with REVERSE_ANSI_SEQUENCES.
from prompt_toolkit.input.ansi_escape_sequences import REVERSE_ANSI_SEQUENCES
from prompt_toolkit.keys import Keys
tui = pexpect.spawn("python source.py", timeout=5)
tui.send(REVERSE_ANSI_SEQUENCES[Keys.ControlC])
To make your code cleaner you can use a helper class:
from prompt_toolkit.input.ansi_escape_sequences import REVERSE_ANSI_SEQUENCES
from prompt_toolkit.keys import Keys
class Keyboard(str, Enum):
ControlH = REVERSE_ANSI_SEQUENCES[Keys.ControlH]
Enter = "\r"
Esc = REVERSE_ANSI_SEQUENCES[Keys.Escape]
# Equivalent keystrokes in terminals; see python-prompt-toolkit for
# further explanations
Alt = Esc
Backspace = ControlH
Read output of command⚑
import sys
import pexpect
child = pexpect.spawn('ls', encoding='utf-8')
child.logfile = sys.stdout
child.expect(pexpect.EOF)
For the tests, you can use the capsys fixture to do assertions on the content:
out, err = capsys.readouterr()
assert "WARNING! you took 1 seconds to process the last element" in out