[Python-checkins] gh-85984: New additions and improvements to the tty library. (#101832)

gpshead webhook-mailer at python.org
Fri May 19 14:13:37 EDT 2023


https://github.com/python/cpython/commit/486bc8e03019b8edc3cbfc6e64db96d65dbe13b6
commit: 486bc8e03019b8edc3cbfc6e64db96d65dbe13b6
branch: main
author: Soumendra Ganguly <67527439+8vasu at users.noreply.github.com>
committer: gpshead <greg at krypto.org>
date: 2023-05-19T18:13:30Z
summary:

gh-85984: New additions and improvements to the tty library. (#101832)

New additions to the tty library. Functions added: cfmakeraw(), and cfmakecbreak(). The
functions setcbreak() and setraw() now return original termios to save an extra tcgetattr() call.

---------

Signed-off-by: Soumendra Ganguly <soumendraganguly at gmail.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Gregory P. Smith [Google LLC] <greg at krypto.org>

files:
A Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst
M Doc/library/tty.rst
M Lib/tty.py

diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst
index b30bc3c7ac42..fc7f98c7931f 100644
--- a/Doc/library/tty.rst
+++ b/Doc/library/tty.rst
@@ -20,18 +20,36 @@ Because it requires the :mod:`termios` module, it will work only on Unix.
 The :mod:`tty` module defines the following functions:
 
 
+.. function:: cfmakeraw(mode)
+
+   Convert the tty attribute list *mode*, which is a list like the one returned
+   by :func:`termios.tcgetattr`, to that of a tty in raw mode.
+
+   .. versionadded:: 3.12
+
+
+.. function:: cfmakecbreak(mode)
+
+   Convert the tty attribute list *mode*, which is a list like the one returned
+   by :func:`termios.tcgetattr`, to that of a tty in cbreak mode.
+
+   .. versionadded:: 3.12
+
+
 .. function:: setraw(fd, when=termios.TCSAFLUSH)
 
    Change the mode of the file descriptor *fd* to raw. If *when* is omitted, it
    defaults to :const:`termios.TCSAFLUSH`, and is passed to
-   :func:`termios.tcsetattr`.
+   :func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr`
+   is saved before setting *fd* to raw mode; this value is returned.
 
 
 .. function:: setcbreak(fd, when=termios.TCSAFLUSH)
 
    Change the mode of file descriptor *fd* to cbreak. If *when* is omitted, it
    defaults to :const:`termios.TCSAFLUSH`, and is passed to
-   :func:`termios.tcsetattr`.
+   :func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr`
+   is saved before setting *fd* to cbreak mode; this value is returned.
 
 
 .. seealso::
diff --git a/Lib/tty.py b/Lib/tty.py
index a72eb6755450..7d916029ff2c 100644
--- a/Lib/tty.py
+++ b/Lib/tty.py
@@ -4,9 +4,9 @@
 
 from termios import *
 
-__all__ = ["setraw", "setcbreak"]
+__all__ = ["cfmakeraw", "cfmakecbreak", "setraw", "setcbreak"]
 
-# Indexes for termios list.
+# Indices for termios list.
 IFLAG = 0
 OFLAG = 1
 CFLAG = 2
@@ -15,22 +15,60 @@
 OSPEED = 5
 CC = 6
 
-def setraw(fd, when=TCSAFLUSH):
-    """Put terminal into a raw mode."""
-    mode = tcgetattr(fd)
-    mode[IFLAG] = mode[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON)
-    mode[OFLAG] = mode[OFLAG] & ~(OPOST)
-    mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB)
-    mode[CFLAG] = mode[CFLAG] | CS8
-    mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG)
+def cfmakeraw(mode):
+    """Make termios mode raw."""
+    # Clear all POSIX.1-2017 input mode flags.
+    # See chapter 11 "General Terminal Interface"
+    # of POSIX.1-2017 Base Definitions.
+    mode[IFLAG] &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP |
+                     INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF)
+
+    # Do not post-process output.
+    mode[OFLAG] &= ~OPOST
+
+    # Disable parity generation and detection; clear character size mask;
+    # let character size be 8 bits.
+    mode[CFLAG] &= ~(PARENB | CSIZE)
+    mode[CFLAG] |= CS8
+
+    # Clear all POSIX.1-2017 local mode flags.
+    mode[LFLAG] &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON |
+                     IEXTEN | ISIG | NOFLSH | TOSTOP)
+
+    # POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing,
+    # Case B: MIN>0, TIME=0
+    # A pending read shall block until MIN (here 1) bytes are received,
+    # or a signal is received.
     mode[CC][VMIN] = 1
     mode[CC][VTIME] = 0
-    tcsetattr(fd, when, mode)
 
-def setcbreak(fd, when=TCSAFLUSH):
-    """Put terminal into a cbreak mode."""
-    mode = tcgetattr(fd)
-    mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON)
+def cfmakecbreak(mode):
+    """Make termios mode cbreak."""
+    # Do not map CR to NL on input.
+    mode[IFLAG] &= ~(ICRNL)
+
+    # Do not echo characters; disable canonical input.
+    mode[LFLAG] &= ~(ECHO | ICANON)
+
+    # POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing,
+    # Case B: MIN>0, TIME=0
+    # A pending read shall block until MIN (here 1) bytes are received,
+    # or a signal is received.
     mode[CC][VMIN] = 1
     mode[CC][VTIME] = 0
-    tcsetattr(fd, when, mode)
+
+def setraw(fd, when=TCSAFLUSH):
+    """Put terminal into raw mode."""
+    mode = tcgetattr(fd)
+    new = list(mode)
+    cfmakeraw(new)
+    tcsetattr(fd, when, new)
+    return mode
+
+def setcbreak(fd, when=TCSAFLUSH):
+    """Put terminal into cbreak mode."""
+    mode = tcgetattr(fd)
+    new = list(mode)
+    cfmakecbreak(new)
+    tcsetattr(fd, when, new)
+    return mode
diff --git a/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst b/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst
new file mode 100644
index 000000000000..246530472165
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst
@@ -0,0 +1,3 @@
+Add :func:`tty.cfmakeraw` and :func:`tty.cfmakecbreak` to :mod:`tty` and
+modernize, the behavior of :func:`tty.setraw` and :func:`tty.setcbreak` to use
+POSIX.1-2017 Chapter 11 "General Terminal Interface" flag masks by default.



More information about the Python-checkins mailing list