Skip to content

Commit

Permalink
Add ConfigDict.ser_json_inf_nan
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Nov 17, 2023
1 parent 575dcd9 commit 8ac095b
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/concepts/json_schema.md
Expand Up @@ -187,6 +187,7 @@ Specifically, the following config options are relevant:
* [`json_schema_extra`][pydantic.config.ConfigDict.json_schema_extra]
* [`ser_json_timedelta`][pydantic.config.ConfigDict.ser_json_timedelta]
* [`ser_json_bytes`][pydantic.config.ConfigDict.ser_json_bytes]
* [`ser_json_inf_nan`][pydantic.config.ConfigDict.ser_json_inf_nan]

### Unenforced `Field` constraints

Expand Down
1 change: 1 addition & 0 deletions pydantic/_internal/_config.py
Expand Up @@ -167,6 +167,7 @@ def dict_not_none(**kwargs: Any) -> Any:
strict=self.config_dict.get('strict'),
ser_json_timedelta=self.config_dict.get('ser_json_timedelta'),
ser_json_bytes=self.config_dict.get('ser_json_bytes'),
ser_json_inf_nan=self.config_dict.get('ser_json_inf_nan'),
from_attributes=self.config_dict.get('from_attributes'),
loc_by_alias=self.config_dict.get('loc_by_alias'),
revalidate_instances=self.config_dict.get('revalidate_instances'),
Expand Down
9 changes: 9 additions & 0 deletions pydantic/config.py
Expand Up @@ -540,6 +540,15 @@ class Transaction(BaseModel):
- `'base64'` will serialize bytes to URL safe base64 strings.
"""

ser_json_inf_nan: Literal['null', 'constants']
"""
The encoding of JSON serialized infinity and NaN float values. Accepts the string values of `'null'` and `'base64'`.
Defaults to `'null'`.
- `'null'` will serialize infinity and NaN values as `null`.
- `'constants'` will serialize infinity and NaN values as `Infinity` and `NaN`.
"""

# whether to validate default values during validation, default False
validate_default: bool
"""Whether to validate default values during validation. Defaults to `False`."""
Expand Down
25 changes: 23 additions & 2 deletions tests/test_types.py
Expand Up @@ -38,7 +38,7 @@
import annotated_types
import dirty_equals
import pytest
from dirty_equals import HasRepr, IsOneOf, IsStr
from dirty_equals import HasRepr, IsFloatNan, IsOneOf, IsStr
from pydantic_core import CoreSchema, PydanticCustomError, SchemaError, core_schema
from typing_extensions import Annotated, Literal, TypedDict, get_args

Expand Down Expand Up @@ -2529,7 +2529,7 @@ class Model(BaseModel):
]


def test_finite_float_validation():
def test_infinite_float_validation():
class Model(BaseModel):
a: float = None

Expand All @@ -2538,6 +2538,27 @@ class Model(BaseModel):
assert math.isnan(Model(a=float('nan')).a)


@pytest.mark.parametrize(
('ser_json_inf_nan', 'input', 'output', 'python_roundtrip'),
(
('null', float('inf'), 'null', None),
('null', float('-inf'), 'null', None),
('null', float('nan'), 'null', None),
('constants', float('inf'), 'Infinity', float('inf')),
('constants', float('-inf'), '-Infinity', float('-inf')),
('constants', float('nan'), 'NaN', IsFloatNan),
),
)
def test_infinite_float_json_serialization(ser_json_inf_nan, input, output, python_roundtrip):
class Model(BaseModel):
model_config = ConfigDict(ser_json_inf_nan=ser_json_inf_nan)
a: float

json_string = Model(a=input).model_dump_json()
assert json_string == f'{{"a":{output}}}'
assert json.loads(json_string) == {'a': python_roundtrip}


@pytest.mark.parametrize('value', [float('inf'), float('-inf'), float('nan')])
def test_finite_float_validation_error(value):
class Model(BaseModel):
Expand Down

0 comments on commit 8ac095b

Please sign in to comment.