liveBook · Manning

Read coroutine

As explained in Python Concurrency with asyncio

The read coroutine is a book-local coroutine that reads terminal input one character at a time, echoes it, handles deletion, and returns a completed input line.

A read coroutine reads terminal input one character at a time, echoes accepted characters, handles deletion, and returns the completed line when the user presses Enter. section 8.4.1

Its input loop coordinates four operations:

  • Awaits one byte from a stream reader. section 8.4.1
  • Appends ordinary characters to an internal buffer and echoes them to standard output. section 8.4.1
  • Removes the last buffered character and erases its displayed form when Delete is pressed. section 8.4.1
  • Clears the input line and returns the buffer after Enter terminates input. section 8.4.1
Listing 8.8 Reading input one character at a time
import sys
from asyncio import StreamReader
from collections import deque
from chapter_08.listing_8_7 import move_back_one_char, clear_line
 
 
async def read_line(stdin_reader: StreamReader) -> str:
    def erase_last_char():                                     #1
        move_back_one_char()
        sys.stdout.write(' ')
        move_back_one_char()
 
    delete_char = b'\x7f'
    input_buffer = deque()
    while (input_char := await stdin_reader.read(1)) != b'\n':
        if input_char == delete_char:                          #2
            if len(input_buffer) > 0:
                input_buffer.pop()
                erase_last_char()
                sys.stdout.flush()
        else:
            input_buffer.append(input_char)                    #3
            sys.stdout.write(input_char.decode())
            sys.stdout.flush()
    clear_line()
    return b''.join(input_buffer).decode()

Inspect the implementation of character reads, deletion handling, output erasure, and input buffering. section 8.4.1

How Python Concurrency with asyncio covers it

How deep it goes
Implements byte-wise reading, buffering, echoing, deletion, and line completion without extending beyond the terminal application.
Examples
Uses Python code that reads bytes, stores them in a deque, echoes characters, and erases the previous character on deletion.
What it assumes
Assumes familiarity with asynchronous functions, stream readers, terminal input, and standard output.
What you can do after
Build an asynchronous line reader for terminal applications with editable echoed input.
How it connects
Connects coroutines with StreamReader, standard input, standard output, terminal raw mode, and cursor-control escape sequences.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Concurrency with asyncio. The section links point to the parts of the book it draws on.