Accepting request 726193 from home:mcalabkova:branches:devel:languages:python

- Update to 3.0.1
  * Many changes, some of them breaking. For example:
  * Remove support for Python 2 (#1120). Only Python>=3.5 is supported.
  * Allow input value to be included in error messages for a number of fields.
  * Change ordering of keys and values arguments to fields.Dict.
  * Please read upstream changelog.
- Drop upstreamed patches reproducible.patch and pytest5.patch

OBS-URL: https://build.opensuse.org/request/show/726193
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-marshmallow?expand=0&rev=17
This commit is contained in:
Tomáš Chvátal 2019-08-27 00:54:41 +00:00 committed by Git OBS Bridge
parent 5cb2311ec5
commit 2a3053079b
7 changed files with 25 additions and 469 deletions

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9cedfc5b6f568d57e8a2cf3d293fbd81b05e5ef557854008d03e25660a39ccfd
size 155874

3
marshmallow-3.0.1.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:23f684b54b1955ebd5bdfbdda4062e438ef86218f14f1a356f570cdf0c016ab3
size 168186

View File

@ -1,425 +0,0 @@
From a7014176a7f211aaaa06b516eceb5468402fd9fc Mon Sep 17 00:00:00 2001
From: Steven Loria <sloria1@gmail.com>
Date: Sun, 30 Jun 2019 12:47:01 -0400
Subject: [PATCH] Fix tests (#1271)
Fix compatibility with pytest 5.0
---
tests/test_decorators.py | 3 +-
tests/test_deserialization.py | 30 ++++++-------------
tests/test_marshalling.py | 9 ------
tests/test_registry.py | 9 +++---
tests/test_schema.py | 14 ++++-----
tests/test_serialization.py | 5 ++--
tests/test_validate.py | 54 ++++++++++++-----------------------
7 files changed, 39 insertions(+), 85 deletions(-)
diff --git a/tests/test_decorators.py b/tests/test_decorators.py
index fa95405f..b8fecb9e 100644
--- a/tests/test_decorators.py
+++ b/tests/test_decorators.py
@@ -305,9 +305,8 @@ def validate_bar(self, value):
schema = BadSchema()
- with pytest.raises(ValueError) as excinfo:
+ with pytest.raises(ValueError, match='"bar" field does not exist.'):
schema.validate({'foo': 42})
- assert '"bar" field does not exist.' in str(excinfo)
def test_precedence(self):
class Schema2(ValidatesSchema):
diff --git a/tests/test_deserialization.py b/tests/test_deserialization.py
index 01d5a637..bd7afc27 100644
--- a/tests/test_deserialization.py
+++ b/tests/test_deserialization.py
@@ -38,9 +38,8 @@ def test_fields_dont_allow_none_by_default(self, FieldClass):
field = FieldClass(src_str='foo')
else:
field = FieldClass()
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Field may not be null.'):
field.deserialize(None)
- assert 'Field may not be null.' in str(excinfo)
def test_allow_none_is_true_if_missing_is_true(self):
field = fields.Field(missing=None)
@@ -311,10 +310,9 @@ class MyBoolean(fields.Boolean):
])
def test_invalid_datetime_deserialization(self, in_value):
field = fields.DateTime()
- with pytest.raises(ValidationError) as excinfo:
- field.deserialize(in_value)
msg = 'Not a valid datetime.'.format(in_value)
- assert msg in str(excinfo)
+ with pytest.raises(ValidationError, match=msg):
+ field.deserialize(in_value)
def test_datetime_passed_year_is_invalid(self):
field = fields.DateTime()
@@ -328,16 +326,11 @@ def test_custom_date_format_datetime_field_deserialization(self):
field = fields.DateTime(format='%d-%m-%Y %H:%M:%S')
#deserialization should fail when datestring is not of same format
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Not a valid datetime.'):
field.deserialize(datestring)
- msg = 'Not a valid datetime.'
- assert msg in str(excinfo)
field = fields.DateTime(format='%H:%M:%S.%f %Y-%m-%d')
assert_datetime_equal(field.deserialize(datestring), dtime)
- field = fields.DateTime()
- assert msg in str(excinfo)
-
@pytest.mark.parametrize('fmt', ['rfc', 'rfc822'])
def test_rfc_datetime_field_deserialization(self, fmt):
dtime = dt.datetime.now().replace(microsecond=0)
@@ -667,9 +660,8 @@ def __call__(self, val):
field = fields.Field(validate=MyValidator())
assert field.deserialize('valid') == 'valid'
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Invalid value.'):
field.deserialize('invalid')
- assert 'Invalid value.' in str(excinfo)
def test_field_deserialization_with_user_validator_that_raises_error_with_list(self):
def validator(val):
@@ -710,16 +702,14 @@ def test_field_deserialization_with_user_validators(self):
for field in m_colletion_type:
assert field.deserialize('Valid') == 'Valid'
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Invalid value.'):
field.deserialize('invalid')
- assert 'Invalid value.' in str(excinfo)
def test_field_deserialization_with_custom_error_message(self):
field = fields.String(validate=lambda s: s.lower() == 'valid',
error_messages={'validator_failed': 'Bad value.'})
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Bad value.'):
field.deserialize('invalid')
- assert 'Bad value.' in str(excinfo)
def test_field_deserialization_with_non_utf8_value(self):
non_utf8_char = '\xc8'
@@ -1235,10 +1225,9 @@ class MethodSerializer(Schema):
def get_name(self, val):
return val.upper()
assert MethodSerializer(strict=True).load({'name': 'joe'})
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Invalid value.'):
MethodSerializer(strict=True).load({'name': 'joseph'})
- assert 'Invalid value.' in str(excinfo)
# Regression test for https://github.com/marshmallow-code/marshmallow/issues/269
def test_nested_data_is_stored_when_validation_fails(self):
@@ -1312,9 +1301,8 @@ def test_deserialize_raises_exception_if_strict_is_true_and_input_type_is_incorr
class MySchema(Schema):
foo = fields.Field()
bar = fields.Field()
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Invalid input type.') as excinfo:
MySchema(strict=True).load([])
- assert 'Invalid input type.' in str(excinfo)
exc = excinfo.value
assert exc.field_names == ['_schema']
assert exc.fields == []
diff --git a/tests/test_marshalling.py b/tests/test_marshalling.py
index 252b1f09..213ac7d0 100644
--- a/tests/test_marshalling.py
+++ b/tests/test_marshalling.py
@@ -122,15 +122,6 @@ def test_extra_data_is_ignored(self, unmarshal):
ret = unmarshal({'extra': 42, 'name': 'Steve'}, fields_)
assert 'extra' not in ret
- # def test_strict_mode_many(self, unmarshal):
- # users = [
- # {'email': 'foobar'},
- # {'email': 'bar@example.com'}
- # ]
- # with pytest.raises(ValidationError) as excinfo:
- # unmarshal(users, {'email': fields.Email()}, strict=True, many=True)
- # assert 'Not a valid email address.' in str(excinfo)
-
def test_stores_errors(self, unmarshal):
data = {'email': 'invalid-email'}
try:
diff --git a/tests/test_registry.py b/tests/test_registry.py
index 1f3c0be9..ae877a32 100644
--- a/tests/test_registry.py
+++ b/tests/test_registry.py
@@ -131,9 +131,9 @@ def test_invalid_class_name_in_nested_field_raises_error(user):
class MySchema(Schema):
nf = fields.Nested('notfound')
sch = MySchema()
- with pytest.raises(RegistryError) as excinfo:
+ msg = 'Class with name {0!r} was not found'.format('notfound')
+ with pytest.raises(RegistryError, match=msg):
sch.dump({'nf': None})
- assert 'Class with name {0!r} was not found'.format('notfound') in str(excinfo)
class FooSerializer(Schema):
_id = fields.Integer()
@@ -149,11 +149,10 @@ class MySchema(Schema):
# Using a nested field with the class name fails because there are
# two defined classes with the same name
sch = MySchema()
- with pytest.raises(RegistryError) as excinfo:
- sch.dump({'foo': {'_id': 1}})
msg = 'Multiple classes with name {0!r} were found.'\
.format('FooSerializer')
- assert msg in str(excinfo)
+ with pytest.raises(RegistryError, match=msg) as excinfo:
+ sch.dump({'foo': {'_id': 1}})
def test_multiple_classes_with_all():
# Import a class with the same name
diff --git a/tests/test_schema.py b/tests/test_schema.py
index b9f7534b..a4b46342 100755
--- a/tests/test_schema.py
+++ b/tests/test_schema.py
@@ -549,9 +549,8 @@ def test_prefix(SchemaClass, user):
def test_fields_must_be_declared_as_instances(user):
class BadUserSchema(Schema):
name = fields.String
- with pytest.raises(TypeError) as excinfo:
+ with pytest.raises(TypeError, match='must be declared as a Field instance'):
BadUserSchema().dump(user)
- assert 'must be declared as a Field instance' in str(excinfo)
@pytest.mark.parametrize('SchemaClass',
[UserSchema, UserMetaSchema])
@@ -1768,11 +1767,10 @@ def test_nested_errors(self):
assert "collaborators" not in errors
def test_nested_strict(self):
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='email'):
_, errors = BlogSchema(strict=True).load(
{'title': "Monty's blog", 'user': {'name': 'Monty', 'email': 'foo'}}
)
- assert 'email' in str(excinfo)
def test_nested_dump_errors(self, blog):
blog.user.email = "foo"
@@ -1785,9 +1783,8 @@ def test_nested_dump_errors(self, blog):
def test_nested_dump_strict(self, blog):
blog.user.email = "foo"
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='email'):
_, errors = BlogSchema(strict=True).dump(blog)
- assert 'email' in str(excinfo)
def test_nested_method_field(self, blog):
data = BlogSchema().dump(blog)[0]
@@ -2127,10 +2124,9 @@ class UserFunctionContextSchema(Schema):
serializer = UserFunctionContextSchema(strict=True)
# no context
serializer.context = None
- with pytest.raises(ValidationError) as excinfo:
- serializer.dump(owner)
msg = 'No context available for Function field {0!r}'.format('is_collab')
- assert msg in str(excinfo)
+ with pytest.raises(ValidationError, match=msg) as excinfo:
+ serializer.dump(owner)
def test_fields_context(self):
class CSchema(Schema):
diff --git a/tests/test_serialization.py b/tests/test_serialization.py
index f188386a..1c0c1c19 100644
--- a/tests/test_serialization.py
+++ b/tests/test_serialization.py
@@ -705,11 +705,10 @@ class ASchema(Schema):
id = fields.Int()
with pytest.raises(ValueError):
fields.List("string")
- with pytest.raises(ValueError) as excinfo:
- fields.List(ASchema)
expected_msg = ('The type of the list elements must be a subclass '
'of marshmallow.base.FieldABC')
- assert expected_msg in str(excinfo)
+ with pytest.raises(ValueError, match=expected_msg):
+ fields.List(ASchema)
def test_serialize_does_not_apply_validators(self, user):
field = fields.Field(validate=lambda x: False)
diff --git a/tests/test_validate.py b/tests/test_validate.py
index 288881af..cafd1e98 100644
--- a/tests/test_validate.py
+++ b/tests/test_validate.py
@@ -131,9 +131,8 @@ def test_url_relative_and_custom_schemes():
def test_url_custom_message():
validator = validate.URL(error="{input} ain't an URL")
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match="invalid ain't an URL"):
validator('invalid')
- assert "invalid ain't an URL" in str(excinfo)
def test_url_repr():
assert (
@@ -187,9 +186,8 @@ def test_email_invalid(invalid_email):
def test_email_custom_message():
validator = validate.Email(error='{input} is not an email addy.')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='invalid is not an email addy.'):
validator('invalid')
- assert 'invalid is not an email addy.' in str(excinfo)
def test_email_repr():
assert (
@@ -228,19 +226,16 @@ def test_range_max():
def test_range_custom_message():
v = validate.Range(2, 3, error='{input} is not between {min} and {max}')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='1 is not between 2 and 3'):
v(1)
- assert '1 is not between 2 and 3' in str(excinfo)
v = validate.Range(2, None, error='{input} is less than {min}')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='1 is less than 2'):
v(1)
- assert '1 is less than 2' in str(excinfo)
v = validate.Range(None, 3, error='{input} is greater than {max}')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='4 is greater than 3'):
v(4)
- assert '4 is greater than 3' in str(excinfo)
def test_range_repr():
assert (
@@ -312,24 +307,20 @@ def test_length_equal():
def test_length_custom_message():
v = validate.Length(5, 6, error='{input} is not between {min} and {max}')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='foo is not between 5 and 6'):
v('foo')
- assert 'foo is not between 5 and 6' in str(excinfo)
v = validate.Length(5, None, error='{input} is shorter than {min}')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='foo is shorter than 5'):
v('foo')
- assert 'foo is shorter than 5' in str(excinfo)
v = validate.Length(None, 2, error='{input} is longer than {max}')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='foo is longer than 2'):
v('foo')
- assert 'foo is longer than 2' in str(excinfo)
v = validate.Length(None, None, equal=4, error='{input} does not have {equal}')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='foo does not have 4'):
v('foo')
- assert 'foo does not have 4' in str(excinfo)
def test_length_repr():
assert (
@@ -362,9 +353,8 @@ def test_equal():
def test_equal_custom_message():
v = validate.Equal('a', error='{input} is not equal to {other}.')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='b is not equal to a.'):
v('b')
- assert 'b is not equal to a.' in str(excinfo)
def test_equal_repr():
assert (
@@ -415,9 +405,8 @@ def test_regexp_compile():
def test_regexp_custom_message():
rex = r'[0-9]+'
v = validate.Regexp(rex, error='{input} does not match {regex}')
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='a does not match'):
v('a')
- assert 'a does not match [0-9]+' in str(excinfo)
def test_regexp_repr():
assert (
@@ -457,9 +446,8 @@ def _identity(self, arg):
assert validate.Predicate('_identity', arg=1)(d) == d
assert validate.Predicate('_identity', arg='abc')(d) == d
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Invalid input.'):
validate.Predicate('_false')(d)
- assert 'Invalid input.' in str(excinfo)
with pytest.raises(ValidationError):
validate.Predicate('_empty')(d)
with pytest.raises(ValidationError):
@@ -477,9 +465,8 @@ def _false(self):
def __str__(self):
return 'Dummy'
d = Dummy()
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Dummy._false is invalid!'):
validate.Predicate('_false', error='{input}.{method} is invalid!')(d)
- assert 'Dummy._false is invalid!' in str(excinfo)
def test_predicate_repr():
assert (
@@ -502,9 +489,8 @@ def test_noneof():
assert validate.NoneOf([])([]) == []
assert validate.NoneOf([1, 2, 3])(None) is None
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Invalid input.'):
validate.NoneOf([1, 2, 3])(3)
- assert 'Invalid input.' in str(excinfo)
with pytest.raises(ValidationError):
validate.NoneOf('abc')('c')
with pytest.raises(ValidationError):
@@ -513,17 +499,15 @@ def test_noneof():
validate.NoneOf('')('')
def test_noneof_custom_message():
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='<not valid>'):
validate.NoneOf([1, 2], error='<not valid>')(1)
- assert '<not valid>' in str(excinfo)
none_of = validate.NoneOf(
[1, 2],
error='{input} cannot be one of {values}'
)
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='1 cannot be one of 1, 2'):
none_of(1)
- assert '1 cannot be one of 1, 2' in str(excinfo)
def test_noneof_repr():
assert (
@@ -545,9 +529,8 @@ def test_oneof():
assert validate.OneOf(dict(a=0, b=1))('a') == 'a'
assert validate.OneOf((1, 2, None))(None) is None
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='Not a valid choice.'):
validate.OneOf([1, 2, 3])(4)
- assert 'Not a valid choice.' in str(excinfo)
with pytest.raises(ValidationError):
validate.OneOf('abc')('d')
with pytest.raises(ValidationError):
@@ -689,9 +672,8 @@ def test_contains_only_in_string():
validate.ContainsOnly('')('a')
def test_contains_only_invalid():
- with pytest.raises(ValidationError) as excinfo:
+ with pytest.raises(ValidationError, match='One or more of the choices you made was not acceptable.'):
validate.ContainsOnly([1, 2, 3])([1, 1])
- assert 'One or more of the choices you made was not acceptable.' in str(excinfo)
with pytest.raises(ValidationError):
validate.ContainsOnly([1, 1, 2])([2, 2])
with pytest.raises(ValidationError):

