From 845f573c0db34c65a7eb9092af20fa7fe7b1404d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lafr=C3=A9choux?= Date: Tue, 30 Apr 2024 11:19:27 +0200 Subject: [PATCH 1/3] DateTime field: allow timestamp 0 --- src/marshmallow/fields.py | 2 -- tests/test_deserialization.py | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/marshmallow/fields.py b/src/marshmallow/fields.py index 42e529c95..ceb32aa91 100644 --- a/src/marshmallow/fields.py +++ b/src/marshmallow/fields.py @@ -1285,8 +1285,6 @@ def _serialize(self, value, attr, obj, **kwargs) -> str | float | None: return value.strftime(data_format) def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime: - if not value: # Falsy values, e.g. '', None, [] are not valid - raise self.make_error("invalid", input=value, obj_type=self.OBJ_TYPE) data_format = self.format or self.DEFAULT_FORMAT func = self.DESERIALIZATION_FUNCS.get(data_format) try: diff --git a/tests/test_deserialization.py b/tests/test_deserialization.py index 6c32feadb..4588e2a7d 100644 --- a/tests/test_deserialization.py +++ b/tests/test_deserialization.py @@ -422,6 +422,7 @@ def test_field_toggle_show_invalid_value_in_error_message(self): [ "not-a-datetime", 42, + 0, "", [], "2018", @@ -576,7 +577,7 @@ def test_timestamp_field_deserialization(self, fmt, value, expected): @pytest.mark.parametrize("fmt", ["timestamp", "timestamp_ms"]) @pytest.mark.parametrize( "in_value", - ["", "!@#", 0, -1, dt.datetime(2013, 11, 10, 1, 23, 45)], + ["", "!@#", -1, dt.datetime(2013, 11, 10, 1, 23, 45)], ) def test_invalid_timestamp_field_deserialization(self, fmt, in_value): field = fields.DateTime(format=fmt) From 6e72beb7daa09ba993a2d3d1738ef2f75a95f607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lafr=C3=A9choux?= Date: Tue, 30 Apr 2024 17:50:34 +0200 Subject: [PATCH 2/3] DateTime field: reject timestamp True/False --- src/marshmallow/fields.py | 2 ++ tests/test_deserialization.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/marshmallow/fields.py b/src/marshmallow/fields.py index ceb32aa91..3d3bec961 100644 --- a/src/marshmallow/fields.py +++ b/src/marshmallow/fields.py @@ -1285,6 +1285,8 @@ def _serialize(self, value, attr, obj, **kwargs) -> str | float | None: return value.strftime(data_format) def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime: + if value is True or value is False: + raise self.make_error("invalid", input=value, obj_type=self.OBJ_TYPE) data_format = self.format or self.DEFAULT_FORMAT func = self.DESERIALIZATION_FUNCS.get(data_format) try: diff --git a/tests/test_deserialization.py b/tests/test_deserialization.py index 4588e2a7d..442b5efbd 100644 --- a/tests/test_deserialization.py +++ b/tests/test_deserialization.py @@ -422,6 +422,8 @@ def test_field_toggle_show_invalid_value_in_error_message(self): [ "not-a-datetime", 42, + True, + False, 0, "", [], From 58fbbcd3446ade39ea3be83ce9ee9170acf0230b Mon Sep 17 00:00:00 2001 From: Jared Deckard Date: Wed, 1 May 2024 17:38:13 +0200 Subject: [PATCH 3/3] Encapsulate timestamp boolean check in utils --- src/marshmallow/fields.py | 2 -- src/marshmallow/utils.py | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/marshmallow/fields.py b/src/marshmallow/fields.py index 3d3bec961..ceb32aa91 100644 --- a/src/marshmallow/fields.py +++ b/src/marshmallow/fields.py @@ -1285,8 +1285,6 @@ def _serialize(self, value, attr, obj, **kwargs) -> str | float | None: return value.strftime(data_format) def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime: - if value is True or value is False: - raise self.make_error("invalid", input=value, obj_type=self.OBJ_TYPE) data_format = self.format or self.DEFAULT_FORMAT func = self.DESERIALIZATION_FUNCS.get(data_format) try: diff --git a/src/marshmallow/utils.py b/src/marshmallow/utils.py index 1194bb3a7..a5fe72624 100644 --- a/src/marshmallow/utils.py +++ b/src/marshmallow/utils.py @@ -192,6 +192,8 @@ def from_iso_date(value): def from_timestamp(value: typing.Any) -> dt.datetime: + if value is True or value is False: + raise ValueError("Not a valid POSIX timestamp") value = float(value) if value < 0: raise ValueError("Not a valid POSIX timestamp")