fix: add correct handling for negative time deltas of iso format serialization (#3899) (#3909)

* changed timedelta_isoformat in pydantic/json.py to produce ISO 8601 compliant string even for negative values
* added tests to verify correct serialization of negative time deltas

Co-authored-by: Josef <sorry.i-keep@it.private>
This commit is contained in:
Pepa
2022-08-08 15:54:09 +02:00
committed by GitHub
parent cd439a4e8d
commit ef4a5d3315
3 changed files with 7 additions and 2 deletions
+2
View File
@@ -0,0 +1,2 @@
Fix incorrect deserialization of python timedelta object to ISO 8601 for negative time deltas.
Minus was serialized in incorrect place ("P-1DT23H59M59.888735S" instead of correct "-P1DT23H59M59.888735S")
+2 -2
View File
@@ -105,8 +105,8 @@ def custom_pydantic_encoder(type_encoders: Dict[Any, Callable[[Type[Any]], Any]]
def timedelta_isoformat(td: datetime.timedelta) -> str:
"""
ISO 8601 encoding for timedeltas.
ISO 8601 encoding for Python timedelta object.
"""
minutes, seconds = divmod(td.seconds, 60)
hours, minutes = divmod(minutes, 60)
return f'P{td.days}DT{hours:d}H{minutes:d}M{seconds:d}.{td.microseconds:06d}S'
return f'{"-" if td.days < 0 else ""}P{abs(td.days)}DT{hours:d}H{minutes:d}M{seconds:d}.{td.microseconds:06d}S'
+3
View File
@@ -46,6 +46,7 @@ class MyEnum(Enum):
(datetime.datetime(2032, 1, 1), '"2032-01-01T00:00:00"'),
(datetime.time(12, 34, 56), '"12:34:56"'),
(datetime.timedelta(days=12, seconds=34, microseconds=56), '1036834.000056'),
(datetime.timedelta(seconds=-1), '-1.0'),
({1, 2, 3}, '[1, 2, 3]'),
(frozenset([1, 2, 3]), '[1, 2, 3]'),
((v for v in range(4)), '[0, 1, 2, 3]'),
@@ -142,6 +143,8 @@ def test_invalid_model():
[
(datetime.timedelta(days=12, seconds=34, microseconds=56), 'P12DT0H0M34.000056S'),
(datetime.timedelta(days=1001, hours=1, minutes=2, seconds=3, microseconds=654_321), 'P1001DT1H2M3.654321S'),
(datetime.timedelta(seconds=-1), '-P1DT23H59M59.000000S'),
(datetime.timedelta(), 'P0DT0H0M0.000000S'),
],
)
def test_iso_timedelta(input, output):