View File

@ -36,15 +36,15 @@
#> I am perhaps hitting
#>
# https://github.com/humitos/sphinx-version-warning/issues/22
Index: marshmallow-2.19.1/docs/conf.py
Index: marshmallow-3.0.1/docs/conf.py
===================================================================
--- marshmallow-2.19.1.orig/docs/conf.py 2019-03-16 21:09:37.000000000 +0100
+++ marshmallow-2.19.1/docs/conf.py 2019-04-01 10:00:19.833567622 +0200
--- marshmallow-3.0.1.orig/docs/conf.py
+++ marshmallow-3.0.1/docs/conf.py
@@ -35,7 +35,6 @@ extensions = [
'sphinx.ext.viewcode',
'alabaster',
'sphinx_issues',
- 'versionwarning.extension',
"sphinx.ext.viewcode",
"alabaster",
"sphinx_issues",
- "versionwarning.extension",
]
primary_domain = 'py'
primary_domain = "py"

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Mon Aug 26 14:10:28 UTC 2019 - Marketa Calabkova <mcalabkova@suse.com>
- Update to 3.0.1
* Many changes, some of them breaking. For example:
* Remove support for Python 2 (#1120). Only Python>=3.5 is supported.
* Allow input value to be included in error messages for a number of fields.
* Change ordering of keys and values arguments to fields.Dict.
* Please read upstream changelog.
- Drop upstreamed patches reproducible.patch and pytest5.patch
-------------------------------------------------------------------
Wed Jul 31 09:13:51 UTC 2019 - Tomáš Chvátal <tchvatal@suse.com>

View File

@ -17,8 +17,9 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-marshmallow
Version: 2.19.5
Version: 3.0.1
Release: 0
Summary: ORM/ODM/framework-agnostic library to convert datatypes from/to Python types
License: MIT AND BSD-3-Clause
@ -27,8 +28,6 @@ URL: https://marshmallow.readthedocs.io/
Source: https://files.pythonhosted.org/packages/source/m/marshmallow/marshmallow-%{version}.tar.gz
# https://github.com/humitos/sphinx-version-warning/issues/22
Patch0: python-marshmallow-no-version-warning.patch
Patch1: reproducible.patch
Patch2: pytest5.patch
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
@ -38,12 +37,12 @@ Suggests: python-simplejson
BuildArch: noarch
# SECTION doc build requirements
BuildRequires: python3-Sphinx
BuildRequires: python3-alabaster
BuildRequires: python3-sphinx-issues
BuildRequires: python3-sphinx-version-warning
# /SECTION
# SECTION test requirements
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module python-dateutil}
BuildRequires: %{python_module pytz}
BuildRequires: %{python_module simplejson}
# /SECTION
@ -64,9 +63,6 @@ HTML Documentation and examples for %{name}.
%setup -q -n marshmallow-%{version}
%autopatch -p1
# remove py3 only tests
rm -r tests/test_py3
%build
%python_build
pushd docs

View File

@ -1,26 +0,0 @@
https://github.com/marshmallow-code/marshmallow/pull/679.patch
From 8064d7e155a78cde6e7a2387ec365dcf0798641d Mon Sep 17 00:00:00 2001
From: "Bernhard M. Wiedemann" <bwiedemann@suse.de>
Date: Sun, 24 Sep 2017 21:54:43 +0200
Subject: [PATCH] Use Changelog date instead of build date
in order to make builds reproducible.
See https://reproducible-builds.org/ for why this is good.
---
docs/conf.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: marshmallow-2.19.2/docs/conf.py
===================================================================
--- marshmallow-2.19.2.orig/docs/conf.py
+++ marshmallow-2.19.2/docs/conf.py
@@ -57,7 +57,7 @@ master_doc = 'index'
# General information about the project.
project = u'marshmallow'
copyright = ' {0:%Y} <a href="https://stevenloria.com">Steven Loria</a>'.format(
- dt.datetime.utcnow()
+ dt.datetime.utcfromtimestamp(os.path.getmtime('../CHANGELOG.rst'))
)
version = release = marshmallow.__version__