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 2022-01-31 22:57:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-proto-plus (Old) and /work/SRC/openSUSE:Factory/.python-proto-plus.new.1898 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-proto-plus" Mon Jan 31 22:57:29 2022 rev:5 rq:950247 version:1.19.9 Changes: -------- --- /work/SRC/openSUSE:Factory/python-proto-plus/python-proto-plus.changes 2021-11-11 21:38:45.160990641 +0100 +++ /work/SRC/openSUSE:Factory/.python-proto-plus.new.1898/python-proto-plus.changes 2022-01-31 22:58:22.181158292 +0100 @@ -1,0 +2,27 @@ +Mon Jan 31 15:13:44 UTC 2022 - Matthias Fehring <buschman...@opensuse.org> + +- update to 0.19.9 + * add pickling support to proto messages + (gh#googleapis/proto-plus-python#280) +- from 0.19.8 + * fix typos +- from 0.19.7 + * restore allowing None as value for stringy ints + (gh#googleapis/proto-plus-python#272) +- from 0.19.6 + * setting 64bit fields from strings supported + (gh#googleapis/proto-plus-python#267) +- from 0.19.5 + * Clarify semantics of multiple oneof variants passed to msg ctor +- from 0.19.4 + * clarify that proto plus messages are not pickleable +- from 0.19.3 + * setting bytes field from python string base64 decodes before + assignment (gh#googleapis/proto-plus-python#265) +- from 0.19.2 + * ensure enums are hashable (gh#googleapis/proto-plus-python#252) +- from 0.19.1 + * ensure enums are incomparable w other enum types + (gh#googleapis/proto-plus-python#248) + +------------------------------------------------------------------- Old: ---- proto-plus-1.19.0.tar.gz New: ---- proto-plus-1.19.9.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-proto-plus.spec ++++++ --- /var/tmp/diff_new_pack.WIt9tn/_old 2022-01-31 22:58:22.689154872 +0100 +++ /var/tmp/diff_new_pack.WIt9tn/_new 2022-01-31 22:58:22.693154845 +0100 @@ -1,7 +1,7 @@ # # spec file # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -28,7 +28,7 @@ %define skip_python2 1 %define modname proto-plus Name: python-proto-plus%{psuffix} -Version: 1.19.0 +Version: 1.19.9 Release: 0 Summary: Pythonic Protocol Buffers License: Apache-2.0 ++++++ proto-plus-1.19.0.tar.gz -> proto-plus-1.19.9.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/PKG-INFO new/proto-plus-1.19.9/PKG-INFO --- old/proto-plus-1.19.0/PKG-INFO 2021-06-29 18:47:59.441519700 +0200 +++ new/proto-plus-1.19.9/PKG-INFO 2022-01-25 23:48:13.936669800 +0100 @@ -1,42 +1,11 @@ Metadata-Version: 2.1 Name: proto-plus -Version: 1.19.0 +Version: 1.19.9 Summary: Beautiful, Pythonic protocol buffers. Home-page: https://github.com/googleapis/proto-plus-python.git Author: Google LLC Author-email: googleapis-packa...@google.com License: Apache 2.0 -Description: Proto Plus for Python - ===================== - - |pypi| |release level| |docs| |codecov| - - Beautiful, Pythonic protocol buffers. - - This is a wrapper around `protocol buffers`_. Protocol buffers is a - specification format for APIs, such as those inside Google. - This library provides protocol buffer message classes and objects that - largely behave like native Python types. - - .. _protocol buffers: https://developers.google.com/protocol-buffers/ - - - Documentation - ------------- - - `Documentation`_ is available on Read the Docs. - - .. _documentation: https://proto-plus-python.readthedocs.io/en/latest/ - - .. |pypi| image:: https://img.shields.io/pypi/v/proto-plus.svg - :target: https://pypi.org/project/proto-plus - .. |release level| image:: https://img.shields.io/badge/release%20level-ga-gold.svg?style=flat - :target: https://cloud.google.com/terms/launch-stages - .. |docs| image:: https://readthedocs.org/projects/proto-plus-python/badge/?version=latest - :target: https://proto-plus-python.readthedocs.io/en/latest/ - .. |codecov| image:: https://codecov.io/gh/googleapis/proto-plus-python/graph/badge.svg - :target: https://codecov.io/gh/googleapis/proto-plus-python - Platform: Posix; MacOS X Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console @@ -52,3 +21,37 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.6 Provides-Extra: testing +License-File: LICENSE + +Proto Plus for Python +===================== + +|pypi| |release level| |docs| |codecov| + + Beautiful, Pythonic protocol buffers. + +This is a wrapper around `protocol buffers`_. Protocol buffers is a +specification format for APIs, such as those inside Google. +This library provides protocol buffer message classes and objects that +largely behave like native Python types. + +.. _protocol buffers: https://developers.google.com/protocol-buffers/ + + +Documentation +------------- + +`Documentation`_ is available on Read the Docs. + +.. _documentation: https://proto-plus-python.readthedocs.io/en/latest/ + +.. |pypi| image:: https://img.shields.io/pypi/v/proto-plus.svg + :target: https://pypi.org/project/proto-plus +.. |release level| image:: https://img.shields.io/badge/release%20level-ga-gold.svg?style=flat + :target: https://cloud.google.com/terms/launch-stages +.. |docs| image:: https://readthedocs.org/projects/proto-plus-python/badge/?version=latest + :target: https://proto-plus-python.readthedocs.io/en/latest/ +.. |codecov| image:: https://codecov.io/gh/googleapis/proto-plus-python/graph/badge.svg + :target: https://codecov.io/gh/googleapis/proto-plus-python + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto/datetime_helpers.py new/proto-plus-1.19.9/proto/datetime_helpers.py --- old/proto-plus-1.19.0/proto/datetime_helpers.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/proto/datetime_helpers.py 2022-01-25 23:48:06.000000000 +0100 @@ -63,7 +63,7 @@ datetime object is ignored and the datetime is treated as UTC. Returns: - str: The RFC3339 formated string representing the datetime. + str: The RFC3339 formatted string representing the datetime. """ if not ignore_zone and value.tzinfo is not None: # Convert to UTC and remove the time zone info. @@ -97,7 +97,7 @@ new values by whichever keyword arguments are specified. For example, if d == date(2002, 12, 31), then d.replace(day=26) == date(2002, 12, 26). - NOTE: nanosecond and microsecond are mutually exclusive arguemnts. + NOTE: nanosecond and microsecond are mutually exclusive arguments. """ ms_provided = "microsecond" in kw diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto/enums.py new/proto-plus-1.19.9/proto/enums.py --- old/proto-plus-1.19.0/proto/enums.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/proto/enums.py 2022-01-25 23:48:06.000000000 +0100 @@ -108,7 +108,48 @@ class Enum(enum.IntEnum, metaclass=ProtoEnumMeta): """A enum object that also builds a protobuf enum descriptor.""" - pass + def _comparable(self, other): + # Avoid 'isinstance' to prevent other IntEnums from matching + return type(other) in (type(self), int) + + def __hash__(self): + return hash(self.value) + + def __eq__(self, other): + if not self._comparable(other): + return NotImplemented + + return self.value == int(other) + + def __ne__(self, other): + if not self._comparable(other): + return NotImplemented + + return self.value != int(other) + + def __lt__(self, other): + if not self._comparable(other): + return NotImplemented + + return self.value < int(other) + + def __le__(self, other): + if not self._comparable(other): + return NotImplemented + + return self.value <= int(other) + + def __ge__(self, other): + if not self._comparable(other): + return NotImplemented + + return self.value >= int(other) + + def __gt__(self, other): + if not self._comparable(other): + return NotImplemented + + return self.value > int(other) class _EnumInfo: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto/fields.py new/proto-plus-1.19.9/proto/fields.py --- old/proto-plus-1.19.0/proto/fields.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/proto/fields.py 2022-01-25 23:48:06.000000000 +0100 @@ -126,14 +126,15 @@ @property def pb_type(self): - """Return the composite type of the field, or None for primitives.""" + """Return the composite type of the field, or the primitive type if a primitive.""" # For enums, return the Python enum. if self.enum: return self.enum - # For non-enum primitives, return None. + # For primitive fields, we still want to know + # what the type is. if not self.message: - return None + return self.proto_type # Return the internal protobuf message. if hasattr(self.message, "_meta"): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto/marshal/marshal.py new/proto-plus-1.19.9/proto/marshal/marshal.py --- old/proto-plus-1.19.0/proto/marshal/marshal.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/proto/marshal/marshal.py 2022-01-25 23:48:06.000000000 +0100 @@ -25,9 +25,12 @@ from proto.marshal.collections import MapComposite from proto.marshal.collections import Repeated from proto.marshal.collections import RepeatedComposite +from proto.marshal.rules import bytes as pb_bytes +from proto.marshal.rules import stringy_numbers from proto.marshal.rules import dates from proto.marshal.rules import struct from proto.marshal.rules import wrappers +from proto.primitives import ProtoType class Rule(abc.ABC): @@ -85,14 +88,6 @@ proto_type (type): A protocol buffer message type. rule: A marshal object """ - # Sanity check: Do not register anything to a class that is not - # a protocol buffer message. - if not issubclass(proto_type, (message.Message, enum.IntEnum)): - raise TypeError( - "Only enums and protocol buffer messages may be " - "registered to the marshal." - ) - # If a rule was provided, register it and be done. if rule: # Ensure the rule implements Rule. @@ -150,6 +145,14 @@ self.register(struct_pb2.ListValue, struct.ListValueRule(marshal=self)) self.register(struct_pb2.Struct, struct.StructRule(marshal=self)) + # Special case for bytes to allow base64 encode/decode + self.register(ProtoType.BYTES, pb_bytes.BytesRule()) + + # Special case for int64 from strings because of dict round trip. + # See https://github.com/protocolbuffers/protobuf/issues/2679 + for rule_class in stringy_numbers.STRINGY_NUMBER_RULES: + self.register(rule_class._proto_type, rule_class()) + def to_python(self, proto_type, value, *, absent: bool = None): # Internal protobuf has its own special type for lists of values. # Return a view around it that implements MutableSequence. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto/marshal/rules/bytes.py new/proto-plus-1.19.9/proto/marshal/rules/bytes.py --- old/proto-plus-1.19.0/proto/marshal/rules/bytes.py 1970-01-01 01:00:00.000000000 +0100 +++ new/proto-plus-1.19.9/proto/marshal/rules/bytes.py 2022-01-25 23:48:06.000000000 +0100 @@ -0,0 +1,44 @@ +# Copyright (C) 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import base64 + + +class BytesRule: + """A marshal between Python strings and protobuf bytes. + + Note: this conversion is asymmetric because Python does have a bytes type. + It is sometimes necessary to convert proto bytes fields to strings, e.g. for + JSON encoding, marshalling a message to a dict. Because bytes fields can + represent arbitrary data, bytes fields are base64 encoded when they need to + be represented as strings. + + It is necessary to have the conversion be bidirectional, i.e. + my_message == MyMessage(MyMessage.to_dict(my_message)) + + To accomplish this, we need to intercept assignments from strings and + base64 decode them back into bytes. + """ + + def to_python(self, value, *, absent: bool = None): + return value + + def to_proto(self, value): + if isinstance(value, str): + value = value.encode("utf-8") + value += b"=" * (4 - len(value) % 4) # padding + value = base64.urlsafe_b64decode(value) + + return value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto/marshal/rules/message.py new/proto-plus-1.19.9/proto/marshal/rules/message.py --- old/proto-plus-1.19.0/proto/marshal/rules/message.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/proto/marshal/rules/message.py 2022-01-25 23:48:06.000000000 +0100 @@ -29,7 +29,16 @@ if isinstance(value, self._wrapper): return self._wrapper.pb(value) if isinstance(value, dict) and not self.is_map: - return self._descriptor(**value) + # We need to use the wrapper's marshaling to handle + # potentially problematic nested messages. + try: + # Try the fast path first. + return self._descriptor(**value) + except TypeError as ex: + # If we have a type error, + # try the slow path in case the error + # was an int64/string issue + return self._wrapper(value)._pb return value @property diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto/marshal/rules/stringy_numbers.py new/proto-plus-1.19.9/proto/marshal/rules/stringy_numbers.py --- old/proto-plus-1.19.0/proto/marshal/rules/stringy_numbers.py 1970-01-01 01:00:00.000000000 +0100 +++ new/proto-plus-1.19.9/proto/marshal/rules/stringy_numbers.py 2022-01-25 23:48:06.000000000 +0100 @@ -0,0 +1,71 @@ +# Copyright (C) 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from proto.primitives import ProtoType + + +class StringyNumberRule: + """A marshal between certain numeric types and strings + + This is a necessary hack to allow round trip conversion + from messages to dicts back to messages. + + See https://github.com/protocolbuffers/protobuf/issues/2679 + and + https://developers.google.com/protocol-buffers/docs/proto3#json + for more details. + """ + + def to_python(self, value, *, absent: bool = None): + return value + + def to_proto(self, value): + if value is not None: + return self._python_type(value) + + return None + + +class Int64Rule(StringyNumberRule): + _python_type = int + _proto_type = ProtoType.INT64 + + +class UInt64Rule(StringyNumberRule): + _python_type = int + _proto_type = ProtoType.UINT64 + + +class SInt64Rule(StringyNumberRule): + _python_type = int + _proto_type = ProtoType.SINT64 + + +class Fixed64Rule(StringyNumberRule): + _python_type = int + _proto_type = ProtoType.FIXED64 + + +class SFixed64Rule(StringyNumberRule): + _python_type = int + _proto_type = ProtoType.SFIXED64 + + +STRINGY_NUMBER_RULES = [ + Int64Rule, + UInt64Rule, + SInt64Rule, + Fixed64Rule, + SFixed64Rule, +] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto/message.py new/proto-plus-1.19.9/proto/message.py --- old/proto-plus-1.19.0/proto/message.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/proto/message.py 2022-01-25 23:48:06.000000000 +0100 @@ -394,7 +394,7 @@ determines whether field name representations preserve proto case (snake_case) or use lowerCamelCase. Default is True. including_default_value_fields (Optional(bool)): An option that - determines whether the default field values should be included in the results. + determines whether the default field values should be included in the results. Default is True. Returns: @@ -453,7 +453,9 @@ message. """ - def __init__(self, mapping=None, *, ignore_unknown_fields=False, **kwargs): + def __init__( + self, mapping=None, *, ignore_unknown_fields=False, **kwargs, + ): # We accept several things for `mapping`: # * An instance of this class. # * An instance of the underlying protobuf descriptor class. @@ -473,7 +475,7 @@ # passed in. # # The `wrap` method on the metaclass is the public API for taking - # ownership of the passed in protobuf objet. + # ownership of the passed in protobuf object. mapping = copy.deepcopy(mapping) if kwargs: mapping.MergeFrom(self._meta.pb(**kwargs)) @@ -538,7 +540,7 @@ to get a boolean that distinguishes between ``False`` and ``None`` (or the same for a string, int, etc.). This library transparently handles that case for you, but this method remains available to - accomodate cases not automatically covered. + accommodate cases not automatically covered. Args: key (str): The name of the field. @@ -640,6 +642,15 @@ if pb_value is not None: self._pb.MergeFrom(self._meta.pb(**{key: pb_value})) + def __getstate__(self): + """Serialize for pickling.""" + return self._pb.SerializeToString() + + def __setstate__(self, value): + """Deserialization for pickling.""" + new_pb = self._meta.pb().FromString(value) + super().__setattr__("_pb", new_pb) + class _MessageInfo: """Metadata about a message. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto_plus.egg-info/PKG-INFO new/proto-plus-1.19.9/proto_plus.egg-info/PKG-INFO --- old/proto-plus-1.19.0/proto_plus.egg-info/PKG-INFO 2021-06-29 18:47:59.000000000 +0200 +++ new/proto-plus-1.19.9/proto_plus.egg-info/PKG-INFO 2022-01-25 23:48:13.000000000 +0100 @@ -1,42 +1,11 @@ Metadata-Version: 2.1 Name: proto-plus -Version: 1.19.0 +Version: 1.19.9 Summary: Beautiful, Pythonic protocol buffers. Home-page: https://github.com/googleapis/proto-plus-python.git Author: Google LLC Author-email: googleapis-packa...@google.com License: Apache 2.0 -Description: Proto Plus for Python - ===================== - - |pypi| |release level| |docs| |codecov| - - Beautiful, Pythonic protocol buffers. - - This is a wrapper around `protocol buffers`_. Protocol buffers is a - specification format for APIs, such as those inside Google. - This library provides protocol buffer message classes and objects that - largely behave like native Python types. - - .. _protocol buffers: https://developers.google.com/protocol-buffers/ - - - Documentation - ------------- - - `Documentation`_ is available on Read the Docs. - - .. _documentation: https://proto-plus-python.readthedocs.io/en/latest/ - - .. |pypi| image:: https://img.shields.io/pypi/v/proto-plus.svg - :target: https://pypi.org/project/proto-plus - .. |release level| image:: https://img.shields.io/badge/release%20level-ga-gold.svg?style=flat - :target: https://cloud.google.com/terms/launch-stages - .. |docs| image:: https://readthedocs.org/projects/proto-plus-python/badge/?version=latest - :target: https://proto-plus-python.readthedocs.io/en/latest/ - .. |codecov| image:: https://codecov.io/gh/googleapis/proto-plus-python/graph/badge.svg - :target: https://codecov.io/gh/googleapis/proto-plus-python - Platform: Posix; MacOS X Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console @@ -52,3 +21,37 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.6 Provides-Extra: testing +License-File: LICENSE + +Proto Plus for Python +===================== + +|pypi| |release level| |docs| |codecov| + + Beautiful, Pythonic protocol buffers. + +This is a wrapper around `protocol buffers`_. Protocol buffers is a +specification format for APIs, such as those inside Google. +This library provides protocol buffer message classes and objects that +largely behave like native Python types. + +.. _protocol buffers: https://developers.google.com/protocol-buffers/ + + +Documentation +------------- + +`Documentation`_ is available on Read the Docs. + +.. _documentation: https://proto-plus-python.readthedocs.io/en/latest/ + +.. |pypi| image:: https://img.shields.io/pypi/v/proto-plus.svg + :target: https://pypi.org/project/proto-plus +.. |release level| image:: https://img.shields.io/badge/release%20level-ga-gold.svg?style=flat + :target: https://cloud.google.com/terms/launch-stages +.. |docs| image:: https://readthedocs.org/projects/proto-plus-python/badge/?version=latest + :target: https://proto-plus-python.readthedocs.io/en/latest/ +.. |codecov| image:: https://codecov.io/gh/googleapis/proto-plus-python/graph/badge.svg + :target: https://codecov.io/gh/googleapis/proto-plus-python + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto_plus.egg-info/SOURCES.txt new/proto-plus-1.19.9/proto_plus.egg-info/SOURCES.txt --- old/proto-plus-1.19.0/proto_plus.egg-info/SOURCES.txt 2021-06-29 18:47:59.000000000 +0200 +++ new/proto-plus-1.19.9/proto_plus.egg-info/SOURCES.txt 2022-01-25 23:48:13.000000000 +0100 @@ -19,9 +19,11 @@ proto/marshal/collections/maps.py proto/marshal/collections/repeated.py proto/marshal/rules/__init__.py +proto/marshal/rules/bytes.py proto/marshal/rules/dates.py proto/marshal/rules/enums.py proto/marshal/rules/message.py +proto/marshal/rules/stringy_numbers.py proto/marshal/rules/struct.py proto/marshal/rules/wrappers.py proto_plus.egg-info/PKG-INFO @@ -32,8 +34,10 @@ proto_plus.egg-info/top_level.txt tests/clam.py tests/conftest.py +tests/enums_test.py tests/mollusc.py tests/test_datetime_helpers.py +tests/test_enum_total_ordering.py tests/test_fields_bytes.py tests/test_fields_composite.py tests/test_fields_composite_string_ref.py @@ -51,6 +55,7 @@ tests/test_json.py tests/test_marshal_register.py tests/test_marshal_strict.py +tests/test_marshal_stringy_numbers.py tests/test_marshal_types_dates.py tests/test_marshal_types_enum.py tests/test_marshal_types_message.py @@ -61,5 +66,6 @@ tests/test_message_filename_with_and_without_manifest.py tests/test_message_filename_with_manifest.py tests/test_message_nested.py +tests/test_message_pickling.py tests/test_modules.py tests/zone.py \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/proto_plus.egg-info/requires.txt new/proto-plus-1.19.9/proto_plus.egg-info/requires.txt --- old/proto-plus-1.19.0/proto_plus.egg-info/requires.txt 2021-06-29 18:47:59.000000000 +0200 +++ new/proto-plus-1.19.9/proto_plus.egg-info/requires.txt 2022-01-25 23:48:13.000000000 +0100 @@ -1,4 +1,4 @@ -protobuf>=3.12.0 +protobuf>=3.19.0 [testing] google-api-core[grpc]>=1.22.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/setup.py new/proto-plus-1.19.9/setup.py --- old/proto-plus-1.19.0/setup.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/setup.py 2022-01-25 23:48:06.000000000 +0100 @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.19.0" +version = "1.19.9" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) @@ -36,7 +36,7 @@ long_description=README, platforms="Posix; MacOS X", include_package_data=True, - install_requires=("protobuf >= 3.12.0",), + install_requires=("protobuf >= 3.19.0",), extras_require={"testing": ["google-api-core[grpc] >= 1.22.2",],}, python_requires=">=3.6", classifiers=[ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/enums_test.py new/proto-plus-1.19.9/tests/enums_test.py --- old/proto-plus-1.19.0/tests/enums_test.py 1970-01-01 01:00:00.000000000 +0100 +++ new/proto-plus-1.19.9/tests/enums_test.py 2022-01-25 23:48:06.000000000 +0100 @@ -0,0 +1,28 @@ +# Copyright (C) 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import proto + +__protobuf__ = proto.module(package="test.proto", manifest={"Enums",},) + + +class OneEnum(proto.Enum): + UNSPECIFIED = 0 + SOME_VALUE = 1 + + +class OtherEnum(proto.Enum): + UNSPECIFIED = 0 + APPLE = 1 + BANANA = 2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/test_datetime_helpers.py new/proto-plus-1.19.9/tests/test_datetime_helpers.py --- old/proto-plus-1.19.0/tests/test_datetime_helpers.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/tests/test_datetime_helpers.py 2022-01-25 23:48:06.000000000 +0100 @@ -281,7 +281,7 @@ """Convert a datetime to seconds since the unix epoch. Args: - value (datetime.datetime): The datetime to covert. + value (datetime.datetime): The datetime to convert. Returns: int: Microseconds since the unix epoch. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/test_enum_total_ordering.py new/proto-plus-1.19.9/tests/test_enum_total_ordering.py --- old/proto-plus-1.19.0/tests/test_enum_total_ordering.py 1970-01-01 01:00:00.000000000 +0100 +++ new/proto-plus-1.19.9/tests/test_enum_total_ordering.py 2022-01-25 23:48:06.000000000 +0100 @@ -0,0 +1,93 @@ +# Copyright 2021, Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +import enums_test + + +def test_total_ordering_w_same_enum_type(): + to_compare = enums_test.OneEnum.SOME_VALUE + + for item in enums_test.OneEnum: + if item.value < to_compare.value: + assert not to_compare == item + assert to_compare != item + assert not to_compare < item + assert not to_compare <= item + assert to_compare > item + assert to_compare >= item + elif item.value > to_compare.value: + assert not to_compare == item + assert to_compare != item + assert to_compare < item + assert to_compare <= item + assert not to_compare > item + assert not to_compare >= item + else: # item.value == to_compare.value: + assert to_compare == item + assert not to_compare != item + assert not to_compare < item + assert to_compare <= item + assert not to_compare > item + assert to_compare >= item + + +def test_total_ordering_w_other_enum_type(): + to_compare = enums_test.OneEnum.SOME_VALUE + + for item in enums_test.OtherEnum: + assert not to_compare == item + assert to_compare.SOME_VALUE != item + with pytest.raises(TypeError): + assert not to_compare < item + with pytest.raises(TypeError): + assert not to_compare <= item + with pytest.raises(TypeError): + assert not to_compare > item + with pytest.raises(TypeError): + assert not to_compare >= item + + +@pytest.mark.parametrize("int_val", range(-1, 3)) +def test_total_ordering_w_int(int_val): + to_compare = enums_test.OneEnum.SOME_VALUE + + if int_val < to_compare.value: + assert not to_compare == int_val + assert to_compare != int_val + assert not to_compare < int_val + assert not to_compare <= int_val + assert to_compare > int_val + assert to_compare >= int_val + elif int_val > to_compare.value: + assert not to_compare == int_val + assert to_compare != int_val + assert to_compare < int_val + assert to_compare <= int_val + assert not to_compare > int_val + assert not to_compare >= int_val + else: # int_val == to_compare.value: + assert to_compare == int_val + assert not to_compare != int_val + assert not to_compare < int_val + assert to_compare <= int_val + assert not to_compare > int_val + assert to_compare >= int_val + + +def test_hashing(): + to_hash = enums_test.OneEnum.SOME_VALUE + + {to_hash: "testing"} # no raise diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/test_fields_bytes.py new/proto-plus-1.19.9/tests/test_fields_bytes.py --- old/proto-plus-1.19.0/tests/test_fields_bytes.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/tests/test_fields_bytes.py 2022-01-25 23:48:06.000000000 +0100 @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import base64 import pytest import proto @@ -71,5 +72,25 @@ # for strings (but not vice versa). foo.bar = b"anything" assert foo.bar == "anything" - with pytest.raises(TypeError): - foo.baz = "anything" + + # We need to permit setting bytes fields from strings, + # but the marshalling needs to base64 decode the result. + # This is a requirement for interop with the vanilla protobuf runtime: + # converting a proto message to a dict base64 encodes the bytes + # because it may be sent over the network via a protocol like HTTP. + encoded_swallow: str = base64.urlsafe_b64encode(b"unladen swallow").decode("utf-8") + assert type(encoded_swallow) == str + foo.baz = encoded_swallow + assert foo.baz == b"unladen swallow" + + +def test_bytes_to_dict_bidi(): + class Foo(proto.Message): + bar = proto.Field(proto.BYTES, number=1) + + foo = Foo(bar=b"spam") + + foo_dict = Foo.to_dict(foo) + foo_two = Foo(foo_dict) + + assert foo == foo_two diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/test_fields_int.py new/proto-plus-1.19.9/tests/test_fields_int.py --- old/proto-plus-1.19.0/tests/test_fields_int.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/tests/test_fields_int.py 2022-01-25 23:48:06.000000000 +0100 @@ -93,3 +93,46 @@ bar_field = Foo.meta.fields["bar"] assert bar_field.descriptor is bar_field.descriptor + + +def test_int64_dict_round_trip(): + # When converting a message to other types, protobuf turns int64 fields + # into decimal coded strings. + # This is not a problem for round trip JSON, but it is a problem + # when doing a round trip conversion from a message to a dict to a message. + # See https://github.com/protocolbuffers/protobuf/issues/2679 + # and + # https://developers.google.com/protocol-buffers/docs/proto3#json + # for more details. + class Squid(proto.Message): + mass_kg = proto.Field(proto.INT64, number=1) + length_cm = proto.Field(proto.UINT64, number=2) + age_s = proto.Field(proto.FIXED64, number=3) + depth_m = proto.Field(proto.SFIXED64, number=4) + serial_num = proto.Field(proto.SINT64, number=5) + + s = Squid(mass_kg=10, length_cm=20, age_s=30, depth_m=40, serial_num=50) + + s_dict = Squid.to_dict(s) + + s2 = Squid(s_dict) + + assert s == s2 + + # Double check that the conversion works with deeply nested messages. + class Clam(proto.Message): + class Shell(proto.Message): + class Pearl(proto.Message): + mass_kg = proto.Field(proto.INT64, number=1) + + pearl = proto.Field(Pearl, number=1) + + shell = proto.Field(Shell, number=1) + + c = Clam(shell=Clam.Shell(pearl=Clam.Shell.Pearl(mass_kg=10))) + + c_dict = Clam.to_dict(c) + + c2 = Clam(c_dict) + + assert c == c2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/test_json.py new/proto-plus-1.19.9/tests/test_json.py --- old/proto-plus-1.19.0/tests/test_json.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/tests/test_json.py 2022-01-25 23:48:06.000000000 +0100 @@ -148,3 +148,17 @@ assert s.mass_kg == 20 assert Squid.to_json(s, preserving_proto_field_name=True) == json_str + + +def test_json_name(): + class Squid(proto.Message): + massKg = proto.Field(proto.INT32, number=1, json_name="mass_in_kilograms") + + s = Squid(massKg=20) + j = Squid.to_json(s) + + assert "mass_in_kilograms" in j + + s_two = Squid.from_json(j) + + assert s == s_two diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/test_marshal_register.py new/proto-plus-1.19.9/tests/test_marshal_register.py --- old/proto-plus-1.19.0/tests/test_marshal_register.py 2021-06-29 18:47:52.000000000 +0200 +++ new/proto-plus-1.19.9/tests/test_marshal_register.py 2022-01-25 23:48:06.000000000 +0100 @@ -33,19 +33,6 @@ assert isinstance(marshal._rules[empty_pb2.Empty], Rule) -def test_invalid_target_registration(): - marshal = BaseMarshal() - with pytest.raises(TypeError): - - @marshal.register(object) - class Rule: - def to_proto(self, value): - return value - - def to_python(self, value, *, absent=None): - return value - - def test_invalid_marshal_class(): marshal = BaseMarshal() with pytest.raises(TypeError): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/test_marshal_stringy_numbers.py new/proto-plus-1.19.9/tests/test_marshal_stringy_numbers.py --- old/proto-plus-1.19.0/tests/test_marshal_stringy_numbers.py 1970-01-01 01:00:00.000000000 +0100 +++ new/proto-plus-1.19.9/tests/test_marshal_stringy_numbers.py 2022-01-25 23:48:06.000000000 +0100 @@ -0,0 +1,50 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +from proto.marshal.marshal import BaseMarshal +from proto.primitives import ProtoType + +INT_32BIT_PLUS_ONE = 0xFFFFFFFF + 1 + + +@pytest.mark.parametrize( + "pb_type,value,expected", + [ + (ProtoType.INT64, 0, 0), + (ProtoType.INT64, INT_32BIT_PLUS_ONE, INT_32BIT_PLUS_ONE), + (ProtoType.SINT64, -INT_32BIT_PLUS_ONE, -INT_32BIT_PLUS_ONE), + (ProtoType.INT64, None, None), + (ProtoType.UINT64, 0, 0), + (ProtoType.UINT64, INT_32BIT_PLUS_ONE, INT_32BIT_PLUS_ONE), + (ProtoType.UINT64, None, None), + (ProtoType.SINT64, 0, 0), + (ProtoType.SINT64, INT_32BIT_PLUS_ONE, INT_32BIT_PLUS_ONE), + (ProtoType.SINT64, -INT_32BIT_PLUS_ONE, -INT_32BIT_PLUS_ONE), + (ProtoType.SINT64, None, None), + (ProtoType.FIXED64, 0, 0), + (ProtoType.FIXED64, INT_32BIT_PLUS_ONE, INT_32BIT_PLUS_ONE), + (ProtoType.FIXED64, -INT_32BIT_PLUS_ONE, -INT_32BIT_PLUS_ONE), + (ProtoType.FIXED64, None, None), + (ProtoType.SFIXED64, 0, 0), + (ProtoType.SFIXED64, INT_32BIT_PLUS_ONE, INT_32BIT_PLUS_ONE), + (ProtoType.SFIXED64, -INT_32BIT_PLUS_ONE, -INT_32BIT_PLUS_ONE), + (ProtoType.SFIXED64, None, None), + ], +) +def test_marshal_to_proto_stringy_numbers(pb_type, value, expected): + + marshal = BaseMarshal() + assert marshal.to_proto(pb_type, value) == expected diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/proto-plus-1.19.0/tests/test_message_pickling.py new/proto-plus-1.19.9/tests/test_message_pickling.py --- old/proto-plus-1.19.0/tests/test_message_pickling.py 1970-01-01 01:00:00.000000000 +0100 +++ new/proto-plus-1.19.9/tests/test_message_pickling.py 2022-01-25 23:48:06.000000000 +0100 @@ -0,0 +1,51 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import itertools +import pickle + +import pytest + +import proto + + +class Squid(proto.Message): + # Test primitives, enums, and repeated fields. + class Chromatophore(proto.Message): + class Color(proto.Enum): + UNKNOWN = 0 + RED = 1 + BROWN = 2 + WHITE = 3 + BLUE = 4 + + color = proto.Field(Color, number=1) + + mass_kg = proto.Field(proto.INT32, number=1) + chromatophores = proto.RepeatedField(Chromatophore, number=2) + + +def test_pickling(): + + s = Squid(mass_kg=20) + colors = ["RED", "BROWN", "WHITE", "BLUE"] + s.chromatophores = [ + {"color": c} for c in itertools.islice(itertools.cycle(colors), 10) + ] + + pickled = pickle.dumps(s) + + unpickled = pickle.loads(pickled) + + assert unpickled == s