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-11-01 13:42:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-marshmallow (Old)
and /work/SRC/openSUSE:Factory/.python-marshmallow.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-marshmallow"
Tue Nov 1 13:42:18 2022 rev:18 rq:1032503 version:3.18.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-marshmallow/python-marshmallow.changes 2022-09-30 17:58:05.401286521 +0200
+++ /work/SRC/openSUSE:Factory/.python-marshmallow.new.2275/python-marshmallow.changes 2022-11-01 13:42:29.399871111 +0100
@@ -2 +2 @@
-Thu Sep 29 15:53:34 UTC 2022 - Yogalakshmi Arunachalam
+Fri Oct 28 18:21:19 UTC 2022 - Yogalakshmi Arunachalam
@@ -8,0 +9,3 @@
+
+-------------------------------------------------------------------
+Thu Sep 29 15:53:34 UTC 2022 - Yogalakshmi Arunachalam
Old:
----
marshmallow-3.17.1.tar.gz
New:
----
marshmallow-3.18.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-marshmallow.spec ++++++
--- /var/tmp/diff_new_pack.GQCtsu/_old 2022-11-01 13:42:29.799873240 +0100
+++ /var/tmp/diff_new_pack.GQCtsu/_new 2022-11-01 13:42:29.807873282 +0100
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-marshmallow
-Version: 3.17.1
+Version: 3.18.0
Release: 0
Summary: ORM/ODM/framework-agnostic library to convert datatypes from/to Python types
License: BSD-3-Clause AND MIT
++++++ marshmallow-3.17.1.tar.gz -> marshmallow-3.18.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/CHANGELOG.rst new/marshmallow-3.18.0/CHANGELOG.rst
--- old/marshmallow-3.17.1/CHANGELOG.rst 2022-08-22 21:36:43.000000000 +0200
+++ new/marshmallow-3.18.0/CHANGELOG.rst 2022-09-15 22:26:57.000000000 +0200
@@ -1,12 +1,23 @@
Changelog
---------
+3.18.0 (2022-09-15)
+*******************
+
+Features:
+
+- Add ``Enum`` field (:pr:`2017`) and (:pr:`2044`).
+
+Bug fixes:
+
+- Fix typing in ``Field._serialize`` signature (:pr:`2046`).
+
3.17.1 (2022-08-22)
*******************
Bug fixes:
-- Add return type to `fields.Email.__init__` (:pr:`2018`).
+- Add return type to ``fields.Email.__init__`` (:pr:`2018`).
Thanks :user:`kkirsche` for the PR.
- Add missing type hint to IPInterface __init__ (:pr:`2036`).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/PKG-INFO new/marshmallow-3.18.0/PKG-INFO
--- old/marshmallow-3.17.1/PKG-INFO 2022-08-22 21:36:55.306264200 +0200
+++ new/marshmallow-3.18.0/PKG-INFO 2022-09-15 22:27:10.895295400 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: marshmallow
-Version: 3.17.1
+Version: 3.18.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
@@ -173,12 +173,6 @@
:target: https://tidelift.com/subscription/pkg/pypi-marshmallow?utm_source=pypi-marshmallow&utm_medium=readme
:alt: Get supported marshmallow with Tidelift
-Security Contact Information
-============================
-
-To report a security vulnerability, please use the
-`Tidelift security contact https://tidelift.com/security`_.
-Tidelift will coordinate the fix and disclosure.
Project Links
=============
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/README.rst new/marshmallow-3.18.0/README.rst
--- old/marshmallow-3.17.1/README.rst 2022-08-22 21:36:43.000000000 +0200
+++ new/marshmallow-3.18.0/README.rst 2022-09-15 22:26:57.000000000 +0200
@@ -145,12 +145,6 @@
:target: https://tidelift.com/subscription/pkg/pypi-marshmallow?utm_source=pypi-marshmallow&utm_medium=readme
:alt: Get supported marshmallow with Tidelift
-Security Contact Information
-============================
-
-To report a security vulnerability, please use the
-`Tidelift security contact https://tidelift.com/security`_.
-Tidelift will coordinate the fix and disclosure.
Project Links
=============
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/setup.py new/marshmallow-3.18.0/setup.py
--- old/marshmallow-3.17.1/setup.py 2022-08-22 21:36:43.000000000 +0200
+++ new/marshmallow-3.18.0/setup.py 2022-09-15 22:26:57.000000000 +0200
@@ -6,7 +6,7 @@
"lint": [
"mypy==0.971",
"flake8==5.0.4",
- "flake8-bugbear==22.8.22",
+ "flake8-bugbear==22.9.11",
"pre-commit~=2.4",
],
"docs": [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/src/marshmallow/__init__.py new/marshmallow-3.18.0/src/marshmallow/__init__.py
--- old/marshmallow-3.17.1/src/marshmallow/__init__.py 2022-08-22 21:36:43.000000000 +0200
+++ new/marshmallow-3.18.0/src/marshmallow/__init__.py 2022-09-15 22:26:57.000000000 +0200
@@ -16,7 +16,7 @@
from . import fields
-__version__ = "3.17.1"
+__version__ = "3.18.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.17.1/src/marshmallow/fields.py new/marshmallow-3.18.0/src/marshmallow/fields.py
--- old/marshmallow-3.17.1/src/marshmallow/fields.py 2022-08-22 21:36:43.000000000 +0200
+++ new/marshmallow-3.18.0/src/marshmallow/fields.py 2022-09-15 22:26:57.000000000 +0200
@@ -11,6 +11,7 @@
import math
import typing
import warnings
+from enum import Enum as EnumType
from collections.abc import Mapping as _Mapping
from marshmallow import validate, utils, class_registry, types
@@ -59,6 +60,7 @@
"IPInterface",
"IPv4Interface",
"IPv6Interface",
+ "Enum",
"Method",
"Function",
"Str",
@@ -384,7 +386,9 @@
self.parent.root if isinstance(self.parent, FieldABC) else self.parent
)
- def _serialize(self, value: typing.Any, attr: str, obj: typing.Any, **kwargs):
+ def _serialize(
+ self, value: typing.Any, attr: str | None, obj: typing.Any, **kwargs
+ ):
"""Serializes ``value`` to a basic Python datatype. Noop by default.
Concrete :class:`Field` classes should implement this method.
@@ -995,11 +999,7 @@
# override Number
def _validated(self, value):
- if self.strict:
- if isinstance(value, numbers.Number) and isinstance(
- value, numbers.Integral
- ):
- return super()._validated(value)
+ if self.strict and not isinstance(value, numbers.Integral):
raise self.make_error("invalid", input=value)
return super()._validated(value)
@@ -1855,6 +1855,79 @@
DESERIALIZATION_CLASS = ipaddress.IPv6Interface
+class Enum(Field):
+ """An Enum field (de)serializing enum members by symbol (name) or by value.
+
+ :param enum Enum: Enum class
+ :param boolean|Schema|Field by_value: Whether to (de)serialize by value or by name,
+ or Field class or instance to use to (de)serialize by value. Defaults to False.
+
+ If `by_value` is `False` (default), enum members are (de)serialized by symbol (name).
+ If it is `True`, they are (de)serialized by value using :class:`Field`.
+ If it is a field instance or class, they are (de)serialized by value using this field.
+
+ .. versionadded:: 3.18.0
+ """
+
+ default_error_messages = {
+ "unknown": "Must be one of: {choices}.",
+ }
+
+ def __init__(
+ self,
+ enum: type[EnumType],
+ *,
+ by_value: bool | Field | type = False,
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+ self.enum = enum
+ self.by_value = by_value
+
+ # Serialization by name
+ if by_value is False:
+ self.field: Field = String()
+ self.choices_text = ", ".join(
+ str(self.field._serialize(m, None, None)) for m in enum.__members__
+ )
+ # Serialization by value
+ else:
+ if by_value is True:
+ self.field = Field()
+ else:
+ try:
+ self.field = resolve_field_instance(by_value)
+ except FieldInstanceResolutionError as error:
+ raise ValueError(
+ '"by_value" must be either a bool or a subclass or instance of '
+ "marshmallow.base.FieldABC."
+ ) from error
+ self.choices_text = ", ".join(
+ str(self.field._serialize(m.value, None, None)) for m in enum
+ )
+
+ def _serialize(self, value, attr, obj, **kwargs):
+ if value is None:
+ return None
+ if self.by_value:
+ val = value.value
+ else:
+ val = value.name
+ return self.field._serialize(val, attr, obj, **kwargs)
+
+ def _deserialize(self, value, attr, data, **kwargs):
+ val = self.field._deserialize(value, attr, data, **kwargs)
+ if self.by_value:
+ try:
+ return self.enum(val)
+ except ValueError as error:
+ raise self.make_error("unknown", choices=self.choices_text) from error
+ try:
+ return getattr(self.enum, val)
+ except AttributeError as error:
+ raise self.make_error("unknown", choices=self.choices_text) from error
+
+
class Method(Field):
"""A field that takes the value returned by a `Schema` method.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/src/marshmallow.egg-info/PKG-INFO new/marshmallow-3.18.0/src/marshmallow.egg-info/PKG-INFO
--- old/marshmallow-3.17.1/src/marshmallow.egg-info/PKG-INFO 2022-08-22 21:36:55.000000000 +0200
+++ new/marshmallow-3.18.0/src/marshmallow.egg-info/PKG-INFO 2022-09-15 22:27:10.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: marshmallow
-Version: 3.17.1
+Version: 3.18.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
@@ -173,12 +173,6 @@
:target: https://tidelift.com/subscription/pkg/pypi-marshmallow?utm_source=pypi-marshmallow&utm_medium=readme
:alt: Get supported marshmallow with Tidelift
-Security Contact Information
-============================
-
-To report a security vulnerability, please use the
-`Tidelift security contact https://tidelift.com/security`_.
-Tidelift will coordinate the fix and disclosure.
Project Links
=============
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/src/marshmallow.egg-info/requires.txt new/marshmallow-3.18.0/src/marshmallow.egg-info/requires.txt
--- old/marshmallow-3.17.1/src/marshmallow.egg-info/requires.txt 2022-08-22 21:36:55.000000000 +0200
+++ new/marshmallow-3.18.0/src/marshmallow.egg-info/requires.txt 2022-09-15 22:27:10.000000000 +0200
@@ -6,7 +6,7 @@
simplejson
mypy==0.971
flake8==5.0.4
-flake8-bugbear==22.8.22
+flake8-bugbear==22.9.11
pre-commit~=2.4
tox
@@ -20,7 +20,7 @@
[lint]
mypy==0.971
flake8==5.0.4
-flake8-bugbear==22.8.22
+flake8-bugbear==22.9.11
pre-commit~=2.4
[tests]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/tests/base.py new/marshmallow-3.18.0/tests/base.py
--- old/marshmallow-3.17.1/tests/base.py 2022-08-22 21:36:43.000000000 +0200
+++ new/marshmallow-3.18.0/tests/base.py 2022-09-15 22:26:57.000000000 +0200
@@ -1,6 +1,8 @@
"""Test utilities and fixtures."""
+import functools
import datetime as dt
import uuid
+from enum import Enum, IntEnum
import simplejson
@@ -12,6 +14,25 @@
central = pytz.timezone("US/Central")
+class GenderEnum(IntEnum):
+ male = 1
+ female = 2
+ non_binary = 3
+
+
+class HairColorEnum(Enum):
+ black = "black hair"
+ brown = "brown hair"
+ blond = "blond hair"
+ red = "red hair"
+
+
+class DateEnum(Enum):
+ date_1 = dt.date(2004, 2, 29)
+ date_2 = dt.date(2008, 2, 29)
+ date_3 = dt.date(2012, 2, 29)
+
+
ALL_FIELDS = [
fields.String,
fields.Integer,
@@ -33,8 +54,12 @@
fields.IPInterface,
fields.IPv4Interface,
fields.IPv6Interface,
+ functools.partial(fields.Enum, GenderEnum),
+ functools.partial(fields.Enum, HairColorEnum, by_value=fields.String),
+ functools.partial(fields.Enum, GenderEnum, by_value=fields.Integer),
]
+
##### Custom asserts #####
@@ -69,7 +94,8 @@
birthdate=None,
birthtime=None,
balance=100,
- sex="male",
+ sex=GenderEnum.male,
+ hair_color=HairColorEnum.black,
employer=None,
various_data=None,
):
@@ -86,8 +112,8 @@
self.email = email
self.balance = balance
self.registered = registered
- self.hair_colors = ["black", "brown", "blond", "redhead"]
- self.sex_choices = ("male", "female")
+ self.hair_colors = list(HairColorEnum.__members__)
+ self.sex_choices = list(GenderEnum.__members__)
self.finger_count = 10
self.uid = uuid.uuid1()
self.time_registered = time_registered or dt.time(1, 23, 45, 6789)
@@ -95,6 +121,7 @@
self.birthtime = birthtime or dt.time(0, 1, 2, 3333)
self.activation_date = dt.date(2013, 12, 11)
self.sex = sex
+ self.hair_color = hair_color
self.employer = employer
self.relatives = []
self.various_data = various_data or {
@@ -180,7 +207,7 @@
birthtime = fields.Time()
activation_date = fields.Date()
since_created = fields.TimeDelta()
- sex = fields.Str(validate=validate.OneOf(["male", "female"]))
+ sex = fields.Str(validate=validate.OneOf(list(GenderEnum.__members__)))
various_data = fields.Dict()
class Meta:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/tests/test_deserialization.py new/marshmallow-3.18.0/tests/test_deserialization.py
--- old/marshmallow-3.17.1/tests/test_deserialization.py 2022-08-22 21:36:43.000000000 +0200
+++ new/marshmallow-3.18.0/tests/test_deserialization.py 2022-09-15 22:26:57.000000000 +0200
@@ -10,7 +10,15 @@
from marshmallow.exceptions import ValidationError
from marshmallow.validate import Equal
-from tests.base import assert_date_equal, assert_time_equal, central, ALL_FIELDS
+from tests.base import (
+ assert_date_equal,
+ assert_time_equal,
+ central,
+ ALL_FIELDS,
+ GenderEnum,
+ HairColorEnum,
+ DateEnum,
+)
class TestDeserializingNone:
@@ -1089,6 +1097,85 @@
assert excinfo.value.args[0] == "Not a valid IPv6 interface."
+ def test_enum_field_by_symbol_deserialization(self):
+ field = fields.Enum(GenderEnum)
+ assert field.deserialize("male") == GenderEnum.male
+
+ def test_enum_field_by_symbol_invalid_value(self):
+ field = fields.Enum(GenderEnum)
+ with pytest.raises(
+ ValidationError, match="Must be one of: male, female, non_binary."
+ ):
+ field.deserialize("dummy")
+
+ def test_enum_field_by_symbol_not_string(self):
+ field = fields.Enum(GenderEnum)
+ with pytest.raises(ValidationError, match="Not a valid string."):
+ field.deserialize(12)
+
+ def test_enum_field_by_value_true_deserialization(self):
+ field = fields.Enum(HairColorEnum, by_value=True)
+ assert field.deserialize("black hair") == HairColorEnum.black
+ field = fields.Enum(GenderEnum, by_value=True)
+ assert field.deserialize(1) == GenderEnum.male
+
+ def test_enum_field_by_value_field_deserialization(self):
+ field = fields.Enum(HairColorEnum, by_value=fields.String)
+ assert field.deserialize("black hair") == HairColorEnum.black
+ field = fields.Enum(GenderEnum, by_value=fields.Integer)
+ assert field.deserialize(1) == GenderEnum.male
+ field = fields.Enum(DateEnum, by_value=fields.Date(format="%d/%m/%Y"))
+ assert field.deserialize("29/02/2004") == DateEnum.date_1
+
+ def test_enum_field_by_value_true_invalid_value(self):
+ field = fields.Enum(HairColorEnum, by_value=True)
+ with pytest.raises(
+ ValidationError,
+ match="Must be one of: black hair, brown hair, blond hair, red hair.",
+ ):
+ field.deserialize("dummy")
+ field = fields.Enum(GenderEnum, by_value=True)
+ with pytest.raises(ValidationError, match="Must be one of: 1, 2, 3."):
+ field.deserialize(12)
+
+ def test_enum_field_by_value_field_invalid_value(self):
+ field = fields.Enum(HairColorEnum, by_value=fields.String)
+ with pytest.raises(
+ ValidationError,
+ match="Must be one of: black hair, brown hair, blond hair, red hair.",
+ ):
+ field.deserialize("dummy")
+ field = fields.Enum(GenderEnum, by_value=fields.Integer)
+ with pytest.raises(ValidationError, match="Must be one of: 1, 2, 3."):
+ field.deserialize(12)
+ field = fields.Enum(DateEnum, by_value=fields.Date(format="%d/%m/%Y"))
+ with pytest.raises(
+ ValidationError, match="Must be one of: 29/02/2004, 29/02/2008, 29/02/2012."
+ ):
+ field.deserialize("28/02/2004")
+
+ def test_enum_field_by_value_true_wrong_type(self):
+ field = fields.Enum(HairColorEnum, by_value=True)
+ with pytest.raises(
+ ValidationError,
+ match="Must be one of: black hair, brown hair, blond hair, red hair.",
+ ):
+ field.deserialize("dummy")
+ field = fields.Enum(GenderEnum, by_value=True)
+ with pytest.raises(ValidationError, match="Must be one of: 1, 2, 3."):
+ field.deserialize(12)
+
+ def test_enum_field_by_value_field_wrong_type(self):
+ field = fields.Enum(HairColorEnum, by_value=fields.String)
+ with pytest.raises(ValidationError, match="Not a valid string."):
+ field.deserialize(12)
+ field = fields.Enum(GenderEnum, by_value=fields.Integer)
+ with pytest.raises(ValidationError, match="Not a valid integer."):
+ field.deserialize("dummy")
+ field = fields.Enum(DateEnum, by_value=fields.Date(format="%d/%m/%Y"))
+ with pytest.raises(ValidationError, match="Not a valid date."):
+ field.deserialize("30/02/2004")
+
def test_deserialization_function_must_be_callable(self):
with pytest.raises(TypeError):
fields.Function(lambda x: None, deserialize="notvalid")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/marshmallow-3.17.1/tests/test_serialization.py new/marshmallow-3.18.0/tests/test_serialization.py
--- old/marshmallow-3.17.1/tests/test_serialization.py 2022-08-22 21:36:43.000000000 +0200
+++ new/marshmallow-3.18.0/tests/test_serialization.py 2022-09-15 22:26:57.000000000 +0200
@@ -11,7 +11,7 @@
from marshmallow import Schema, fields, missing as missing_
-from tests.base import User, ALL_FIELDS, central
+from tests.base import User, ALL_FIELDS, central, GenderEnum, HairColorEnum, DateEnum
class DateTimeList:
@@ -255,6 +255,31 @@
== ipv6interface_exploded_string
)
+ def test_enum_field_by_symbol_serialization(self, user):
+ user.sex = GenderEnum.male
+ field = fields.Enum(GenderEnum)
+ assert field.serialize("sex", user) == "male"
+
+ def test_enum_field_by_value_true_serialization(self, user):
+ user.hair_color = HairColorEnum.black
+ field = fields.Enum(HairColorEnum, by_value=True)
+ assert field.serialize("hair_color", user) == "black hair"
+ user.sex = GenderEnum.male
+ field = fields.Enum(GenderEnum, by_value=True)
+ assert field.serialize("sex", user) == 1
+ user.some_date = DateEnum.date_1
+
+ def test_enum_field_by_value_field_serialization(self, user):
+ user.hair_color = HairColorEnum.black
+ field = fields.Enum(HairColorEnum, by_value=fields.String)
+ assert field.serialize("hair_color", user) == "black hair"
+ user.sex = GenderEnum.male
+ field = fields.Enum(GenderEnum, by_value=fields.Integer)
+ assert field.serialize("sex", user) == 1
+ user.some_date = DateEnum.date_1
+ field = fields.Enum(DateEnum, by_value=fields.Date(format="%d/%m/%Y"))
+ assert field.serialize("some_date", user) == "29/02/2004"
+
def test_decimal_field(self, user):
user.m1 = 12
user.m2 = "12.355"