Does not set slave termios. Documented in the source.
Does not set initial slave window size. Documented in the source. Does not handle SIGWINCH. See bpo-41494, bpo-41541. This is essential in the following practical scenarios: i. creating split windows/panes while using a terminal multiplexer; ii. when resizing GUI terminal emulator window, especially relevant when using tiling window managers; iii. resizing an ansi-term window created inside a GNU Emacs frame.
Does not perform signal handling. Signals must be blocked during sensitive portions of code.
The current version of pty.spawn() uses pty.fork() internally. However, pty.fork() closes slave and only returns (pid, master_fd). To update winsize, access to slave is necessary. Further, slave termios must be properly set. The proposed modifications do this by implementing a login_tty(3) based function ( tty.login() ), and using that in pty.spawn() instead of pty.fork(). tty.login() tries TIOCSCTTY before falling back to the old SysV method because Python currently does not provide an interface to the native login_tty(3).
tty.setraw() is called right after tty.tcgetattr(). This increases redundancy of code because tty.setraw() itself makes an identical tty.tcgetattr() call.
Requires testing/porting to more platforms. Solaris, Illumos, macOS, Cygwin, etc. Windows ConPTY?
In addition to the above, if a major revision is made to pty, I'd suggest also addressing the issue of "master/slave" terminology, and replace it with something comparable like "parent/child". There's an open devguide issue (python/devguide#605) to more explicitly state terms to avoid, and support for avoiding usage of "slave/master" seems uncontroversial (especially in any new code).
8vasu commented on Sep 20, 2020
8vasumannequin
MannequinAuthor
More actions
Makes sense. I will happily make a change of terminology in the pypty2 repository after the most desirable alternative is determined based on the choice of the majority. I think 'mother/son' sounds cute while still retaining the same initials as before; people used to the older
terminology will find this easy to remember. Terminology such as parent/child and server/client might make it a little confusing.
Why not make cfmakeraw() and cfmakecbreak() returning a new list instead of modifying the input in-place? In any case you need to make a copy, but it is errorprone, because the list contains a nested list. See #110392.
Regarding "master/slave" terminology:
I plan to use a strategy I learned at @evildmp's workshop. First, merge #102413, which extends os with a bunch of functions that handle PTY-pairs. There's no simple way to avoid using the inappropriate terms in these functions' docs.
The merge will make the os docs worse in this respect -- but it'll also make the issue more obvious, and hopefully easier to solve.
After that I'll propose a PR. Still don't know how that will look, but there's lively brainstorming and style guide recommendations over at the Docs community discord.
Anyway: @8vasu, feel free to focus on the techincal side, and leave terminology to me.
I have also commented a variation of this on: #102413
@vstinner While I am not a CPython maintainer and hence do not have much say in deciding which directions such a prestigious project should take, I am an end user who does pty programming frequently (Python or otherwise) and I will have to deal with the consequences (good or bad) of any decisions taken here.
I have severe clinical OCD/OCPD and would like to issue a warning here: using generic names like main_fd, second_fd, or parent_fd, child_fd, or server_fd, client_fd will lead to havoc very easily. Just take a look at the source of your very own https://github.com/python/cpython/blob/3.12/Lib/pty.py and try a search/replace involving terms parent/child (already used by processes) or a program like ssh(1) which uses the terms server/client in networking context and also sets up a pty pair.
On the other hand one can easily have first_fd, second_fd, third_fd or even main_fd in their existing programs. The pair main, subordinate comes to mind, but again, main_fd might be taken and main, subordinate carry the same overtones as master, slave, which is what you are trying to avoid in the first place.
For a change that is easy to maintain for current and future Python maintainers and eliminates all possibility of confusion for end users when they are referring to documentation, we must use something that is:
not already taken to almost absolutely eliminate any chances of variable name collision while
maintaining that the initials m and s stay the same.
Edit:
Some data: about naming pty-pairs; apart from the file/project/module/documentation-local confusion that inevitably will arise due to using process-specific terminology parent/child; networking-specific terminology server/client, and generic terms main, primary/seconday, here is some global data directly generated using script at the bottom of this post:
Current timezone and date: Sun Jan 21 06:17:13 AM CET 2024 Current directory: /tmp/tmp.21-Jan-2024+05:14:25.JZlA6tqeCz Temporarily moving into directory: /tmp/tmp.uZECXBwUzE
Activity
8vasu commented on Sep 19, 2020
The current pty library has the following issues:
Does not set slave termios. Documented in the source.
Does not set initial slave window size. Documented in the source. Does not handle SIGWINCH. See bpo-41494, bpo-41541. This is essential in the following practical scenarios: i. creating split windows/panes while using a terminal multiplexer; ii. when resizing GUI terminal emulator window, especially relevant when using tiling window managers; iii. resizing an ansi-term window created inside a GNU Emacs frame.
Does not perform signal handling. Signals must be blocked during sensitive portions of code.
Hangs on FreeBSD. See bpo-26228.
Includes deprecated functions pty.master_open(), pty.slave_open().
In pty.fork(), the fallback code should try using TIOCSCTTY first. It is still using the old method of opening a tty to make it the controlling tty. Currently even SysV based systems provide TIOCSCTTY. See https://stackoverflow.com/questions/51593530/code-explanation-for-glibc-login-tty-function-openttyname-immediately-f
The current version of pty.spawn() uses pty.fork() internally. However, pty.fork() closes slave and only returns (pid, master_fd). To update winsize, access to slave is necessary. Further, slave termios must be properly set. The proposed modifications do this by implementing a login_tty(3) based function ( tty.login() ), and using that in pty.spawn() instead of pty.fork(). tty.login() tries TIOCSCTTY before falling back to the old SysV method because Python currently does not provide an interface to the native login_tty(3).
tty.setraw() is called right after tty.tcgetattr(). This increases redundancy of code because tty.setraw() itself makes an identical tty.tcgetattr() call.
Requires testing/porting to more platforms. Solaris, Illumos, macOS, Cygwin, etc. Windows ConPTY?
There should be an option in pty.spawn() to turn off slave's ECHO flag. For example, when it is being used in a pipe. See util-linux/util-linux@1eee1ac and util-linux/util-linux@75ccd75#diff-3834a3d25eeaf20d9d0dcb05a46995f6
Tests are incomplete. Tests consider OSes such as Tru64 but not {Free/Net/Open/...}BSD.
Find ongoing work here: https://github.com/8vasu/pypty2
aeros commented on Sep 20, 2020
In addition to the above, if a major revision is made to pty, I'd suggest also addressing the issue of "master/slave" terminology, and replace it with something comparable like "parent/child". There's an open devguide issue (python/devguide#605) to more explicitly state terms to avoid, and support for avoiding usage of "slave/master" seems uncontroversial (especially in any new code).
8vasu commented on Sep 20, 2020
Makes sense. I will happily make a change of terminology in the pypty2 repository after the most desirable alternative is determined based on the choice of the majority. I think 'mother/son' sounds cute while still retaining the same initials as before; people used to the older
terminology will find this easy to remember. Terminology such as parent/child and server/client might make it a little confusing.
asvetlov commented on Nov 25, 2020
New changeset c13d899 by Soumendra Ganguly in branch 'master':
bpo-41818: Updated tests for the standard pty library (GH-22962)
c13d899
vstinner commented on Nov 25, 2020
This change broke x86 Gentoo buildbots: bpo-42463.
asvetlov commented on Nov 25, 2020
#23514 has the fix, waiting for all buildbots finish before pressing "Merge" button.
Gentoo bots are green.
24 remaining items
gh-85984: New additions and improvements to the tty library. (#101832)
Merge branch 'main' into gsallam/main
pythongh-85984: Document change in return type of tty functions
gh-85984: Document change in return type of tty functions (#110028)
pythongh-85984: Document change in return type of tty functions (pyth…
[3.12] gh-85984: Document change in return type of tty functions (GH-…
serhiy-storchaka commented on Oct 10, 2023
Why not make cfmakeraw() and cfmakecbreak() returning a new list instead of modifying the input in-place? In any case you need to make a copy, but it is errorprone, because the list contains a nested list. See #110392.
encukou commented on Jan 4, 2024
Regarding "master/slave" terminology:
I plan to use a strategy I learned at @evildmp's workshop. First, merge #102413, which extends os with a bunch of functions that handle PTY-pairs. There's no simple way to avoid using the inappropriate terms in these functions' docs.
The merge will make the os docs worse in this respect -- but it'll also make the issue more obvious, and hopefully easier to solve.
After that I'll propose a PR. Still don't know how that will look, but there's lively brainstorming and style guide recommendations over at the Docs community discord.
Anyway: @8vasu, feel free to focus on the techincal side, and leave terminology to me.
vstinner commented on Jan 8, 2024
See also: python/devguide#605 (which was already mentioned previously).
8vasu commented on Jan 20, 2024
I have also commented a variation of this on: #102413
@vstinner While I am not a CPython maintainer and hence do not have much say in deciding which directions such a prestigious project should take, I am an end user who does pty programming frequently (Python or otherwise) and I will have to deal with the consequences (good or bad) of any decisions taken here.
I have severe clinical OCD/OCPD and would like to issue a warning here: using generic names like main_fd, second_fd, or parent_fd, child_fd, or server_fd, client_fd will lead to havoc very easily. Just take a look at the source of your very own https://github.com/python/cpython/blob/3.12/Lib/pty.py and try a search/replace involving terms parent/child (already used by processes) or a program like ssh(1) which uses the terms server/client in networking context and also sets up a pty pair.
On the other hand one can easily have first_fd, second_fd, third_fd or even main_fd in their existing programs. The pair main, subordinate comes to mind, but again, main_fd might be taken and main, subordinate carry the same overtones as master, slave, which is what you are trying to avoid in the first place.
For a change that is easy to maintain for current and future Python maintainers and eliminates all possibility of confusion for end users when they are referring to documentation, we must use something that is:
Edit:
Some data: about naming pty-pairs; apart from the file/project/module/documentation-local confusion that inevitably will arise due to using process-specific terminology parent/child; networking-specific terminology server/client, and generic terms main, primary/seconday, here is some global data directly generated using script at the bottom of this post:
Current timezone and date: Sun Jan 21 06:17:13 AM CET 2024
Current directory: /tmp/tmp.21-Jan-2024+05:14:25.JZlA6tqeCz
Temporarily moving into directory: /tmp/tmp.uZECXBwUzE
Cloning CPython repository...
Cloning into 'cpython'...
remote: Enumerating objects: 1004157, done.
remote: Counting objects: 100% (690/690), done.
remote: Compressing objects: 100% (425/425), done.
remote: Total 1004157 (delta 428), reused 448 (delta 265), pack-reused 1003467
Receiving objects: 100% (1004157/1004157), 549.31 MiB | 5.16 MiB/s, done.
Resolving deltas: 100% (804152/804152), done.
Moving into CPython repository...
/tmp/tmp.uZECXBwUzE/cpython
Running grep to count number of occurences of concerned terms:
master: 757 occurences ignoring cases and 727 occurences not ignoring cases
master_fd: 80 occurences ignoring cases and 80 occurences not ignoring cases
slave: 155 occurences ignoring cases and 154 occurences not ignoring cases
slave_fd: 43 occurences ignoring cases and 43 occurences not ignoring cases
parent: 3760 occurences ignoring cases and 3255 occurences not ignoring cases
parent_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
child: 5703 occurences ignoring cases and 5067 occurences not ignoring cases
child_fd: 3 occurences ignoring cases and 3 occurences not ignoring cases
server: 6237 occurences ignoring cases and 5045 occurences not ignoring cases
server_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
client: 3036 occurences ignoring cases and 2682 occurences not ignoring cases
client_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
primary: 378 occurences ignoring cases and 346 occurences not ignoring cases
primary_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
secondary: 38 occurences ignoring cases and 35 occurences not ignoring cases
secondary_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
main: 25612 occurences ignoring cases and 24847 occurences not ignoring cases
main_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
second: 4361 occurences ignoring cases and 3987 occurences not ignoring cases
second_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
mother: 1 occurences ignoring cases and 1 occurences not ignoring cases
mother_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
(^|[^j])son: 0 occurences ignoring cases and 0 occurences not ignoring cases
(^|[^j])son_fd: 0 occurences ignoring cases and 0 occurences not ignoring cases
Removing CPython repository to free up space in /tmp...
gh-85984: Add POSIX pseudo-terminal functions. (GH-102413)
gh-85984: Add _POSIX_VDISABLE from unistd.h to termios module. (#114985)
pythongh-85984: Add POSIX pseudo-terminal functions. (pythonGH-102413)
pythongh-85984: Add _POSIX_VDISABLE from unistd.h to termios module. (p…
pythongh-85984: Document change in return type of tty functions (pyth…