Skip to content

Commit 7c5378e

Browse files
Issue 23798: Wrap getpass.getpass in a signal handler to avoid SIGTTOU (sonic-net#4061)
Python 3.13 will raise a SIGTTOU signal when getpass.getpass is called in a background process, like when running under pytest. Wrap the call in a signal handler to ignore the signal and avoid hanging.
1 parent 28dfb29 commit 7c5378e

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

tests/remote_cli_test.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import socket
1313
import termios
1414
import getpass
15+
import signal
1516

1617
MULTI_LC_REXEC_OUTPUT = '''======== LINE-CARD0|sonic-lc1 output: ========
1718
hello world
@@ -83,7 +84,18 @@ def mock_getpass(prompt="Password:", stream=None):
8384

8485

8586
class TestRemoteExec(object):
86-
__getpass = getpass.getpass
87+
# Store the original function at class definition time to avoid recursion
88+
_original_getpass = getpass.getpass
89+
90+
@staticmethod
91+
def __getpass(prompt="Password:", stream=None):
92+
"""SIGTTOU-safe wrapper for getpass.getpass() for Python 3.13 compatibility"""
93+
original_sigttou_handler = signal.signal(signal.SIGTTOU, signal.SIG_IGN)
94+
try:
95+
# Call the original function, in case getpass.getpass has been overridden
96+
return TestRemoteExec._original_getpass(prompt, stream)
97+
finally:
98+
signal.signal(signal.SIGTTOU, original_sigttou_handler)
8799

88100
@classmethod
89101
def setup_class(cls):
@@ -225,9 +237,10 @@ def test_rexec_without_password_input(self):
225237
runner = CliRunner()
226238
getpass.getpass = TestRemoteExec.__getpass
227239
LINECARD_NAME = "all"
228-
result = runner.invoke(
229-
rexec.cli, [LINECARD_NAME, "-c", "show version"])
240+
241+
result = runner.invoke(rexec.cli, [LINECARD_NAME, "-c", "show version"])
230242
getpass.getpass = mock_getpass
243+
231244
print(result.output)
232245
assert result.exit_code == 1, result.output
233246
assert "Aborted" in result.output

0 commit comments

Comments
 (0)