From 5cb2311ec5423ff5ffa478a06c1971d9572b9b7c97e0f9b5e4e636758998e25b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Wed, 31 Jul 2019 09:14:19 +0000 Subject: [PATCH] - Add patch to fix building with pytest5 from upstream git: * pytest5.patch OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-marshmallow?expand=0&rev=15 --- pytest5.patch | 425 +++++++++++++++++++++++++++++++++++++ python-marshmallow.changes | 6 + python-marshmallow.spec | 5 +- 3 files changed, 434 insertions(+), 2 deletions(-) create mode 100644 pytest5.patch diff --git a/pytest5.patch b/pytest5.patch new file mode 100644 index 0000000..75294c7 --- /dev/null +++ b/pytest5.patch @@ -0,0 +1,425 @@ +From a7014176a7f211aaaa06b516eceb5468402fd9fc Mon Sep 17 00:00:00 2001 +From: Steven Loria +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=''): + validate.NoneOf([1, 2], error='')(1) +- assert '' 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): diff --git a/python-marshmallow.changes b/python-marshmallow.changes index 9319b34..2b3992f 100644 --- a/python-marshmallow.changes +++ b/python-marshmallow.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Jul 31 09:13:51 UTC 2019 - Tomáš Chvátal + +- Add patch to fix building with pytest5 from upstream git: + * pytest5.patch + ------------------------------------------------------------------- Wed Jul 24 07:53:46 UTC 2019 - Tomáš Chvátal diff --git a/python-marshmallow.spec b/python-marshmallow.spec index eb51672..1ae3304 100644 --- a/python-marshmallow.spec +++ b/python-marshmallow.spec @@ -28,6 +28,7 @@ Source: https://files.pythonhosted.org/packages/source/m/marshmallow/mar # 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 @@ -61,8 +62,8 @@ HTML Documentation and examples for %{name}. %prep %setup -q -n marshmallow-%{version} -%patch0 -p1 -%patch1 -p1 +%autopatch -p1 + # remove py3 only tests rm -r tests/test_py3