Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-proto-plus for openSUSE:Factory checked in at 2026-08-11 17:17:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-proto-plus (Old) and /work/SRC/openSUSE:Factory/.python-proto-plus.new.17972 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-proto-plus" Tue Aug 11 17:17:43 2026 rev:22 rq:1370651 version:1.28.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-proto-plus/python-proto-plus.changes 2026-07-29 19:02:51.657116974 +0200 +++ /work/SRC/openSUSE:Factory/.python-proto-plus.new.17972/python-proto-plus.changes 2026-08-11 17:19:12.211301875 +0200 @@ -1,0 +2,7 @@ +Tue Aug 11 08:20:08 UTC 2026 - Matthias Fehring <[email protected]> - 1.28.3 + +- update to 1.28.3 + * add context to TypeErrors during message manipulation + * require Protobuf 6.33.5+ + +------------------------------------------------------------------- Old: ---- proto_plus-1.28.2.tar.gz New: ---- proto_plus-1.28.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-proto-plus.spec ++++++ --- /var/tmp/diff_new_pack.f9sFLU/_old 2026-08-11 17:19:13.479355420 +0200 +++ /var/tmp/diff_new_pack.f9sFLU/_new 2026-08-11 17:19:13.483355589 +0200 @@ -27,27 +27,27 @@ %define modname proto_plus %{?sle15_python_module_pythons} Name: python-proto-plus%{psuffix} -Version: 1.28.2 +Version: 1.28.3 Release: 0 Summary: Pythonic Protocol Buffers License: Apache-2.0 URL: https://github.com/googleapis/google-cloud-python Source0: https://files.pythonhosted.org/packages/source/p/%{modname}/%{modname}-%{version}.tar.gz BuildRequires: %{python_module pip} -BuildRequires: %{python_module protobuf >= 3.19.0} +BuildRequires: %{python_module protobuf >= 6.33.5} BuildRequires: %{python_module setuptools} BuildRequires: %{python_module wheel} BuildRequires: python-rpm-macros # SECTION test requirements %if %{with test} -BuildRequires: %{python_module google-api-core >= 1.31.5} +BuildRequires: %{python_module google-api-core >= 2.25.0} BuildRequires: %{python_module proto-plus} BuildRequires: %{python_module pytest} BuildRequires: %{python_module pytz} %endif # /SECTION BuildRequires: fdupes -Requires: python-protobuf >= 3.19.0 +Requires: python-protobuf >= 6.33.5 BuildArch: noarch %python_subpackages ++++++ proto_plus-1.28.2.tar.gz -> proto_plus-1.28.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/PKG-INFO new/proto_plus-1.28.3/PKG-INFO --- old/proto_plus-1.28.2/PKG-INFO 2026-07-22 18:00:40.291706800 +0200 +++ new/proto_plus-1.28.3/PKG-INFO 2026-08-06 08:00:09.969019700 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: proto-plus -Version: 1.28.2 +Version: 1.28.3 Summary: Beautiful, Pythonic protocol buffers Author-email: Google LLC <[email protected]> License: Apache 2.0 @@ -23,9 +23,9 @@ Requires-Python: >=3.10 Description-Content-Type: text/x-rst License-File: LICENSE -Requires-Dist: protobuf<8.0.0,>=4.25.8 +Requires-Dist: protobuf<8.0.0,>=6.33.5 Provides-Extra: testing -Requires-Dist: google-api-core>=1.31.5; extra == "testing" +Requires-Dist: google-api-core>=2.25.0; extra == "testing" Dynamic: license-file Proto Plus for Python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/proto/marshal/marshal.py new/proto_plus-1.28.3/proto/marshal/marshal.py --- old/proto_plus-1.28.2/proto/marshal/marshal.py 2026-07-22 17:58:56.000000000 +0200 +++ new/proto_plus-1.28.3/proto/marshal/marshal.py 2026-08-06 07:54:33.000000000 +0200 @@ -223,7 +223,8 @@ # annotation. We need to do the conversion based on the `value` # field's type. if isinstance(value, dict) and ( - proto_type.DESCRIPTOR.has_options + hasattr(proto_type, "DESCRIPTOR") + and proto_type.DESCRIPTOR.has_options and proto_type.DESCRIPTOR.GetOptions().map_entry ): recursive_type = type(proto_type().value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/proto/message.py new/proto_plus-1.28.3/proto/message.py --- old/proto_plus-1.28.2/proto/message.py 2026-07-22 17:58:57.000000000 +0200 +++ new/proto_plus-1.28.3/proto/message.py 2026-08-06 07:54:32.000000000 +0200 @@ -659,28 +659,34 @@ mapping, ) ) - params = {} # Update the mapping to address any values that need to be # coerced. marshal = self._meta.marshal - for key, value in mapping.items(): - (key, pb_type) = self._get_pb_type_from_key(key) - if pb_type is None: - if ignore_unknown_fields: - continue - - raise ValueError( - "Unknown field for {}: {}".format(self.__class__.__name__, key) + try: + for key, value in mapping.items(): + (key, pb_type) = self._get_pb_type_from_key(key) + if pb_type is None: + if ignore_unknown_fields: + continue + + raise ValueError( + "Unknown field for {}: {}".format(self.__class__.__name__, key) + ) + + pb_value = marshal.to_proto(pb_type, value) + + if pb_value is not None: + params[key] = pb_value + + # Create the internal protocol buffer. + super().__setattr__("_pb", self._meta.pb(**params)) + except TypeError as e: + raise TypeError( + "Failed to initialize {}. Underlying error: {}".format( + self.__class__.__name__, e ) - - pb_value = marshal.to_proto(pb_type, value) - - if pb_value is not None: - params[key] = pb_value - - # Create the internal protocol buffer. - super().__setattr__("_pb", self._meta.pb(**params)) + ) from e def _get_pb_type_from_key(self, key): """Given a key, return the corresponding pb_type. @@ -852,16 +858,23 @@ "Unknown field for {}: {}".format(self.__class__.__name__, key) ) - pb_value = marshal.to_proto(pb_type, value) + try: + pb_value = marshal.to_proto(pb_type, value) - # Clear the existing field. - # This is the only way to successfully write nested falsy values, - # because otherwise MergeFrom will no-op on them. - self._pb.ClearField(key) + # Clear the existing field. + # This is the only way to successfully write nested falsy values, + # because otherwise MergeFrom will no-op on them. + self._pb.ClearField(key) - # Merge in the value being set. - if pb_value is not None: - self._pb.MergeFrom(self._meta.pb(**{key: pb_value})) + # Merge in the value being set. + if pb_value is not None: + self._pb.MergeFrom(self._meta.pb(**{key: pb_value})) + except TypeError as e: + raise TypeError( + "Failed to set field '{}' on {} to value {}. Underlying error: {}".format( + key, self.__class__.__name__, value, e + ) + ) from e def __getstate__(self): """Serialize for pickling.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/proto/version.py new/proto_plus-1.28.3/proto/version.py --- old/proto_plus-1.28.2/proto/version.py 2026-07-22 17:58:58.000000000 +0200 +++ new/proto_plus-1.28.3/proto/version.py 2026-08-06 07:54:32.000000000 +0200 @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.28.2" +__version__ = "1.28.3" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/proto_plus.egg-info/PKG-INFO new/proto_plus-1.28.3/proto_plus.egg-info/PKG-INFO --- old/proto_plus-1.28.2/proto_plus.egg-info/PKG-INFO 2026-07-22 18:00:40.000000000 +0200 +++ new/proto_plus-1.28.3/proto_plus.egg-info/PKG-INFO 2026-08-06 08:00:09.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: proto-plus -Version: 1.28.2 +Version: 1.28.3 Summary: Beautiful, Pythonic protocol buffers Author-email: Google LLC <[email protected]> License: Apache 2.0 @@ -23,9 +23,9 @@ Requires-Python: >=3.10 Description-Content-Type: text/x-rst License-File: LICENSE -Requires-Dist: protobuf<8.0.0,>=4.25.8 +Requires-Dist: protobuf<8.0.0,>=6.33.5 Provides-Extra: testing -Requires-Dist: google-api-core>=1.31.5; extra == "testing" +Requires-Dist: google-api-core>=2.25.0; extra == "testing" Dynamic: license-file Proto Plus for Python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/proto_plus.egg-info/requires.txt new/proto_plus-1.28.3/proto_plus.egg-info/requires.txt --- old/proto_plus-1.28.2/proto_plus.egg-info/requires.txt 2026-07-22 18:00:40.000000000 +0200 +++ new/proto_plus-1.28.3/proto_plus.egg-info/requires.txt 2026-08-06 08:00:09.000000000 +0200 @@ -1,4 +1,4 @@ -protobuf<8.0.0,>=4.25.8 +protobuf<8.0.0,>=6.33.5 [testing] -google-api-core>=1.31.5 +google-api-core>=2.25.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/pyproject.toml new/proto_plus-1.28.3/pyproject.toml --- old/proto_plus-1.28.2/pyproject.toml 2026-07-22 17:59:00.000000000 +0200 +++ new/proto_plus-1.28.3/pyproject.toml 2026-08-06 07:54:32.000000000 +0200 @@ -38,7 +38,7 @@ "Topic :: Software Development :: Code Generators", "Topic :: Software Development :: Libraries :: Python Modules", ] -dependencies = ["protobuf >= 4.25.8, < 8.0.0"] +dependencies = ["protobuf >= 6.33.5, < 8.0.0"] dynamic = ["version"] [project.urls] @@ -47,7 +47,7 @@ Homepage = "https://github.com/googleapis/google-cloud-python/tree/main/packages/proto-plus" [project.optional-dependencies] -testing = ["google-api-core >= 1.31.5"] +testing = ["google-api-core >= 2.25.0"] [tool.setuptools.dynamic] version = { attr = "proto.version.__version__" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/tests/test_fields_enum.py new/proto_plus-1.28.3/tests/test_fields_enum.py --- old/proto_plus-1.28.2/tests/test_fields_enum.py 2026-07-22 17:59:00.000000000 +0200 +++ new/proto_plus-1.28.3/tests/test_fields_enum.py 2026-08-06 07:54:33.000000000 +0200 @@ -12,9 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os import proto -import pytest import sys @@ -357,25 +355,6 @@ assert t == t2 -if os.environ.get("PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION", "python") == "cpp": - # This test only works, and is only relevant, with the cpp runtime. - # Python just doesn't give a care and lets it work anyway. - def test_enum_alias_bad(): - # Certain enums may shadow the different enum monikers with the same value. - # This is generally discouraged, and protobuf will object by default, - # but will explicitly allow this behavior if the enum is defined with - # the `allow_alias` option set. - with pytest.raises(TypeError): - # The wrapper message is a hack to avoid manifest wrangling to - # define the enum. - class BadMessage(proto.Message): - class BadEnum(proto.Enum): - UNKNOWN = 0 - DEFAULT = 0 - - bad_dup_enum = proto.Field(proto.ENUM, number=1, enum=BadEnum) - - def test_enum_alias_good(): # Have to split good and bad enum alias into two tests so that the generated # file descriptor is properly created. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto_plus-1.28.2/tests/test_message.py new/proto_plus-1.28.3/tests/test_message.py --- old/proto_plus-1.28.2/tests/test_message.py 2026-07-22 17:58:56.000000000 +0200 +++ new/proto_plus-1.28.3/tests/test_message.py 2026-08-06 07:54:30.000000000 +0200 @@ -500,3 +500,39 @@ def test_dir_message_base(): assert set(dir(proto.Message)) == set(dir(type)) + + +def test_invalid_initialization_type_error(): + """Verify that bad types passed to __init__ raise a descriptive TypeError.""" + + class UserProfile(proto.Message): + username = proto.Field(proto.STRING, number=1) + age = proto.Field(proto.INT32, number=2) + + with pytest.raises(TypeError) as excinfo: + # Passing a list where a string is expected + UserProfile(username=["not", "a", "string"]) + + error_msg = str(excinfo.value) + assert "Failed to initialize UserProfile" in error_msg + assert "Underlying error" in error_msg + assert isinstance(excinfo.value.__cause__, TypeError) + + +def test_invalid_assignment_type_error(): + """Verify that bad types assigned via __setattr__ raise a descriptive TypeError.""" + + class UserProfile(proto.Message): + username = proto.Field(proto.STRING, number=1) + age = proto.Field(proto.INT32, number=2) + + profile = UserProfile() + + with pytest.raises(TypeError) as excinfo: + # Assigning a dictionary where an integer is expected + profile.age = {"invalid": "type"} + + error_msg = str(excinfo.value) + assert "Failed to set field 'age' on UserProfile" in error_msg + assert "{'invalid': 'type'}" in error_msg + assert isinstance(excinfo.value.__cause__, TypeError)
