diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 6fe2ec98fb40888..4da883b787898a0 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -180,8 +180,7 @@ def __init__(self, cmd, timeout, output=None, stderr=None): self.stderr = stderr def __str__(self): - return ("Command '%s' timed out after %s seconds" % - (self.cmd, self.timeout)) + return f"Command {self.cmd!r} timed out after {self.timeout} seconds" @property def stdout(self): diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index d066ae85dfc51a6..098af792bcc86de 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -2449,6 +2449,19 @@ def test_CalledProcessError_str(self): err = subprocess.CalledProcessError(-9876543, "fake cmd") self.assertEqual(str(err), "Command 'fake cmd' died with unknown signal 9876543.") + def test_TimeoutExpired_str(self): + # timeout command string + err = subprocess.TimeoutExpired("fake cmd", 1) + self.assertEqual(str(err), "Command 'fake cmd' timed out after 1 seconds") + + # timeout command string with a single-quote + err = subprocess.TimeoutExpired("fake ' cmd", 1) + self.assertEqual(str(err), 'Command "fake \' cmd" timed out after 1 seconds') + + # timeout command list + err = subprocess.TimeoutExpired(["fake", "cmd"], 1) + self.assertEqual(str(err), "Command ['fake', 'cmd'] timed out after 1 seconds") + def test_preexec(self): # DISCLAIMER: Setting environment variables is *not* a good use # of a preexec_fn. This is merely a test. diff --git a/Misc/NEWS.d/next/Library/2026-06-29-16-30-58.gh-issue-152558.CCfp-R.rst b/Misc/NEWS.d/next/Library/2026-06-29-16-30-58.gh-issue-152558.CCfp-R.rst new file mode 100644 index 000000000000000..84cca209ee4c6b4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-29-16-30-58.gh-issue-152558.CCfp-R.rst @@ -0,0 +1 @@ +Avoid redundant quoting in :exc:`subprocess.TimeoutExpired` messages.