From 4c967b0bb2ead29156bcc53c1f3b227b3afb2e8b Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 19 Feb 2021 10:27:44 -0800 Subject: [PATCH 01/33] feat: Pypi publish ghub actions (#189) --- .github/workflows/pypi-upload.yaml | 24 ++++++++++++++++++++++++ .github/workflows/release-please.yml | 16 ++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 .github/workflows/pypi-upload.yaml create mode 100644 .github/workflows/release-please.yml diff --git a/.github/workflows/pypi-upload.yaml b/.github/workflows/pypi-upload.yaml new file mode 100644 index 00000000..28ae777e --- /dev/null +++ b/.github/workflows/pypi-upload.yaml @@ -0,0 +1,24 @@ +name: Upload Python Package to PyPI + +on: + release: + types: [created] + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install dependencies + run: python -m pip install twine + - name: Package and upload modulee + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + python setup.py sdist bdist_wheel + twine upload dist/* diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 00000000..f62dda84 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,16 @@ +name: release-please + +on: + push: + branches: + - master + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: GoogleCloudPlatform/release-please-action@v1.3.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + release-type: python + package-name: proto-plus From 3bf3c800aa517188ff267fa9a18f68776dd05154 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 19 Feb 2021 10:36:50 -0800 Subject: [PATCH 02/33] chore: Ci fix (#187) --- .github/workflows/tests.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3be96ea0..f0642c8b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,6 +13,10 @@ jobs: style-check: runs-on: ubuntu-latest steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.7.0 + with: + access_token: ${{ github.token }} - uses: actions/checkout@v2 - name: Set up Python 3.8 uses: actions/setup-python@v2 @@ -25,6 +29,10 @@ jobs: docs: runs-on: ubuntu-latest steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.7.0 + with: + access_token: ${{ github.token }} - uses: actions/checkout@v2 - name: Set up Python 3.8 uses: actions/setup-python@v2 @@ -45,6 +53,10 @@ jobs: - python: 3.9 variant: cpp steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.7.0 + with: + access_token: ${{ github.token }} - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v2 From 5b260c200511f6120f822f3de1906687b446ad6b Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Wed, 24 Feb 2021 14:18:41 -0800 Subject: [PATCH 03/33] chore: attempt to remove release-please Github action (#196) It's possible the .github/release-please.yml file is sufficient. --- .github/workflows/release-please.yml | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .github/workflows/release-please.yml diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml deleted file mode 100644 index f62dda84..00000000 --- a/.github/workflows/release-please.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: release-please - -on: - push: - branches: - - master - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: GoogleCloudPlatform/release-please-action@v1.3.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - release-type: python - package-name: proto-plus From 5ebf1a9ba46b7de18ca86f1982ad7d6acdae57cc Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Wed, 24 Feb 2021 23:26:19 +0100 Subject: [PATCH 04/33] chore(deps): update styfle/cancel-workflow-action action to v0.8.0 (#193) Co-authored-by: Dov Shlachter --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f0642c8b..b64a7462 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.7.0 + uses: styfle/cancel-workflow-action@0.8.0 with: access_token: ${{ github.token }} - uses: actions/checkout@v2 @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.7.0 + uses: styfle/cancel-workflow-action@0.8.0 with: access_token: ${{ github.token }} - uses: actions/checkout@v2 @@ -54,7 +54,7 @@ jobs: variant: cpp steps: - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.7.0 + uses: styfle/cancel-workflow-action@0.8.0 with: access_token: ${{ github.token }} - uses: actions/checkout@v2 From 7ef9adcacd0ac99895393c36a8e49f2638b018c5 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 24 Feb 2021 15:25:58 -0800 Subject: [PATCH 05/33] chore: release 1.14.0 (#191) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Dov Shlachter --- CHANGELOG.md | 13 +++++++++++++ setup.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00a9e65d..7cb13f4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [1.14.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.13.1...v1.14.0) (2021-02-24) + + +### Features + +* Pypi publish ghub actions ([#189](https://www.github.com/googleapis/proto-plus-python/issues/189)) ([4c967b0](https://www.github.com/googleapis/proto-plus-python/commit/4c967b0bb2ead29156bcc53c1f3b227b3afb2e8b)) + + +### Bug Fixes + +* proper __setitem__ and insert for RepeatedComposite ([#178](https://www.github.com/googleapis/proto-plus-python/issues/178)) ([1157a76](https://www.github.com/googleapis/proto-plus-python/commit/1157a76bb608d72389f46dc4d8e9aa00cc14ccc6)) +* proper native marshal for repeated enumeration fields ([#180](https://www.github.com/googleapis/proto-plus-python/issues/180)) ([30265d6](https://www.github.com/googleapis/proto-plus-python/commit/30265d654d7f3589cbd0994d2ac564db1fd44265)) + ### [1.13.1](https://www.github.com/googleapis/proto-plus-python/compare/v1.13.0...v1.13.1) (2021-02-09) diff --git a/setup.py b/setup.py index fd2a81a1..09b780c1 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.13.1" +version = "1.14.0" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From 923ab31e4685b47acae793198be55335e5eeae38 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 26 Feb 2021 09:52:23 -0800 Subject: [PATCH 06/33] fix: install the wheel dependency (#197) --- .github/workflows/pypi-upload.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pypi-upload.yaml b/.github/workflows/pypi-upload.yaml index 28ae777e..05545359 100644 --- a/.github/workflows/pypi-upload.yaml +++ b/.github/workflows/pypi-upload.yaml @@ -14,7 +14,7 @@ jobs: with: python-version: '3.x' - name: Install dependencies - run: python -m pip install twine + run: python -m pip install twine wheel - name: Package and upload modulee env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} From 9fcf8569a6edc4f623791bcd6f14392721d06470 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 26 Feb 2021 09:56:04 -0800 Subject: [PATCH 07/33] chore: release 1.14.1 (#198) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb13f4b..918571f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [1.14.1](https://www.github.com/googleapis/proto-plus-python/compare/v1.14.0...v1.14.1) (2021-02-26) + + +### Bug Fixes + +* install the wheel dependency ([#197](https://www.github.com/googleapis/proto-plus-python/issues/197)) ([923ab31](https://www.github.com/googleapis/proto-plus-python/commit/923ab31e4685b47acae793198be55335e5eeae38)) + ## [1.14.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.13.1...v1.14.0) (2021-02-24) diff --git a/setup.py b/setup.py index 09b780c1..447da7b7 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.14.0" +version = "1.14.1" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From babdc5cddf08235cac3cda66200babab44204688 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 26 Feb 2021 15:23:46 -0800 Subject: [PATCH 08/33] fix: use the correct environment for uploading to pypi (#199) --- .github/workflows/pypi-upload.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pypi-upload.yaml b/.github/workflows/pypi-upload.yaml index 05545359..60e1bd3c 100644 --- a/.github/workflows/pypi-upload.yaml +++ b/.github/workflows/pypi-upload.yaml @@ -7,6 +7,7 @@ on: jobs: publish: runs-on: ubuntu-latest + environment: PyPI steps: - uses: actions/checkout@v2 - name: Set up Python From 03653da22d5a4e9c9db1596cc99dbf696c15f6a3 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 26 Feb 2021 15:25:22 -0800 Subject: [PATCH 09/33] chore: release 1.14.2 (#200) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 918571f4..20d712c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [1.14.2](https://www.github.com/googleapis/proto-plus-python/compare/v1.14.1...v1.14.2) (2021-02-26) + + +### Bug Fixes + +* use the correct environment for uploading to pypi ([#199](https://www.github.com/googleapis/proto-plus-python/issues/199)) ([babdc5c](https://www.github.com/googleapis/proto-plus-python/commit/babdc5cddf08235cac3cda66200babab44204688)) + ### [1.14.1](https://www.github.com/googleapis/proto-plus-python/compare/v1.14.0...v1.14.1) (2021-02-26) diff --git a/setup.py b/setup.py index 447da7b7..813adb9d 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.14.1" +version = "1.14.2" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From 2a10bbecaf8955c7bf1956086aef42630112788b Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Wed, 3 Mar 2021 17:00:12 -0800 Subject: [PATCH 10/33] fix: adding enums to a repeated field does not raise a TypeError (#202) Fixes issue #201, where enums added to a repeated field triggered a TypeError because they were coverted to integers during marshaling. --- proto/marshal/collections/repeated.py | 2 +- tests/test_marshal_strict.py | 24 ++++++++++++++++++++ tests/test_marshal_types_enum.py | 32 +++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/test_marshal_strict.py diff --git a/proto/marshal/collections/repeated.py b/proto/marshal/collections/repeated.py index 30fa68d0..01b5d2fd 100644 --- a/proto/marshal/collections/repeated.py +++ b/proto/marshal/collections/repeated.py @@ -174,5 +174,5 @@ def __setitem__(self, key, value): def insert(self, index: int, value): """Insert ``value`` in the sequence before ``index``.""" - pb_value = self._marshal.to_proto(self._pb_type, value, strict=True) + pb_value = self._marshal.to_proto(self._pb_type, value) self.pb.insert(index, pb_value) diff --git a/tests/test_marshal_strict.py b/tests/test_marshal_strict.py new file mode 100644 index 00000000..75e2f05d --- /dev/null +++ b/tests/test_marshal_strict.py @@ -0,0 +1,24 @@ +# 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 +from proto.marshal.marshal import BaseMarshal +import pytest + + +def test_strict_to_proto(): + m = BaseMarshal() + + with pytest.raises(TypeError): + m.to_proto(dict, None, strict=True) diff --git a/tests/test_marshal_types_enum.py b/tests/test_marshal_types_enum.py index 1d302053..6cd348c3 100644 --- a/tests/test_marshal_types_enum.py +++ b/tests/test_marshal_types_enum.py @@ -58,3 +58,35 @@ class Foo(proto.Enum): with mock.patch.object(warnings, "warn") as warn: assert enum_rule.to_python(4) == 4 warn.assert_called_once_with("Unrecognized Foo enum value: 4") + + +def test_enum_append(): + class Bivalve(proto.Enum): + CLAM = 0 + OYSTER = 1 + + class MolluscContainer(proto.Message): + bivalves = proto.RepeatedField(proto.ENUM, number=1, enum=Bivalve,) + + mc = MolluscContainer() + clam = Bivalve.CLAM + mc.bivalves.append(clam) + mc.bivalves.append(1) + + assert mc.bivalves == [clam, Bivalve.OYSTER] + + +def test_enum_map_insert(): + class Bivalve(proto.Enum): + CLAM = 0 + OYSTER = 1 + + class MolluscContainer(proto.Message): + bivalves = proto.MapField(proto.STRING, proto.ENUM, number=1, enum=Bivalve,) + + mc = MolluscContainer() + clam = Bivalve.CLAM + mc.bivalves["clam"] = clam + mc.bivalves["oyster"] = 1 + + assert mc.bivalves == {"clam": clam, "oyster": Bivalve.OYSTER} From 8e6f0e5c09e0f40eec52da051084a5a7bdd2b812 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 4 Mar 2021 13:12:10 -0700 Subject: [PATCH 11/33] chore: release 1.14.3 (#203) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d712c9..9cbaddca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [1.14.3](https://www.github.com/googleapis/proto-plus-python/compare/v1.14.2...v1.14.3) (2021-03-04) + + +### Bug Fixes + +* adding enums to a repeated field does not raise a TypeError ([#202](https://www.github.com/googleapis/proto-plus-python/issues/202)) ([2a10bbe](https://www.github.com/googleapis/proto-plus-python/commit/2a10bbecaf8955c7bf1956086aef42630112788b)) + ### [1.14.2](https://www.github.com/googleapis/proto-plus-python/compare/v1.14.1...v1.14.2) (2021-02-26) diff --git a/setup.py b/setup.py index 813adb9d..f446e4b7 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.14.2" +version = "1.14.3" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From 03a90b0d728d71a33f6cf94685ffed96714afdf6 Mon Sep 17 00:00:00 2001 From: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> Date: Thu, 4 Mar 2021 14:10:09 -0700 Subject: [PATCH 12/33] chore: edit required status checks (#204) Editing to match the names of the GH Actions checks --- .github/sync-repo-settings.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index a1cc91e1..a545722c 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -7,7 +7,13 @@ branchProtectionRules: requiredStatusCheckContexts: - 'style-check' - 'docs' - - 'unit' + - 'unit (3.6)' + - 'unit (3.6, cpp)' + - 'unit (3.7)' + - 'unit (3.7, cpp)' + - 'unit (3.8)' + - 'unit (3.9, cpp)' + - 'unit (3.9)' - 'cla/google' requiredApprovingReviewCount: 1 requiresCodeOwnerReviews: true From 8e76e614a31a378fd339c9ed615940689a864c9f Mon Sep 17 00:00:00 2001 From: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> Date: Wed, 10 Mar 2021 11:44:04 -0700 Subject: [PATCH 13/33] chore: remove the circleci badge (#206) --- README.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 140248c0..08ec2bd9 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ Proto Plus for Python ===================== -|pypi| |release level| |ci| |docs| |codecov| +|pypi| |release level| |docs| |codecov| Beautiful, Pythonic protocol buffers. @@ -26,7 +26,5 @@ Documentation :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/ -.. |ci| image:: https://circleci.com/gh/googleapis/proto-plus-python.svg?style=shield - :target: https://circleci.com/gh/googleapis/proto-plus-python .. |codecov| image:: https://codecov.io/gh/googleapis/proto-plus-python/graph/badge.svg :target: https://codecov.io/gh/googleapis/proto-plus-python From 6d4d71399f494b9f3bd47b6f3ef0b6d3c0c547b5 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Wed, 10 Mar 2021 13:34:32 -0800 Subject: [PATCH 14/33] feat: allow_alias for enums (#207) Certain APIs, e.g. recommendationengine, have enums where variants are aliased, i.e. different names map to the same integer value. Allowing this behavior in proto plus for the cpp protobuf runtime requires constructing and passing the correct options. --- .github/sync-repo-settings.yaml | 2 +- proto/enums.py | 16 ++++++++++++++ tests/test_fields_enum.py | 39 +++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index a545722c..d5b332af 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -12,7 +12,7 @@ branchProtectionRules: - 'unit (3.7)' - 'unit (3.7, cpp)' - 'unit (3.8)' - - 'unit (3.9, cpp)' + # - 'unit (3.9, cpp)' # Don't have binary wheels for 3.9 cpp protobuf yet - 'unit (3.9)' - 'cla/google' requiredApprovingReviewCount: 1 diff --git a/proto/enums.py b/proto/enums.py index 22e8f42d..1fe8746f 100644 --- a/proto/enums.py +++ b/proto/enums.py @@ -47,6 +47,21 @@ def __new__(mcls, name, bases, attrs): filename = _file_info._FileInfo.proto_file_name( attrs.get("__module__", name.lower()) ) + + # Retrieve any enum options. + # We expect something that looks like an EnumOptions message, + # either an actual instance or a dict-like representation. + pb_options = "_pb_options" + opts = attrs.pop(pb_options, {}) + # This is the only portable way to remove the _pb_options name + # from the enum attrs. + # In 3.7 onwards, we can define an _ignore_ attribute and do some + # mucking around with that. + if pb_options in attrs._member_names: + idx = attrs._member_names.index(pb_options) + attrs._member_names.pop(idx) + + # Make the descriptor. enum_desc = descriptor_pb2.EnumDescriptorProto( name=name, # Note: the superclass ctor removes the variants, so get them now. @@ -60,6 +75,7 @@ def __new__(mcls, name, bases, attrs): ), key=lambda v: v.number, ), + options=opts, ) file_info = _file_info._FileInfo.maybe_add_descriptor(filename, package) diff --git a/tests/test_fields_enum.py b/tests/test_fields_enum.py index eeeab325..e5d5b324 100644 --- a/tests/test_fields_enum.py +++ b/tests/test_fields_enum.py @@ -12,7 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import proto +import pytest import sys @@ -353,3 +355,40 @@ class Task(proto.Message): t = Task(weekday="TUESDAY") t2 = Task.deserialize(Task.serialize(t)) 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. + # For the python runtime, aliases are allowed by default, but we want to + # make sure that the options don't cause problems. + # For the cpp runtime, we need to verify that we can in fact define aliases. + class GoodMessage(proto.Message): + class GoodEnum(proto.Enum): + _pb_options = {"allow_alias": True} + UNKNOWN = 0 + DEFAULT = 0 + + good_dup_enum = proto.Field(proto.ENUM, number=1, enum=GoodEnum) + + assert GoodMessage.GoodEnum.UNKNOWN == GoodMessage.GoodEnum.DEFAULT == 0 From 36c0c56cbbdbbeea227baad5896c94e2a2355daf Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 10 Mar 2021 13:38:41 -0800 Subject: [PATCH 15/33] chore: release 1.15.0 (#208) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cbaddca..42fb1ed7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.15.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.14.3...v1.15.0) (2021-03-10) + + +### Features + +* allow_alias for enums ([#207](https://www.github.com/googleapis/proto-plus-python/issues/207)) ([6d4d713](https://www.github.com/googleapis/proto-plus-python/commit/6d4d71399f494b9f3bd47b6f3ef0b6d3c0c547b5)) + ### [1.14.3](https://www.github.com/googleapis/proto-plus-python/compare/v1.14.2...v1.14.3) (2021-03-04) diff --git a/setup.py b/setup.py index f446e4b7..b445ef9c 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.14.3" +version = "1.15.0" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From 7675a0c8d1004f2727d64100527f2b208d305017 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 12 Mar 2021 10:08:16 -0800 Subject: [PATCH 16/33] feat: add preserving_proto_field_name passthrough in MessageMeta.to_dict (#211) --- proto/message.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/proto/message.py b/proto/message.py index abb8f635..8ed2a69a 100644 --- a/proto/message.py +++ b/proto/message.py @@ -369,7 +369,9 @@ def from_json(cls, payload, *, ignore_unknown_fields=False) -> "Message": Parse(payload, instance._pb, ignore_unknown_fields=ignore_unknown_fields) return instance - def to_dict(cls, instance, *, use_integers_for_enums=True) -> "Message": + def to_dict( + cls, instance, *, use_integers_for_enums=True, preserving_proto_field_name=True + ) -> "Message": """Given a message instance, return its representation as a python dict. Args: @@ -378,6 +380,9 @@ def to_dict(cls, instance, *, use_integers_for_enums=True) -> "Message": use_integers_for_enums (Optional(bool)): An option that determines whether enum values should be represented by strings (False) or integers (True). Default is True. + preserving_proto_field_name (Optional(bool)): An option that + determines whether field name representations preserve + proto case (snake_case) or use lowerCamelCase. Default is True. Returns: dict: A representation of the protocol buffer using pythonic data structures. @@ -387,7 +392,7 @@ def to_dict(cls, instance, *, use_integers_for_enums=True) -> "Message": return MessageToDict( cls.pb(instance), including_default_value_fields=True, - preserving_proto_field_name=True, + preserving_proto_field_name=preserving_proto_field_name, use_integers_for_enums=use_integers_for_enums, ) From 5abbbdfb789c2ba0560d24c976f927341a3386f9 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 12 Mar 2021 10:19:56 -0800 Subject: [PATCH 17/33] chore: use repository secrets for pypi upload (#210) This is coupled with a behind the scenes change to the repository secrets. --- .github/workflows/pypi-upload.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/pypi-upload.yaml b/.github/workflows/pypi-upload.yaml index 60e1bd3c..05545359 100644 --- a/.github/workflows/pypi-upload.yaml +++ b/.github/workflows/pypi-upload.yaml @@ -7,7 +7,6 @@ on: jobs: publish: runs-on: ubuntu-latest - environment: PyPI steps: - uses: actions/checkout@v2 - name: Set up Python From f39c196cc59677b6d4400a71578f86ae5ecf998f Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 12 Mar 2021 10:25:47 -0800 Subject: [PATCH 18/33] chore: use repository secrets for pypi upload (#210) This is coupled with a behind the scenes change to the repository secrets. From 4799f74ac039f74590825985452e80b2c0013620 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 12 Mar 2021 10:30:06 -0800 Subject: [PATCH 19/33] chore: use repository secrets for pypi upload (#210) This is coupled with a behind the scenes change to the repository secrets. From ad35c19e3b119a7ad68529fbd9bbd83c50e7aa81 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 12 Mar 2021 11:01:59 -0800 Subject: [PATCH 20/33] chore: release 1.16.0 (#212) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Dov Shlachter --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42fb1ed7..4db46b5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.16.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.15.0...v1.16.0) (2021-03-12) + + +### Features + +* add preserving_proto_field_name passthrough in MessageMeta.to_dict ([#211](https://www.github.com/googleapis/proto-plus-python/issues/211)) ([7675a0c](https://www.github.com/googleapis/proto-plus-python/commit/7675a0c8d1004f2727d64100527f2b208d305017)) + ## [1.15.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.14.3...v1.15.0) (2021-03-10) diff --git a/setup.py b/setup.py index b445ef9c..f6975fa0 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.15.0" +version = "1.16.0" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From b2c245bf044b964897f4e7423ff4944ae915e469 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Fri, 12 Mar 2021 14:52:02 -0800 Subject: [PATCH 21/33] feat: add preserving_proto_field_name to to_json (#213) --- proto/message.py | 9 +++++++-- tests/test_json.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/proto/message.py b/proto/message.py index 8ed2a69a..68e5bb0a 100644 --- a/proto/message.py +++ b/proto/message.py @@ -332,7 +332,8 @@ def to_json( instance, *, use_integers_for_enums=True, - including_default_value_fields=True + including_default_value_fields=True, + preserving_proto_field_name=False, ) -> str: """Given a message instance, serialize it to json @@ -342,6 +343,9 @@ def to_json( use_integers_for_enums (Optional(bool)): An option that determines whether enum values should be represented by strings (False) or integers (True). Default is True. + preserving_proto_field_name (Optional(bool)): An option that + determines whether field name representations preserve + proto case (snake_case) or use lowerCamelCase. Default is False. Returns: str: The json string representation of the protocol buffer. @@ -350,6 +354,7 @@ def to_json( cls.pb(instance), use_integers_for_enums=use_integers_for_enums, including_default_value_fields=including_default_value_fields, + preserving_proto_field_name=preserving_proto_field_name, ) def from_json(cls, payload, *, ignore_unknown_fields=False) -> "Message": @@ -620,7 +625,7 @@ def __init__( package: str, full_name: str, marshal: Marshal, - options: descriptor_pb2.MessageOptions + options: descriptor_pb2.MessageOptions, ) -> None: self.package = package self.full_name = full_name diff --git a/tests/test_json.py b/tests/test_json.py index 4b7be8be..d1cbc1fb 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -136,3 +136,15 @@ class Octopus(proto.Message): # Don't permit unknown fields by default with pytest.raises(ParseError): o = Octopus.from_json(json_str) + + +def test_json_snake_case(): + class Squid(proto.Message): + mass_kg = proto.Field(proto.INT32, number=1) + + json_str = '{\n "mass_kg": 20\n}' + s = Squid.from_json(json_str) + + assert s.mass_kg == 20 + + assert Squid.to_json(s, preserving_proto_field_name=True) == json_str From 521f33deb2d08b1a3fe1754489fcfbfc4e446e3c Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 12 Mar 2021 23:00:06 +0000 Subject: [PATCH 22/33] chore: release 1.17.0 (#214) :robot: I have created a release \*beep\* \*boop\* --- ## [1.17.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.16.0...v1.17.0) (2021-03-12) ### Features * add preserving_proto_field_name to to_json ([#213](https://www.github.com/googleapis/proto-plus-python/issues/213)) ([b2c245b](https://www.github.com/googleapis/proto-plus-python/commit/b2c245bf044b964897f4e7423ff4944ae915e469)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4db46b5f..98d229d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.17.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.16.0...v1.17.0) (2021-03-12) + + +### Features + +* add preserving_proto_field_name to to_json ([#213](https://www.github.com/googleapis/proto-plus-python/issues/213)) ([b2c245b](https://www.github.com/googleapis/proto-plus-python/commit/b2c245bf044b964897f4e7423ff4944ae915e469)) + ## [1.16.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.15.0...v1.16.0) (2021-03-12) diff --git a/setup.py b/setup.py index f6975fa0..cb6384a8 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.16.0" +version = "1.17.0" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From 11c3e58a9ba59f0d7d808a26597dab735ca982ba Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Tue, 16 Mar 2021 12:14:34 -0700 Subject: [PATCH 23/33] feat: add copy_from method for field assignment (#215) Because of implementation detatils of the underlying protocol buffers runtime, assigning to a proto-plus message field is achieved by copying, not by updating references. This can lead to surprising and unintuitive behavior for developers who are expecting python object behavior, e.g. reference aliases. This PR adds a 'Message.copy_from' method that is semantically identical to regular assignment. This can be used at the discretion of the developer to clarify expected behavior. --- docs/messages.rst | 68 ++++++++++++++++++++++++++++++++++++++ docs/reference/message.rst | 2 +- proto/message.py | 32 +++++++++++++++++- tests/test_message.py | 24 ++++++++++++++ 4 files changed, 124 insertions(+), 2 deletions(-) diff --git a/docs/messages.rst b/docs/messages.rst index af23ea9d..e7861b04 100644 --- a/docs/messages.rst +++ b/docs/messages.rst @@ -80,6 +80,74 @@ Instantiate messages using either keyword arguments or a :class:`dict` >>> song.title 'Canon in D' + +Assigning to Fields +------------------- + +One of the goals of proto-plus is to make protobufs feel as much like regular python +objects as possible. It is possible to update a message's field by assigning to it, +just as if it were a regular python object. + +.. code-block:: python + + song = Song() + song.composer = Composer(given_name="Johann", family_name="Bach") + + # Can also assign from a dictionary as a convenience. + song.composer = {"given_name": "Claude", "family_name": "Debussy"} + + # Repeated fields can also be assigned + class Album(proto.Message): + songs = proto.RepeatedField(Song, number=1) + + a = Album() + songs = [Song(title="Canon in D"), Song(title="Little Fugue")] + a.songs = songs + +.. note:: + + Assigning to a proto-plus message field works by making copies, not by updating references. + This is necessary because of memory layout requirements of protocol buffers. + These memory constraints are maintained by the protocol buffers runtime. + This behavior can be surprising under certain circumstances, e.g. trying to save + an alias to a nested field. + + :class:`proto.Message` defines a helper message, :meth:`~.Message.copy_from` to + help make the distinction clear when reading code. + The semantics of :meth:`~.Message.copy_from` are identical to the field assignment behavior described above. + + .. code-block:: python + + composer = Composer(given_name="Johann", family_name="Bach") + song = Song(title="Tocatta and Fugue in D Minor", composer=composer) + composer.given_name = "Wilhelm" + + # 'composer' is NOT a reference to song.composer + assert song.composer.given_name == "Johann" + + # We CAN update the song's composer by assignment. + song.composer = composer + composer.given_name = "Carl" + + # 'composer' is STILL not a referene to song.composer. + assert song.composer.given_name == "Wilhelm" + + # It does work in reverse, though, + # if we want a reference we can access then update. + composer = song.composer + composer.given_name = "Gottfried" + + assert song.composer.given_name == "Gottfried" + + # We can use 'copy_from' if we're concerned that the code + # implies that assignment involves references. + composer = Composer(given_name="Elisabeth", family_name="Bach") + # We could also do Message.copy_from(song.composer, composer) instead. + Composer.copy_from(song.composer, composer) + + assert song.composer.given_name == "Elisabeth" + + Enums ----- diff --git a/docs/reference/message.rst b/docs/reference/message.rst index 34da8376..436b0c81 100644 --- a/docs/reference/message.rst +++ b/docs/reference/message.rst @@ -11,7 +11,7 @@ Message and Field .. automethod:: to_json .. automethod:: from_json .. automethod:: to_dict - + .. automethod:: copy_from .. automodule:: proto.fields :members: diff --git a/proto/message.py b/proto/message.py index 68e5bb0a..e046d628 100644 --- a/proto/message.py +++ b/proto/message.py @@ -401,6 +401,36 @@ def to_dict( use_integers_for_enums=use_integers_for_enums, ) + def copy_from(cls, instance, other): + """Equivalent for protobuf.Message.CopyFrom + + Args: + instance: An instance of this message type + other: (Union[dict, ~.Message): + A dictionary or message to reinitialize the values for this message. + """ + if isinstance(other, cls): + # Just want the underlying proto. + other = Message.pb(other) + elif isinstance(other, cls.pb()): + # Don't need to do anything. + pass + elif isinstance(other, collections.abc.Mapping): + # Coerce into a proto + other = cls._meta.pb(**other) + else: + raise TypeError( + "invalid argument type to copy to {}: {}".format( + cls.__name__, other.__class__.__name__ + ) + ) + + # Note: we can't just run self.__init__ because this may be a message field + # for a higher order proto; the memory layout for protos is NOT LIKE the + # python memory model. We cannot rely on just setting things by reference. + # Non-trivial complexity is (partially) hidden by the protobuf runtime. + cls.pb(instance).CopyFrom(other) + class Message(metaclass=MessageMeta): """The abstract base class for a message. @@ -436,7 +466,7 @@ def __init__(self, mapping=None, *, ignore_unknown_fields=False, **kwargs): # # The `wrap` method on the metaclass is the public API for taking # ownership of the passed in protobuf objet. - mapping = copy.copy(mapping) + mapping = copy.deepcopy(mapping) if kwargs: mapping.MergeFrom(self._meta.pb(**kwargs)) diff --git a/tests/test_message.py b/tests/test_message.py index b723fcde..a77f554a 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -317,3 +317,27 @@ class Squid(proto.Message): s = Squid({"mass_kg": 20, "length_cm": 100}, ignore_unknown_fields=True) assert not hasattr(s, "length_cm") + + +def test_copy_from(): + class Mollusc(proto.Message): + class Squid(proto.Message): + mass_kg = proto.Field(proto.INT32, number=1) + + squid = proto.Field(Squid, number=1) + + m = Mollusc() + s = Mollusc.Squid(mass_kg=20) + Mollusc.Squid.copy_from(m.squid, s) + assert m.squid is not s + assert m.squid == s + + s.mass_kg = 30 + Mollusc.Squid.copy_from(m.squid, Mollusc.Squid.pb(s)) + assert m.squid == s + + Mollusc.Squid.copy_from(m.squid, {"mass_kg": 10}) + assert m.squid.mass_kg == 10 + + with pytest.raises(TypeError): + Mollusc.Squid.copy_from(m.squid, (("mass_kg", 20))) From 5c74cf439ddc2c08b2691c9aebdcdac24f502184 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Tue, 16 Mar 2021 19:18:02 +0000 Subject: [PATCH 24/33] chore: release 1.18.0 (#216) :robot: I have created a release \*beep\* \*boop\* --- ## [1.18.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.17.0...v1.18.0) (2021-03-16) ### Features * add copy_from method for field assignment ([#215](https://www.github.com/googleapis/proto-plus-python/issues/215)) ([11c3e58](https://www.github.com/googleapis/proto-plus-python/commit/11c3e58a9ba59f0d7d808a26597dab735ca982ba)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98d229d9..23d1c644 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.18.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.17.0...v1.18.0) (2021-03-16) + + +### Features + +* add copy_from method for field assignment ([#215](https://www.github.com/googleapis/proto-plus-python/issues/215)) ([11c3e58](https://www.github.com/googleapis/proto-plus-python/commit/11c3e58a9ba59f0d7d808a26597dab735ca982ba)) + ## [1.17.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.16.0...v1.17.0) (2021-03-12) diff --git a/setup.py b/setup.py index cb6384a8..b4914d2e 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.17.0" +version = "1.18.0" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From c9667c22d0b8f6026dbf69d502eb8eb972279891 Mon Sep 17 00:00:00 2001 From: odidev Date: Fri, 19 Mar 2021 23:44:28 +0530 Subject: [PATCH 25/33] fix: Add arm64 support for PY3.6 (#219) Build with python3.6 using protobuf v3.12.0. Its wheel and source tar are not available for arm64 to build from source. So upgraded protobuf to recent version having source tar. Signed-off-by: odidev --- testing/constraints-3.6.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt index f7365f65..31111ae4 100644 --- a/testing/constraints-3.6.txt +++ b/testing/constraints-3.6.txt @@ -5,5 +5,5 @@ # # e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", # Then this file should have foo==1.14.0 -protobuf==3.12.0 -google-api-core==1.22.2 \ No newline at end of file +protobuf==3.15.6 +google-api-core==1.22.2 From cfd5b6caca3fa9add89d8c69ea620505dd90dd7c Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 19 Mar 2021 15:13:02 -0700 Subject: [PATCH 26/33] chore: release 1.18.1 (#220) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23d1c644..81f2c4a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### [1.18.1](https://www.github.com/googleapis/proto-plus-python/compare/v1.18.0...v1.18.1) (2021-03-19) + + +### Bug Fixes + +* Add arm64 support for PY3.6 ([#219](https://www.github.com/googleapis/proto-plus-python/issues/219)) ([c9667c2](https://www.github.com/googleapis/proto-plus-python/commit/c9667c22d0b8f6026dbf69d502eb8eb972279891)) + ## [1.18.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.17.0...v1.18.0) (2021-03-16) diff --git a/setup.py b/setup.py index b4914d2e..df4fa964 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.18.0" +version = "1.18.1" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From cb4d480502501db3cba98c217885c86e87465f95 Mon Sep 17 00:00:00 2001 From: WhiteSource Renovate Date: Mon, 12 Apr 2021 22:59:27 +0200 Subject: [PATCH 27/33] chore(deps): update styfle/cancel-workflow-action action to v0.9.0 (#225) --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b64a7462..7da71521 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.8.0 + uses: styfle/cancel-workflow-action@0.9.0 with: access_token: ${{ github.token }} - uses: actions/checkout@v2 @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.8.0 + uses: styfle/cancel-workflow-action@0.9.0 with: access_token: ${{ github.token }} - uses: actions/checkout@v2 @@ -54,7 +54,7 @@ jobs: variant: cpp steps: - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.8.0 + uses: styfle/cancel-workflow-action@0.9.0 with: access_token: ${{ github.token }} - uses: actions/checkout@v2 From 64642c9ddc7cbc0a7e1c55633f5e65960d9379e9 Mon Sep 17 00:00:00 2001 From: Dan Lee <71398022+dandhlee@users.noreply.github.com> Date: Fri, 16 Apr 2021 17:27:57 -0400 Subject: [PATCH 28/33] chore: prevent normalization of semver versioning (#227) * chore: prevent normalization of semver versioning * chore: update style for consistency * chore: update workaround to make sic work --- setup.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index df4fa964..15062ffb 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,22 @@ import io import os -from setuptools import find_packages, setup +import setuptools + +# Disable version normalization performed by setuptools.setup() +try: + # Try the approach of using sic(), added in setuptools 46.1.0 + from setuptools import sic +except ImportError: + # Try the approach of replacing packaging.version.Version + sic = lambda v: v + try: + # setuptools >=39.0.0 uses packaging from setuptools.extern + from setuptools.extern import packaging + except ImportError: + # setuptools <39.0.0 uses packaging from pkg_resources.extern + from pkg_resources.extern import packaging + packaging.version.Version = packaging.version.LegacyVersion version = "1.18.1" @@ -24,14 +39,14 @@ with io.open(os.path.join(PACKAGE_ROOT, "README.rst")) as file_obj: README = file_obj.read() -setup( +setuptools.setup( name="proto-plus", - version=version, + version=sic(version), license="Apache 2.0", author="Google LLC", author_email="googleapis-packages@google.com", url="https://github.com/googleapis/proto-plus-python.git", - packages=find_packages(exclude=["docs", "tests"]), + packages=setuptools.find_packages(exclude=["docs", "tests"]), description="Beautiful, Pythonic protocol buffers.", long_description=README, platforms="Posix; MacOS X", From c6c4c52ac9ec9fdbb75f6bf644162d8a2f0fe9e3 Mon Sep 17 00:00:00 2001 From: Dan Lee <71398022+dandhlee@users.noreply.github.com> Date: Fri, 23 Apr 2021 19:13:57 -0400 Subject: [PATCH 29/33] chore(revert): revert preventing normalization (#228) --- setup.py | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/setup.py b/setup.py index 15062ffb..df4fa964 100644 --- a/setup.py +++ b/setup.py @@ -15,22 +15,7 @@ import io import os -import setuptools - -# Disable version normalization performed by setuptools.setup() -try: - # Try the approach of using sic(), added in setuptools 46.1.0 - from setuptools import sic -except ImportError: - # Try the approach of replacing packaging.version.Version - sic = lambda v: v - try: - # setuptools >=39.0.0 uses packaging from setuptools.extern - from setuptools.extern import packaging - except ImportError: - # setuptools <39.0.0 uses packaging from pkg_resources.extern - from pkg_resources.extern import packaging - packaging.version.Version = packaging.version.LegacyVersion +from setuptools import find_packages, setup version = "1.18.1" @@ -39,14 +24,14 @@ with io.open(os.path.join(PACKAGE_ROOT, "README.rst")) as file_obj: README = file_obj.read() -setuptools.setup( +setup( name="proto-plus", - version=sic(version), + version=version, license="Apache 2.0", author="Google LLC", author_email="googleapis-packages@google.com", url="https://github.com/googleapis/proto-plus-python.git", - packages=setuptools.find_packages(exclude=["docs", "tests"]), + packages=find_packages(exclude=["docs", "tests"]), description="Beautiful, Pythonic protocol buffers.", long_description=README, platforms="Posix; MacOS X", From e25dd7d65273a834f66d3be0445b88011103dc81 Mon Sep 17 00:00:00 2001 From: "google-cloud-policy-bot[bot]" <80869356+google-cloud-policy-bot[bot]@users.noreply.github.com> Date: Wed, 28 Apr 2021 09:58:58 -0700 Subject: [PATCH 30/33] chore: add SECURITY.md (#229) Co-authored-by: google-cloud-policy-bot[bot] <80869356+google-cloud-policy-bot[bot]@users.noreply.github.com> --- SECURITY.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..8b58ae9c --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). + +The Google Security Team will respond within 5 working days of your report on g.co/vulnz. + +We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. From 15c2f479f81f0f80d451ca9b043e42cecfe7184e Mon Sep 17 00:00:00 2001 From: vishwaja13 <26506063+vishwaja13@users.noreply.github.com> Date: Tue, 29 Jun 2021 22:08:37 +0530 Subject: [PATCH 31/33] feat: pass 'including_default_value_fields' through to 'Message.to_dict' method (#232) Solution to the following issue #231, should work as boolean value and according to the value the GoogleAdsRow default columns should or should not return in results. If including_default_value_fields is False default columns should not return and if True default values should return now. Closes #231. --- proto/message.py | 12 ++++++++++-- tests/test_message.py | 5 +++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/proto/message.py b/proto/message.py index e046d628..00ec4cc7 100644 --- a/proto/message.py +++ b/proto/message.py @@ -375,7 +375,12 @@ def from_json(cls, payload, *, ignore_unknown_fields=False) -> "Message": return instance def to_dict( - cls, instance, *, use_integers_for_enums=True, preserving_proto_field_name=True + cls, + instance, + *, + use_integers_for_enums=True, + preserving_proto_field_name=True, + including_default_value_fields=True, ) -> "Message": """Given a message instance, return its representation as a python dict. @@ -388,6 +393,9 @@ def to_dict( preserving_proto_field_name (Optional(bool)): An option that 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. + Default is True. Returns: dict: A representation of the protocol buffer using pythonic data structures. @@ -396,7 +404,7 @@ def to_dict( """ return MessageToDict( cls.pb(instance), - including_default_value_fields=True, + including_default_value_fields=including_default_value_fields, preserving_proto_field_name=preserving_proto_field_name, use_integers_for_enums=use_integers_for_enums, ) diff --git a/tests/test_message.py b/tests/test_message.py index a77f554a..5351dbd7 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -262,6 +262,11 @@ class Color(proto.Enum): s_dict = Squid.to_dict(s, use_integers_for_enums=False) assert s_dict["chromatophores"][0]["color"] == "RED" + s_new_2 = Squid(mass_kg=20) + s_dict_2 = Squid.to_dict(s_new_2, including_default_value_fields=False) + expected_dict = {"mass_kg": 20} + assert s_dict_2 == expected_dict + new_s = Squid(s_dict) assert new_s == s From 6cb2a4eddfdcc1f0bedcdac81e8b66170638eeea Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Tue, 29 Jun 2021 09:42:01 -0700 Subject: [PATCH 32/33] chore: release 1.19.0 (#233) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81f2c4a9..eaf77f1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.19.0](https://www.github.com/googleapis/proto-plus-python/compare/v1.18.1...v1.19.0) (2021-06-29) + + +### Features + +* pass 'including_default_value_fields' through to 'Message.to_dict' method ([#232](https://www.github.com/googleapis/proto-plus-python/issues/232)) ([15c2f47](https://www.github.com/googleapis/proto-plus-python/commit/15c2f479f81f0f80d451ca9b043e42cecfe7184e)) + ### [1.18.1](https://www.github.com/googleapis/proto-plus-python/compare/v1.18.0...v1.18.1) (2021-03-19) diff --git a/setup.py b/setup.py index df4fa964..b6bc503a 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from setuptools import find_packages, setup -version = "1.18.1" +version = "1.19.0" PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__)) From 360d24783db123f01703640202459eb922cf4974 Mon Sep 17 00:00:00 2001 From: Dov Shlachter Date: Tue, 29 Jun 2021 09:46:23 -0700 Subject: [PATCH 33/33] chore: enable cpp tests for 3.9 (#234) Binary wheels for protoc for python 3.9 have been published, so the corresponding unit tests should be enabled. --- .github/workflows/tests.yml | 4 ---- noxfile.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7da71521..93d7308a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -48,10 +48,6 @@ jobs: matrix: python: [3.6, 3.7, 3.8, 3.9] variant: ['', cpp] - # Note: as of 2021-02-09, there are no 3.9 python wheels for protobuf/grpc - exclude: - - python: 3.9 - variant: cpp steps: - name: Cancel Previous Runs uses: styfle/cancel-workflow-action@0.9.0 diff --git a/noxfile.py b/noxfile.py index 0ed6caa7..1ca07cec 100644 --- a/noxfile.py +++ b/noxfile.py @@ -54,7 +54,7 @@ def unit(session, proto="python"): # Check if protobuf has released wheels for new python versions # https://pypi.org/project/protobuf/#files # This list will generally be shorter than 'unit' -@nox.session(python=["3.6", "3.7", "3.8"]) +@nox.session(python=["3.6", "3.7", "3.8", "3.9"]) def unitcpp(session): return unit(session, proto="cpp")