From dc9c50e56e80bde1cf1a467994317de5bf0b4c7a Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Sat, 11 Jul 2026 08:17:57 -0400 Subject: [PATCH] Report an out-of-range duration as invalid instead of erroring. Signed-off-by: Charlie Tonneslan --- jsonschema/_format.py | 9 ++++++++- jsonschema/tests/test_format.py | 12 ++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 5efda86e6..80a174708 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -3,6 +3,7 @@ from contextlib import suppress from datetime import date, datetime from uuid import UUID +import decimal import ipaddress import re import typing @@ -524,7 +525,13 @@ def is_uri_template(instance: object) -> bool: @_checks_drafts( draft201909="duration", draft202012="duration", - raises=isoduration.DurationParsingException, + # isoduration parses components with decimal.Decimal, which raises a + # decimal.DecimalException (e.g. Overflow) rather than a + # DurationParsingException on extreme values such as "P1E1000000D". + raises=( + isoduration.DurationParsingException, + decimal.DecimalException, + ), ) def is_duration(instance: object) -> bool: if not isinstance(instance, str): diff --git a/jsonschema/tests/test_format.py b/jsonschema/tests/test_format.py index d829f9848..5f2b7b107 100644 --- a/jsonschema/tests/test_format.py +++ b/jsonschema/tests/test_format.py @@ -89,3 +89,15 @@ def test_repr(self): repr(checker), "", ) + + def test_duration_with_overflowing_exponent_is_invalid(self): + # A duration whose exponent overflows decimal used to raise an uncaught + # decimal.Overflow instead of reporting the instance as invalid. + # See https://github.com/python-jsonschema/jsonschema/issues/1511 + try: + import isoduration # noqa: F401 + except ImportError: + self.skipTest("isoduration is not installed") + checker = FormatChecker() + with self.assertRaises(FormatError): + checker.check(instance="P1E1000000D", format="duration")