From 14459a2097da55fe7cf85915f2806b929f213ca2 Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Thu, 23 Apr 2020 15:23:00 +0200 Subject: [PATCH 1/9] ConstrainedFloat schema: account for differences between IEEE floats and json --- pydantic/schema.py | 3 +++ pydantic/types.py | 21 +++++++++++++++++++++ tests/test_schema.py | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/pydantic/schema.py b/pydantic/schema.py index 63e2058adf..777e249a91 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.outer_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..72d9338186 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,7 @@ def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: maximum=cls.le, multipleOf=cls.multiple_of, ) + cls._schema_ieee_compatibility_transform(field_schema) @classmethod def __get_validators__(cls) -> 'CallableGenerator': @@ -346,6 +348,25 @@ def __get_validators__(cls) -> 'CallableGenerator': yield number_size_validator yield number_multiple_validator + @classmethod + def _schema_ieee_compatibility_transform(cls, field_schema: Dict[Any, Any]) -> None: + """Modify constraints to account for differences between IEEE floats and json + + Transformations applied: + - remove field exclusiveMinimum if it is equal to `-math.inf` + - remove field minimum if it is equal to `-math.inf` + - remove field exclusiveMaximum if it is equal to `math.inf` + - remove field maximum if it is equal to `math.inf` + """ + 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'] + def confloat( *, 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}), From 644eda4a58ab7916873a156bc5000bd69befff94 Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Thu, 23 Apr 2020 20:25:46 +0200 Subject: [PATCH 2/9] add changes --- changes/1417-vdwees.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changes/1417-vdwees.md diff --git a/changes/1417-vdwees.md b/changes/1417-vdwees.md new file mode 100644 index 0000000000..8473892089 --- /dev/null +++ b/changes/1417-vdwees.md @@ -0,0 +1,4 @@ + +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. From 89110ae38c282ab618fc3d0777cbef5ae628d5c4 Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Fri, 24 Apr 2020 16:25:07 +0200 Subject: [PATCH 3/9] Update changes/1417-vdwees.md Co-Authored-By: Samuel Colvin --- changes/1417-vdwees.md | 1 - 1 file changed, 1 deletion(-) diff --git a/changes/1417-vdwees.md b/changes/1417-vdwees.md index 8473892089..b04b6d3437 100644 --- a/changes/1417-vdwees.md +++ b/changes/1417-vdwees.md @@ -1,4 +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. From ed467f0cba88d0b7a71d9535391f74aefada6e30 Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Fri, 24 Apr 2020 16:25:29 +0200 Subject: [PATCH 4/9] Update changes/1417-vdwees.md Co-Authored-By: Samuel Colvin --- changes/1417-vdwees.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes/1417-vdwees.md b/changes/1417-vdwees.md index b04b6d3437..84eb1bc309 100644 --- a/changes/1417-vdwees.md +++ b/changes/1417-vdwees.md @@ -1,3 +1,3 @@ -Modify schema constraints on ConstrainedFloat so that exclusiveMinimum and +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. From a67247f1bc0626ce8596e5a1cdf0d2588f207a63 Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Fri, 24 Apr 2020 16:27:57 +0200 Subject: [PATCH 5/9] fixup --- changes/1417-vdwees.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes/1417-vdwees.md b/changes/1417-vdwees.md index 84eb1bc309..4f191031b7 100644 --- a/changes/1417-vdwees.md +++ b/changes/1417-vdwees.md @@ -1,3 +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. +`exclusiveMaximum` and `maximum` are not included if they are equal to `math.inf`. From 6fa457b951ea0706f50124f6f6e520a37c905ede Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Fri, 24 Apr 2020 16:30:22 +0200 Subject: [PATCH 6/9] Update pydantic/types.py Difference of styles :) Co-Authored-By: Samuel Colvin --- pydantic/types.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pydantic/types.py b/pydantic/types.py index 72d9338186..217161d431 100644 --- a/pydantic/types.py +++ b/pydantic/types.py @@ -350,7 +350,8 @@ def __get_validators__(cls) -> 'CallableGenerator': @classmethod def _schema_ieee_compatibility_transform(cls, field_schema: Dict[Any, Any]) -> None: - """Modify constraints to account for differences between IEEE floats and json + """ + Modify constraints to account for differences between IEEE floats and json Transformations applied: - remove field exclusiveMinimum if it is equal to `-math.inf` From 539c11cd66538766096caca7315b20dbd88b5a13 Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Fri, 24 Apr 2020 16:50:13 +0200 Subject: [PATCH 7/9] merge _schema_ieee_compatibility_transform into parent method --- pydantic/types.py | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/pydantic/types.py b/pydantic/types.py index 217161d431..b5b81eb987 100644 --- a/pydantic/types.py +++ b/pydantic/types.py @@ -340,25 +340,7 @@ def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: maximum=cls.le, multipleOf=cls.multiple_of, ) - cls._schema_ieee_compatibility_transform(field_schema) - - @classmethod - def __get_validators__(cls) -> 'CallableGenerator': - yield strict_float_validator if cls.strict else float_validator - yield number_size_validator - yield number_multiple_validator - - @classmethod - def _schema_ieee_compatibility_transform(cls, field_schema: Dict[Any, Any]) -> None: - """ - Modify constraints to account for differences between IEEE floats and json - - Transformations applied: - - remove field exclusiveMinimum if it is equal to `-math.inf` - - remove field minimum if it is equal to `-math.inf` - - remove field exclusiveMaximum if it is equal to `math.inf` - - remove field maximum if it is equal to `math.inf` - """ + # 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: @@ -368,6 +350,12 @@ def _schema_ieee_compatibility_transform(cls, field_schema: Dict[Any, Any]) -> N if field_schema.get('maximum') == math.inf: del field_schema['maximum'] + @classmethod + def __get_validators__(cls) -> 'CallableGenerator': + yield strict_float_validator if cls.strict else float_validator + yield number_size_validator + yield number_multiple_validator + def confloat( *, From f40747ff75cce996cdf23fb2aa5fd2c92161d725 Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Fri, 24 Apr 2020 16:52:12 +0200 Subject: [PATCH 8/9] capitalize --- pydantic/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydantic/types.py b/pydantic/types.py index b5b81eb987..2b7a64e946 100644 --- a/pydantic/types.py +++ b/pydantic/types.py @@ -340,7 +340,7 @@ 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 + # 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: From 78d1218b8f496b38e6ffdba90c7d937e04cba5ea Mon Sep 17 00:00:00 2001 From: Jesse VanderWees Date: Fri, 24 Apr 2020 18:41:01 +0200 Subject: [PATCH 9/9] use type_, not outer_type_ --- pydantic/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydantic/schema.py b/pydantic/schema.py index 777e249a91..ec0a085468 100644 --- a/pydantic/schema.py +++ b/pydantic/schema.py @@ -234,7 +234,7 @@ 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.outer_type_, '__modify_schema__', None) + modify_schema = getattr(field.type_, '__modify_schema__', None) if modify_schema: modify_schema(f_schema) return f_schema