diff --git a/Lib/shlex.py b/Lib/shlex.py index 5bf6e0d70e0012..5959f52dd12639 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -322,6 +322,9 @@ def quote(s): if not s: return "''" + if not isinstance(s, str): + raise TypeError(f"expected string object, got {type(s).__name__!r}") + # Use bytes.translate() for performance safe_chars = (b'%+,-./0123456789:=@' b'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index a13ddcb76b7bcb..2a355abdeeb30f 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -330,6 +330,7 @@ def testQuote(self): unsafe = '"`$\\!' + unicode_sample self.assertEqual(shlex.quote(''), "''") + self.assertEqual(shlex.quote(None), "''") self.assertEqual(shlex.quote(safeunquoted), safeunquoted) self.assertEqual(shlex.quote('test file name'), "'test file name'") for u in unsafe: @@ -338,6 +339,8 @@ def testQuote(self): for u in unsafe: self.assertEqual(shlex.quote("test%s'name'" % u), "'test%s'\"'\"'name'\"'\"''" % u) + self.assertRaises(TypeError, shlex.quote, 42) + self.assertRaises(TypeError, shlex.quote, b"abc") def testJoin(self): for split_command, command in [ diff --git a/Misc/NEWS.d/next/Library/2025-09-12-01-01-05.gh-issue-138804.46ZukT.rst b/Misc/NEWS.d/next/Library/2025-09-12-01-01-05.gh-issue-138804.46ZukT.rst new file mode 100644 index 00000000000000..5d403f8cf034ad --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-12-01-01-05.gh-issue-138804.46ZukT.rst @@ -0,0 +1,3 @@ +Raise :exc:`TypeError` instead of :exc:`AttributeError` when an argument of +incorrect type is passed to :func:`shlex.quote`. This restores the behavior of +the function prior to 3.14.