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&#x3D;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&#x3D;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&#x3D;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&#x3D;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

Reply via email to