Skip to content

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

References