Ei vielä käännetty
Tätä sivua ei ole vielä käännetty suomeksi, joten se näytetään englanniksi. Auta kääntämään
tty Module Complexity¶
The tty module switches a Unix terminal between its line-buffered default, cbreak mode and raw
mode. It is a thin layer over termios: each mode is a handful of bit operations on the
seven-item attribute list that termios.tcgetattr() returns.
Every operation here is O(1). The attribute list has a fixed length, and its control-character
list holds termios.NCCS entries, a constant of the platform, so nothing on this page grows
with an input. The one wait is outside that bound: with TCSADRAIN or the default TCSAFLUSH,
tcsetattr() does not return until output already queued for the terminal has been sent, and
TCSAFLUSH also discards input that has arrived but not been read.
Complexity Reference¶
Changing a terminal's mode¶
| Operation | Time | Space | Notes |
|---|---|---|---|
tty.setraw(fd, when=termios.TCSAFLUSH) |
O(1) | O(1) | One tcgetattr() and one tcsetattr(); also turns off signal keys and output processing |
tty.setcbreak(fd, when=termios.TCSAFLUSH) |
O(1) | O(1) | One tcgetattr() and one tcsetattr(); turns off echo and line buffering, keeps signal keys and output processing |
Restoring with termios.tcsetattr(fd, when, saved) |
O(1) | O(1) | saved from termios.tcgetattr(), or from the return value of setraw()/setcbreak() on 3.12.1+ |
Editing an attribute list¶
| Operation | Time | Space | Notes |
|---|---|---|---|
tty.cfmakeraw(mode) |
O(1) | O(1) | Edits mode in place and makes no system call; 3.12+ |
tty.cfmakecbreak(mode) |
O(1) | O(1) | Edits mode in place and makes no system call; 3.12+ |
Constants¶
| Operation | Time | Space | Notes |
|---|---|---|---|
tty.IFLAG, tty.OFLAG, tty.CFLAG, tty.LFLAG, tty.ISPEED, tty.OSPEED, tty.CC |
O(1) | O(1) | Indices 0 to 6 into the attribute list |
Raw and Cbreak Mode¶
Both modes make input readable as each byte arrives, without waiting for a whole line, and
without echoing it. Raw mode also turns off the keys that raise signals and the terminal's output
processing, so Ctrl-C arrives as a byte rather than as KeyboardInterrupt. Save the attributes
first and restore them in a finally block; the saved list is all that restoring needs.
import os
import termios
import tty
controller, terminal = os.openpty()
try:
saved = termios.tcgetattr(terminal) # O(1)
try:
tty.setcbreak(terminal) # O(1)
mode = termios.tcgetattr(terminal)
assert not mode[tty.LFLAG] & (termios.ECHO | termios.ICANON)
assert mode[tty.LFLAG] & termios.ISIG # signal keys stay on
tty.setraw(terminal) # O(1)
mode = termios.tcgetattr(terminal)
assert not mode[tty.LFLAG] & termios.ISIG
assert not mode[tty.OFLAG] & termios.OPOST
finally:
termios.tcsetattr(terminal, termios.TCSADRAIN, saved) # O(1)
restored = termios.tcgetattr(terminal)
restored[tty.LFLAG] &= ~termios.PENDIN # macOS sets it when canonical mode returns
assert restored == saved
finally:
os.close(terminal)
os.close(controller)
Building a Mode Without Touching the Terminal¶
cfmakeraw() and cfmakecbreak() do the bit operations of setraw() and setcbreak() on a
list you pass in, and return None. They make no system call, so a mode can be prepared once
and applied with termios.tcsetattr() whenever it is needed.
import os
import termios
import tty
controller, terminal = os.openpty()
try:
mode = termios.tcgetattr(terminal)
assert tty.cfmakeraw(mode) is None # O(1), edits mode in place
assert not mode[tty.LFLAG] & termios.ECHO
assert mode[tty.CC][termios.VMIN] == 1
assert termios.tcgetattr(terminal)[tty.LFLAG] & termios.ECHO # not applied yet
termios.tcsetattr(terminal, termios.TCSANOW, mode) # O(1)
assert not termios.tcgetattr(terminal)[tty.LFLAG] & termios.ECHO
finally:
os.close(terminal)
os.close(controller)
Performance Best Practices¶
✅ Do:
- Save the attributes once and restore them in
finally: both are O(1), and a terminal left in raw mode outlives the program - Switch back and forth with lists prepared once by
cfmakeraw()orcfmakecbreak()(3.12+): each switch is then onetcsetattr(), wheresetraw()andsetcbreak()also read the attributes first
❌ Avoid:
- The default
TCSAFLUSHwhen input typed ahead matters - it is discarded; passTCSADRAINorTCSANOWaswhen - Restoring from the value
setraw()orsetcbreak()returns in code that also runs before 3.12.1 - calltermios.tcgetattr()first instead
Version Notes¶
- Python 3.12+: Added
cfmakeraw()andcfmakecbreak();setraw()andsetcbreak()return a list instead ofNone - Python 3.12.1+: That list is the attributes the call replaced, and restores the terminal; on
3.12.0 its
VMINandVTIMEentries already hold the new mode's values - Python 3.12.2+:
setcbreak()andcfmakecbreak()leave carriage-return translation (ICRNL) as it was, whichsetcbreak()also does on 3.11; 3.12.0 and 3.12.1 clear it