diff --git a/changes/1417-vdwees.md b/changes/1417-vdwees.md new file mode 100644 index 0000000000..4f191031b7 --- /dev/null +++ b/changes/1417-vdwees.md @@ -0,0 +1,3 @@ +Modify schema constraints on `ConstrainedFloat` so that `exclusiveMinimum` and +minimum are not included in the schema if they are equal to `-math.inf` and +`exclusiveMaximum` and `maximum` are not included if they are equal to `math.inf`. diff --git a/pydantic/schema.py b/pydantic/schema.py index 63e2058adf..ec0a085468 100644 --- a/pydantic/schema.py +++ b/pydantic/schema.py @@ -234,6 +234,9 @@ def get_field_schema_validations(field: ModelField) -> Dict[str, Any]: f_schema['const'] = field.default if field.field_info.extra: f_schema.update(field.field_info.extra) + modify_schema = getattr(field.type_, '__modify_schema__', None) + if modify_schema: + modify_schema(f_schema) return f_schema diff --git a/pydantic/types.py b/pydantic/types.py index 8eb72d6ac9..2b7a64e946 100644 --- a/pydantic/types.py +++ b/pydantic/types.py @@ -1,3 +1,4 @@ +import math import re import warnings from decimal import Decimal @@ -339,6 +340,15 @@ def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: maximum=cls.le, multipleOf=cls.multiple_of, ) + # Modify constraints to account for differences between IEEE floats and JSON + if field_schema.get('exclusiveMinimum') == -math.inf: + del field_schema['exclusiveMinimum'] + if field_schema.get('minimum') == -math.inf: + del field_schema['minimum'] + if field_schema.get('exclusiveMaximum') == math.inf: + del field_schema['exclusiveMaximum'] + if field_schema.get('maximum') == math.inf: + del field_schema['maximum'] @classmethod def __get_validators__(cls) -> 'CallableGenerator': diff --git a/tests/test_schema.py b/tests/test_schema.py index e78ddb69e0..b0bd2f0206 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -1,3 +1,4 @@ +import math import os import sys import tempfile @@ -1119,6 +1120,10 @@ class UserModel(BaseModel): ({'lt': 5}, float, {'type': 'number', 'exclusiveMaximum': 5}), ({'ge': 2}, float, {'type': 'number', 'minimum': 2}), ({'le': 5}, float, {'type': 'number', 'maximum': 5}), + ({'gt': -math.inf}, float, {'type': 'number'}), + ({'lt': math.inf}, float, {'type': 'number'}), + ({'ge': -math.inf}, float, {'type': 'number'}), + ({'le': math.inf}, float, {'type': 'number'}), ({'multiple_of': 5}, float, {'type': 'number', 'multipleOf': 5}), ({'gt': 2}, Decimal, {'type': 'number', 'exclusiveMinimum': 2}), ({'lt': 5}, Decimal, {'type': 'number', 'exclusiveMaximum': 5}),