Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add support for protobuf 5.x #644

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

parthea
Copy link
Collaborator

@parthea parthea commented Apr 27, 2024

Fixes #628 🦕
Fixes #641 🦕
Fixes #642 🦕

Regarding the including_default_value_fields argument of json_format.MessageToDict() in protobuf:

In protobuf version 3.19.6 - The default value of including_default_value_fields was False
https://github.com/protocolbuffers/protobuf/blob/5cba162a5d93f8df786d828621019e03e50edb4f/python/google/protobuf/json_format.py#L92

At the time that the argument was removed in protobuf 5.x - the default value of including_default_value_fields was False
protocolbuffers/protobuf@2699579#diff-8de817c14d6a087981503c9aea38730b1b3e98f4e306db5ff9d525c7c304f234

IOW, setting argument including_default_value_fields to False had no effect as it was the default behaviour.

The Unit tests / unit_prerelease-3.12 presubmit check was added to run tests against the latest pre-release version of protobuf as several dependencies have a constraint on protobuf<5

@product-auto-label product-auto-label bot added the size: m Pull request size is medium. label Apr 27, 2024
@parthea parthea force-pushed the add-support-for-protobuf-5-x branch 7 times, most recently from f8f719b to a650198 Compare April 27, 2024 15:11
@parthea parthea force-pushed the add-support-for-protobuf-5-x branch from a650198 to ac9cad8 Compare April 27, 2024 15:12
@parthea parthea marked this pull request as ready for review April 29, 2024 14:36
@parthea parthea requested review from a team as code owners April 29, 2024 14:36
@parthea parthea added the owlbot:run Add this label to trigger the Owlbot post processor. label Apr 29, 2024
@gcf-owl-bot gcf-owl-bot bot removed the owlbot:run Add this label to trigger the Owlbot post processor. label Apr 29, 2024
@anndro
Copy link

anndro commented May 16, 2024

Hello @parthea is there any scheduled date for release this pull request?

@zhangskz
Copy link

@parthea Is there anything blocking this PR still?

Copy link
Contributor

@vchudnov-g vchudnov-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of suggestions, and some questions, but nothing major. This looks good!

Comment on lines +191 to 207
# For backwards compatibility with protobuf 3.x 4.x
# Remove once support for protobuf 3.x and 4.x is dropped
# https://github.com/googleapis/python-api-core/issues/643
if PROTOBUF_VERSION[0:2] in ["3.", "4."]:
request_kwargs = json_format.MessageToDict(
request,
preserving_proto_field_name=True,
including_default_value_fields=True, # type: ignore # backward compatibility
)
else:
request_kwargs = json_format.MessageToDict(
request,
preserving_proto_field_name=True,
always_print_fields_with_no_presence=True,
)

transcoded_request = path_template.transcode(http_options, **request_kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have this block repeated in four places. I suggest factoring it out into a helper function that only needs to take one parameter:

Suggested change
# For backwards compatibility with protobuf 3.x 4.x
# Remove once support for protobuf 3.x and 4.x is dropped
# https://github.com/googleapis/python-api-core/issues/643
if PROTOBUF_VERSION[0:2] in ["3.", "4."]:
request_kwargs = json_format.MessageToDict(
request,
preserving_proto_field_name=True,
including_default_value_fields=True, # type: ignore # backward compatibility
)
else:
request_kwargs = json_format.MessageToDict(
request,
preserving_proto_field_name=True,
always_print_fields_with_no_presence=True,
)
transcoded_request = path_template.transcode(http_options, **request_kwargs)
transcoded_request = _transcode_request(request)

Comment on lines +137 to +147
if install_grpc:
session.install(
"-e",
".[grpc]",
"-c",
f"{constraints_dir}/constraints-{session.python}.txt",
)
else:
session.install(
"-e", ".", "-c", f"{constraints_dir}/constraints-{session.python}.txt"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more succinct and clearer in highlighting the difference between the two branches, IMO:

Suggested change
if install_grpc:
session.install(
"-e",
".[grpc]",
"-c",
f"{constraints_dir}/constraints-{session.python}.txt",
)
else:
session.install(
"-e", ".", "-c", f"{constraints_dir}/constraints-{session.python}.txt"
)
session.install(
"-e",
".[grpc]" if install_grpc else ".",
"-c",
f"{constraints_dir}/constraints-{session.python}.txt",
)


if prerelease:
install_prerelease_dependencies(
session, f"{constraints_dir}/constraints-{PYTHON_VERSIONS[0]}.txt"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused: in line 206, where we call default(..., prerelease=True), the decorator constrains python=PYTHON_VERSIONS[-1]. But here we are referencing the constraints for PYTHON_VERSIONS[0]. Could you clarify?

@@ -72,17 +76,46 @@ def blacken(session):
session.run("black", *BLACK_EXCLUDES, *BLACK_PATHS)


def default(session, install_grpc=True):
def install_prerelease_dependencies(session, constraints_path):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I have gaps in my mental model for testing prerelease;

This installs our dependencies at pre-release versions, right?

Is the only difference, then, the use of --pre below? If it's the same set of dependencies, it seems it would be clearer to have them loaded in the same place for pre-release and stable versions, and add the extra install parameters conditionally on each thing we install.

(It might be easier to talk synchronously about this.)

def unit(session):
"""Run the unit test suite."""
default(session)


@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"])
@nox.session(python=PYTHON_VERSIONS[-1])
def unit_prerelease(session):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this tests running against the pre-release versions of the dependencies, right? And we only bother to do this with the latest Python run-time.

A comment might be helpful. Also, my personal preference would to rename this (and similar code elsewhere) as unit_with_prerelease_deps. Every time I read something like unit_prerelease my mind first assumes we're testing the pre-release version of this library, not of its dependencies.

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
option: ["", "_grpc_gcp", "_wo_grpc"]
option: ["", "_grpc_gcp", "_wo_grpc", "_prerelease"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this more succinct code should work (I haven't tested it) and would be easier to maintain.
Ref: https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#expanding-or-adding-matrix-configurations

        option: ["", "_grpc_gcp", "_wo_grpc"]
        python:
          - "3.7"
          - "3.8"
          - "3.9"
          - "3.10"
          - "3.11"
          - "3.12"
        exclude:
          - option: "_wo_grpc"
            python: 3.7
          - option: "_wo_grpc"
            python: 3.8
          - option: "_wo_grpc"
            python: 3.9
         include:
          - option: "_prerelease"
            python: 3.12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: m Pull request size is medium.
Projects
None yet
5 participants