@@ -7,8 +7,6 @@ pub use builtins::{ascii, print, reversed};
77
88#[ pymodule]
99mod builtins {
10- use std:: io:: IsTerminal ;
11-
1210 use crate :: {
1311 AsObject , PyObject , PyObjectRef , PyPayload , PyRef , PyResult , TryFromObject , VirtualMachine ,
1412 builtins:: {
@@ -464,6 +462,8 @@ mod builtins {
464462
465463 #[ pyfunction]
466464 fn input ( prompt : OptionalArg < PyStrRef > , vm : & VirtualMachine ) -> PyResult {
465+ use std:: io:: IsTerminal ;
466+
467467 let stdin = sys:: get_stdin ( vm) ?;
468468 let stdout = sys:: get_stdout ( vm) ?;
469469 let stderr = sys:: get_stderr ( vm) ?;
@@ -476,8 +476,13 @@ mod builtins {
476476 . is_ok_and ( |fd| fd == expected)
477477 } ;
478478
479- // everything is normal, we can just rely on rustyline to use stdin/stdout
480- if fd_matches ( & stdin, 0 ) && fd_matches ( & stdout, 1 ) && std:: io:: stdin ( ) . is_terminal ( ) {
479+ // Check if we should use rustyline (interactive terminal, not PTY child)
480+ let use_rustyline = fd_matches ( & stdin, 0 )
481+ && fd_matches ( & stdout, 1 )
482+ && std:: io:: stdin ( ) . is_terminal ( )
483+ && !is_pty_child ( ) ;
484+
485+ if use_rustyline {
481486 let prompt = prompt. as_ref ( ) . map_or ( "" , |s| s. as_str ( ) ) ;
482487 let mut readline = Readline :: new ( ( ) ) ;
483488 match readline. readline ( prompt) {
@@ -502,6 +507,21 @@ mod builtins {
502507 }
503508 }
504509
510+ /// Check if we're running in a PTY child process (e.g., after pty.fork()).
511+ /// pty.fork() calls setsid(), making the child a session leader.
512+ /// In this case, rustyline may hang because it uses raw mode.
513+ #[ cfg( unix) ]
514+ fn is_pty_child ( ) -> bool {
515+ use nix:: unistd:: { getpid, getsid} ;
516+ // If this process is a session leader, we're likely in a PTY child
517+ getsid ( None ) == Ok ( getpid ( ) )
518+ }
519+
520+ #[ cfg( not( unix) ) ]
521+ fn is_pty_child ( ) -> bool {
522+ false
523+ }
524+
505525 #[ pyfunction]
506526 fn isinstance ( obj : PyObjectRef , typ : PyObjectRef , vm : & VirtualMachine ) -> PyResult < bool > {
507527 obj. is_instance ( & typ, vm)
0 commit comments