1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
From: Colin Watson <cjwatson@debian.org>
Date: Sun, 15 Jun 2025 10:52:15 +0100
Subject: Make empty durations an error in pure-Python parser
Some of Debian's test runners noticed that the pydantic-extra-types
tests are failing on 32-bit architectures:
______________________ test_invalid_zero_duration_string _______________________
def test_invalid_zero_duration_string():
"""'P' is not a valid ISO 8601 duration and should raise a validation error."""
> with pytest.raises(ValidationError):
E Failed: DID NOT RAISE <class 'pydantic_core._pydantic_core.ValidationError'>
tests/test_pendulum_dt.py:447: Failed
Debian currently has pendulum 3.0.0, which disabled the Rust extensions
if `struct.calcsize("P") == 4`, and the Rust and Python parsers disagree
about how to handle an empty duration: the Rust parser reports an error,
while the Python parser returns `Duration()`. 3.1.0 removes that
particular limitation on using Rust extensions on 32-bit architectures,
but the parser discrepancy still seems to be present.
I don't have access to the full text of the standard, but Wikipedia's
summary says 'However, at least one element must be present, thus "P" is
not a valid representation for a duration of 0 seconds', so I think the
Rust parser is correct. Adjust the Python parser to match.
Origin: other, https://github.com/python-pendulum/pendulum/pull/903
Last-Update: 2025-06-16
---
src/pendulum/parsing/iso8601.py | 2 +-
tests/parsing/test_parse_iso8601.py | 10 ++++++++--
2 files changed, 9 insertions(+), 3 deletions(-)
--- a/src/pendulum/parsing/iso8601.py
+++ b/src/pendulum/parsing/iso8601.py
@@ -267,3 +267,3 @@
m = ISO8601_DURATION.match(text)
- if not m:
+ if not m or (not m.group("w") and not m.group("ymd") and not m.group("hms")):
return None
--- a/tests/parsing/test_parse_iso8601.py
+++ b/tests/parsing/test_parse_iso8601.py
@@ -92,3 +92,3 @@
-def test_parse_ios8601_invalid():
+def test_parse_iso8601_invalid():
# Invalid month
@@ -195,3 +195,3 @@
)
-def test_parse_ios8601_duration(
+def test_parse_iso8601_duration(
text: str, expected: tuple[int, int, int, int, int, int, int, int]
@@ -210 +210,7 @@
) == expected
+
+
+def test_parse_iso8601_duration_invalid():
+ # Must include at least one element
+ with pytest.raises(ValueError):
+ parse_iso8601("P")
|