Skip to content

Commit 601eac1

Browse files
committed
gh-140950: Reset shlex state in push_source() so post-EOF pushes are read
After get_token() reaches end of input it sets self.state to None. A subsequent push_source() did not reset state, so the next get_token() call returned EOF immediately and the newly pushed source was silently ignored. pop_source() already resets state to ' ' for the same reason; do the same in push_source().
1 parent cb3b4b9 commit 601eac1

3 files changed

Lines changed: 19 additions & 0 deletions

File tree

Lib/shlex.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ def push_source(self, newstream, newfile=None):
8181
self.infile = newfile
8282
self.instream = newstream
8383
self.lineno = 1
84+
# Reset state so that a source pushed after EOF (when state is None)
85+
# is still read. Mirrors pop_source().
86+
self.state = ' '
8487
if self.debug:
8588
if newfile is not None:
8689
print('shlex: pushing to file %s' % (self.infile,))

Lib/test/test_shlex.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,18 @@ def testPunctuationCharsReadOnly(self):
368368
with self.assertRaises(AttributeError):
369369
shlex_instance.punctuation_chars = False
370370

371+
def testPushSourceAfterEOF(self):
372+
# gh-140950: a source pushed after the current input has reached
373+
# EOF must still be read. Previously get_token() set state to None
374+
# at EOF, and push_source() did not reset it, so the new source
375+
# was silently ignored.
376+
lexer = shlex.shlex('a')
377+
self.assertEqual(lexer.get_token(), 'a')
378+
self.assertEqual(lexer.get_token(), lexer.eof)
379+
lexer.push_source('b')
380+
self.assertEqual(lexer.get_token(), 'b')
381+
self.assertEqual(lexer.get_token(), lexer.eof)
382+
371383
@cpython_only
372384
def test_lazy_imports(self):
373385
import_helper.ensure_lazy_imports('shlex', {'collections', 're', 'os'})
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix :class:`shlex.shlex` ignoring a source pushed via
2+
:meth:`~shlex.shlex.push_source` after the current input had reached EOF.
3+
:meth:`!push_source` now resets the internal lexer state, mirroring
4+
:meth:`~shlex.shlex.pop_source`.

0 commit comments

Comments
 (0)