From 04719da910ce35966f84f8facb6ad1091aae21fb Mon Sep 17 00:00:00 2001 From: eeshsaxena Date: Sat, 15 Aug 2026 13:42:01 +0530 Subject: [PATCH] Raise ParseError, not StopIteration, from readOne on an empty stream readOne returns next(readComponents(...)). An empty or whitespace-only stream produces no components, so next() raised a bare StopIteration out of readOne. Catch it and raise ParseError instead. --- tests/test_vobject_parsing.py | 10 ++++++++++ vobject/base.py | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/test_vobject_parsing.py b/tests/test_vobject_parsing.py index e18adc5..4b9873d 100644 --- a/tests/test_vobject_parsing.py +++ b/tests/test_vobject_parsing.py @@ -143,6 +143,16 @@ def test_bad_stream(): vobject.base.readOne(bad_stream) +def test_empty_stream(): + """ + An empty or whitespace-only stream has no components and used to raise a + bare StopIteration; it should raise ParseError. + """ + for stream in ("", " ", "\n\n\t"): + with pytest.raises(vobject.base.ParseError): + vobject.base.readOne(stream) + + def test_bad_line(): """ Test bad line in ics file diff --git a/vobject/base.py b/vobject/base.py index 6a88668..6cf4378 100644 --- a/vobject/base.py +++ b/vobject/base.py @@ -1122,7 +1122,12 @@ def readOne(stream, validate=False, transform=True, ignoreUnreadable=False, allo """ Return the first component from stream. """ - return next(readComponents(stream, validate, transform, ignoreUnreadable, allowQP)) + try: + return next(readComponents(stream, validate, transform, ignoreUnreadable, allowQP)) + except StopIteration: + # An empty (or whitespace-only) stream yields no components; report it + # as a parse error instead of letting a bare StopIteration escape. + raise ParseError("No components in stream") # --------------------------- version registry ---------------------------------