diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 62c0e4ee..be1c07e3 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 string @@ -518,7 +519,10 @@ def is_uri_template(instance: object) -> bool: @_checks_drafts( draft201909="duration", draft202012="duration", - raises=isoduration.DurationParsingException, + 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 d829f984..99cd5f8a 100644 --- a/jsonschema/tests/test_format.py +++ b/jsonschema/tests/test_format.py @@ -80,6 +80,14 @@ def test_format_checkers_come_with_defaults(self): with self.assertRaises(FormatError): checker.check(instance="not-an-ipv4", format="ipv4") + def test_duration_overflow_is_invalid(self): + checker = FormatChecker() + if "duration" not in checker.checkers: + self.skipTest("isoduration is not installed") + + with self.assertRaises(FormatError): + checker.check(instance="P1E1000000D", format="duration") + def test_repr(self): checker = FormatChecker(formats=()) checker.checks("foo")(lambda thing: True) # pragma: no cover