From 408822f40d2e65918a1311e324ac032af2ec3b1a Mon Sep 17 00:00:00 2001 From: ThanhNguyxn Date: Sat, 7 Feb 2026 17:44:29 +0700 Subject: [PATCH] gh-140950: Read pushed shlex source after EOF --- Lib/shlex.py | 1 + Lib/test/test_shlex.py | 10 ++++++++++ .../2026-02-07-16-55-00.gh-issue-140950.Jk2mQp.rst | 2 ++ 3 files changed, 13 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-02-07-16-55-00.gh-issue-140950.Jk2mQp.rst diff --git a/Lib/shlex.py b/Lib/shlex.py index 5959f52dd12639..c5076751562a03 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -81,6 +81,7 @@ def push_source(self, newstream, newfile=None): self.infile = newfile self.instream = newstream self.lineno = 1 + self.state = ' ' if self.debug: if newfile is not None: print('shlex: pushing to file %s' % (self.infile,)) diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index 2a355abdeeb30f..a9a52afd4815ba 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -179,6 +179,16 @@ def testCompat(self): "%s: %s != %s" % (self.data[i][0], l, self.data[i][1:])) + def test_push_source_after_eof(self): + for posix in (False, True): + with self.subTest(posix=posix): + lexer = shlex.shlex('a', posix=posix) + self.assertEqual(lexer.get_token(), 'a') + self.assertEqual(lexer.get_token(), lexer.eof) + lexer.push_source('b') + self.assertEqual(lexer.get_token(), 'b') + self.assertEqual(lexer.get_token(), lexer.eof) + def testSyntaxSplitAmpersandAndPipe(self): """Test handling of syntax splitting of &, |""" # Could take these forms: &&, &, |&, ;&, ;;& diff --git a/Misc/NEWS.d/next/Library/2026-02-07-16-55-00.gh-issue-140950.Jk2mQp.rst b/Misc/NEWS.d/next/Library/2026-02-07-16-55-00.gh-issue-140950.Jk2mQp.rst new file mode 100644 index 00000000000000..9df5673e8ecab8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-07-16-55-00.gh-issue-140950.Jk2mQp.rst @@ -0,0 +1,2 @@ +Fix :meth:`shlex.shlex.push_source` so a new source pushed after EOF is read +correctly instead of being skipped.