Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-marshmallow for openSUSE:Factory checked in at 2022-12-03 10:03:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-marshmallow (Old) and /work/SRC/openSUSE:Factory/.python-marshmallow.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-marshmallow" Sat Dec 3 10:03:43 2022 rev:19 rq:1039662 version:3.19.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-marshmallow/python-marshmallow.changes 2022-11-01 13:42:29.399871111 +0100 +++ /work/SRC/openSUSE:Factory/.python-marshmallow.new.1835/python-marshmallow.changes 2022-12-03 10:03:59.555359010 +0100 @@ -1,0 +2,6 @@ +Fri Dec 2 20:31:35 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com> + +- Update to 3.19.0 + * Add timestamp and timestamp_ms formats to fields.DateTime (#612). Thanks @vgavro for the suggestion and thanks @vanHoi for the PR. + +------------------------------------------------------------------- Old: ---- marshmallow-3.18.0.tar.gz New: ---- marshmallow-3.19.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-marshmallow.spec ++++++ --- /var/tmp/diff_new_pack.d5lmnA/_old 2022-12-03 10:04:00.067361855 +0100 +++ /var/tmp/diff_new_pack.d5lmnA/_new 2022-12-03 10:04:00.071361878 +0100 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-marshmallow -Version: 3.18.0 +Version: 3.19.0 Release: 0 Summary: ORM/ODM/framework-agnostic library to convert datatypes from/to Python types License: BSD-3-Clause AND MIT ++++++ marshmallow-3.18.0.tar.gz -> marshmallow-3.19.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/AUTHORS.rst new/marshmallow-3.19.0/AUTHORS.rst --- old/marshmallow-3.18.0/AUTHORS.rst 2022-09-15 22:26:57.000000000 +0200 +++ new/marshmallow-3.19.0/AUTHORS.rst 2022-11-11 17:10:31.000000000 +0100 @@ -170,3 +170,4 @@ - Isira Seneviratne `@Isira-Seneviratne <https://github.com/Isira-Seneviratne>`_ - Karthikeyan Singaravelan `@tirkarthi <https://github.com/tirkarthi>`_ - Marco Satti `@marcosatti <https://github.com/marcosatti>`_ +- Ivo Reumkens `@vanHoi <https://github.com/vanHoi>`_ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/CHANGELOG.rst new/marshmallow-3.19.0/CHANGELOG.rst --- old/marshmallow-3.18.0/CHANGELOG.rst 2022-09-15 22:26:57.000000000 +0200 +++ new/marshmallow-3.19.0/CHANGELOG.rst 2022-11-11 17:10:31.000000000 +0100 @@ -1,6 +1,16 @@ Changelog --------- +3.19.0 (2022-11-11) +******************* + +Features: + +- Add ``timestamp`` and ``timestamp_ms`` formats to `fields.DateTime` + (:issue:`612`). + Thanks :user:`vgavro` for the suggestion and thanks :user:`vanHoi` for + the PR. + 3.18.0 (2022-09-15) ******************* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/PKG-INFO new/marshmallow-3.19.0/PKG-INFO --- old/marshmallow-3.18.0/PKG-INFO 2022-09-15 22:27:10.895295400 +0200 +++ new/marshmallow-3.19.0/PKG-INFO 2022-11-11 17:10:43.928643500 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: marshmallow -Version: 3.18.0 +Version: 3.19.0 Summary: A lightweight library for converting complex datatypes to and from native Python datatypes. Home-page: https://github.com/marshmallow-code/marshmallow Author: Steven Loria diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/setup.py new/marshmallow-3.19.0/setup.py --- old/marshmallow-3.18.0/setup.py 2022-09-15 22:26:57.000000000 +0200 +++ new/marshmallow-3.19.0/setup.py 2022-11-11 17:10:31.000000000 +0100 @@ -4,13 +4,13 @@ EXTRAS_REQUIRE = { "tests": ["pytest", "pytz", "simplejson"], "lint": [ - "mypy==0.971", + "mypy==0.990", "flake8==5.0.4", - "flake8-bugbear==22.9.11", + "flake8-bugbear==22.10.25", "pre-commit~=2.4", ], "docs": [ - "sphinx==5.1.1", + "sphinx==5.3.0", "sphinx-issues==3.0.1", "alabaster==0.7.12", "sphinx-version-warning==1.1.2", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/src/marshmallow/__init__.py new/marshmallow-3.19.0/src/marshmallow/__init__.py --- old/marshmallow-3.18.0/src/marshmallow/__init__.py 2022-09-15 22:26:57.000000000 +0200 +++ new/marshmallow-3.19.0/src/marshmallow/__init__.py 2022-11-11 17:10:31.000000000 +0100 @@ -16,7 +16,7 @@ from . import fields -__version__ = "3.18.0" +__version__ = "3.19.0" __parsed_version__ = Version(__version__) __version_info__: tuple[int, int, int] | tuple[ int, int, int, str, int diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/src/marshmallow/fields.py new/marshmallow-3.19.0/src/marshmallow/fields.py --- old/marshmallow-3.18.0/src/marshmallow/fields.py 2022-09-15 22:26:57.000000000 +0200 +++ new/marshmallow-3.19.0/src/marshmallow/fields.py 2022-11-11 17:10:31.000000000 +0100 @@ -1218,11 +1218,14 @@ Example: ``'2014-12-22T03:12:58.019077+00:00'`` :param format: Either ``"rfc"`` (for RFC822), ``"iso"`` (for ISO8601), - or a date format string. If `None`, defaults to "iso". + ``"timestamp"``, ``"timestamp_ms"`` (for a POSIX timestamp) or a date format string. + If `None`, defaults to "iso". :param kwargs: The same keyword arguments that :class:`Field` receives. .. versionchanged:: 3.0.0rc9 Does not modify timezone information on (de)serialization. + .. versionchanged:: 3.19 + Add timestamp as a format. """ SERIALIZATION_FUNCS = { @@ -1230,13 +1233,17 @@ "iso8601": utils.isoformat, "rfc": utils.rfcformat, "rfc822": utils.rfcformat, - } # type: typing.Dict[str, typing.Callable[[typing.Any], str]] + "timestamp": utils.timestamp, + "timestamp_ms": utils.timestamp_ms, + } # type: typing.Dict[str, typing.Callable[[typing.Any], str | float]] DESERIALIZATION_FUNCS = { "iso": utils.from_iso_datetime, "iso8601": utils.from_iso_datetime, "rfc": utils.from_rfc, "rfc822": utils.from_rfc, + "timestamp": utils.from_timestamp, + "timestamp_ms": utils.from_timestamp_ms, } # type: typing.Dict[str, typing.Callable[[str], typing.Any]] DEFAULT_FORMAT = "iso" @@ -1252,7 +1259,7 @@ "format": '"{input}" cannot be formatted as a {obj_type}.', } - def __init__(self, format: str | None = None, **kwargs): + def __init__(self, format: str | None = None, **kwargs) -> None: super().__init__(**kwargs) # Allow this to be None. It may be set later in the ``_serialize`` # or ``_deserialize`` methods. This allows a Schema to dynamically set the @@ -1267,7 +1274,7 @@ or self.DEFAULT_FORMAT ) - def _serialize(self, value, attr, obj, **kwargs): + def _serialize(self, value, attr, obj, **kwargs) -> str | float | None: if value is None: return None data_format = self.format or self.DEFAULT_FORMAT @@ -1277,7 +1284,7 @@ else: return value.strftime(data_format) - def _deserialize(self, value, attr, data, **kwargs): + 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 @@ -1298,7 +1305,7 @@ ) from error @staticmethod - def _make_object_from_format(value, data_format): + def _make_object_from_format(value, data_format) -> dt.datetime: return dt.datetime.strptime(value, data_format) @@ -1323,11 +1330,11 @@ *, timezone: dt.timezone | None = None, **kwargs, - ): + ) -> None: super().__init__(format=format, **kwargs) self.timezone = timezone - def _deserialize(self, value, attr, data, **kwargs): + def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime: ret = super()._deserialize(value, attr, data, **kwargs) if is_aware(ret): if self.timezone is None: @@ -1360,11 +1367,11 @@ *, default_timezone: dt.tzinfo | None = None, **kwargs, - ): + ) -> None: super().__init__(format=format, **kwargs) self.default_timezone = default_timezone - def _deserialize(self, value, attr, data, **kwargs): + def _deserialize(self, value, attr, data, **kwargs) -> dt.datetime: ret = super()._deserialize(value, attr, data, **kwargs) if not is_aware(ret): if self.default_timezone is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/src/marshmallow/utils.py new/marshmallow-3.19.0/src/marshmallow/utils.py --- old/marshmallow-3.18.0/src/marshmallow/utils.py 2022-09-15 22:26:57.000000000 +0200 +++ new/marshmallow-3.19.0/src/marshmallow/utils.py 2022-11-11 17:10:31.000000000 +0100 @@ -190,6 +190,34 @@ return dt.date(**kw) +def from_timestamp(value: typing.Any) -> dt.datetime: + value = float(value) + if value < 0: + raise ValueError("Not a valid POSIX timestamp") + + # Load a timestamp with utc as timezone to prevent using system timezone. + # Then set timezone to None, to let the Field handle adding timezone info. + return dt.datetime.fromtimestamp(value, tz=dt.timezone.utc).replace(tzinfo=None) + + +def from_timestamp_ms(value: typing.Any) -> dt.datetime: + value = float(value) + return from_timestamp(value / 1000) + + +def timestamp( + value: dt.datetime, +) -> float: + if not is_aware(value): + # When a date is naive, use UTC as zone info to prevent using system timezone. + value = value.replace(tzinfo=dt.timezone.utc) + return value.timestamp() + + +def timestamp_ms(value: dt.datetime) -> float: + return timestamp(value) * 1000 + + def isoformat(datetime: dt.datetime) -> str: """Return the ISO8601-formatted representation of a datetime object. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/src/marshmallow.egg-info/PKG-INFO new/marshmallow-3.19.0/src/marshmallow.egg-info/PKG-INFO --- old/marshmallow-3.18.0/src/marshmallow.egg-info/PKG-INFO 2022-09-15 22:27:10.000000000 +0200 +++ new/marshmallow-3.19.0/src/marshmallow.egg-info/PKG-INFO 2022-11-11 17:10:43.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: marshmallow -Version: 3.18.0 +Version: 3.19.0 Summary: A lightweight library for converting complex datatypes to and from native Python datatypes. Home-page: https://github.com/marshmallow-code/marshmallow Author: Steven Loria diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/src/marshmallow.egg-info/requires.txt new/marshmallow-3.19.0/src/marshmallow.egg-info/requires.txt --- old/marshmallow-3.18.0/src/marshmallow.egg-info/requires.txt 2022-09-15 22:27:10.000000000 +0200 +++ new/marshmallow-3.19.0/src/marshmallow.egg-info/requires.txt 2022-11-11 17:10:43.000000000 +0100 @@ -4,23 +4,23 @@ pytest pytz simplejson -mypy==0.971 +mypy==0.990 flake8==5.0.4 -flake8-bugbear==22.9.11 +flake8-bugbear==22.10.25 pre-commit~=2.4 tox [docs] -sphinx==5.1.1 +sphinx==5.3.0 sphinx-issues==3.0.1 alabaster==0.7.12 sphinx-version-warning==1.1.2 autodocsumm==0.2.9 [lint] -mypy==0.971 +mypy==0.990 flake8==5.0.4 -flake8-bugbear==22.9.11 +flake8-bugbear==22.10.25 pre-commit~=2.4 [tests] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/tests/test_deserialization.py new/marshmallow-3.19.0/tests/test_deserialization.py --- old/marshmallow-3.18.0/tests/test_deserialization.py 2022-09-15 22:26:57.000000000 +0200 +++ new/marshmallow-3.19.0/tests/test_deserialization.py 2022-11-11 17:10:31.000000000 +0100 @@ -527,6 +527,50 @@ assert field.deserialize(value) == expected @pytest.mark.parametrize( + ("fmt", "value", "expected"), + [ + ("timestamp", 1384043025, dt.datetime(2013, 11, 10, 0, 23, 45)), + ("timestamp", "1384043025", dt.datetime(2013, 11, 10, 0, 23, 45)), + ("timestamp", 1384043025, dt.datetime(2013, 11, 10, 0, 23, 45)), + ("timestamp", 1384043025.12, dt.datetime(2013, 11, 10, 0, 23, 45, 120000)), + ( + "timestamp", + 1384043025.123456, + dt.datetime(2013, 11, 10, 0, 23, 45, 123456), + ), + ("timestamp", 1, dt.datetime(1970, 1, 1, 0, 0, 1)), + ("timestamp_ms", 1384043025000, dt.datetime(2013, 11, 10, 0, 23, 45)), + ("timestamp_ms", 1000, dt.datetime(1970, 1, 1, 0, 0, 1)), + ], + ) + def test_timestamp_field_deserialization(self, fmt, value, expected): + field = fields.DateTime(format=fmt) + assert field.deserialize(value) == expected + + # By default, a datetime from a timestamp is never aware. + field = fields.NaiveDateTime(format=fmt) + assert field.deserialize(value) == expected + + field = fields.AwareDateTime(format=fmt) + with pytest.raises(ValidationError, match="Not a valid aware datetime."): + field.deserialize(value) + + # But it can be added by providing a default. + field = fields.AwareDateTime(format=fmt, default_timezone=central) + expected_aware = expected.replace(tzinfo=central) + assert field.deserialize(value) == expected_aware + + @pytest.mark.parametrize("fmt", ["timestamp", "timestamp_ms"]) + @pytest.mark.parametrize( + "in_value", + ["", "!@#", 0, -1, dt.datetime(2013, 11, 10, 1, 23, 45)], + ) + def test_invalid_timestamp_field_deserialization(self, fmt, in_value): + field = fields.DateTime(format="timestamp") + with pytest.raises(ValidationError, match="Not a valid datetime."): + field.deserialize(in_value) + + @pytest.mark.parametrize( ("fmt", "timezone", "value", "expected"), [ ("iso", None, "2013-11-10T01:23:45", dt.datetime(2013, 11, 10, 1, 23, 45)), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.18.0/tests/test_serialization.py new/marshmallow-3.19.0/tests/test_serialization.py --- old/marshmallow-3.18.0/tests/test_serialization.py 2022-09-15 22:26:57.000000000 +0200 +++ new/marshmallow-3.19.0/tests/test_serialization.py 2022-11-11 17:10:31.000000000 +0100 @@ -579,6 +579,38 @@ field = fields.DateTime(format=fmt) assert field.serialize("d", {"d": value}) == expected + @pytest.mark.parametrize( + ("fmt", "value", "expected"), + [ + ("timestamp", dt.datetime(1970, 1, 1), 0), + ("timestamp", dt.datetime(2013, 11, 10, 0, 23, 45), 1384043025), + ( + "timestamp", + dt.datetime(2013, 11, 10, 0, 23, 45, tzinfo=dt.timezone.utc), + 1384043025, + ), + ( + "timestamp", + central.localize(dt.datetime(2013, 11, 10, 0, 23, 45), is_dst=False), + 1384064625, + ), + ("timestamp_ms", dt.datetime(2013, 11, 10, 0, 23, 45), 1384043025000), + ( + "timestamp_ms", + dt.datetime(2013, 11, 10, 0, 23, 45, tzinfo=dt.timezone.utc), + 1384043025000, + ), + ( + "timestamp_ms", + central.localize(dt.datetime(2013, 11, 10, 0, 23, 45), is_dst=False), + 1384064625000, + ), + ], + ) + def test_datetime_field_timestamp(self, fmt, value, expected): + field = fields.DateTime(format=fmt) + assert field.serialize("d", {"d": value}) == expected + @pytest.mark.parametrize("fmt", ["iso", "iso8601", None]) @pytest.mark.parametrize( ("value", "expected"),