-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Api Core: add a method that calculates a fieldmask from two messages #5320
Conversation
from google.protobuf.message import Message | ||
from google.protobuf.descriptor import FieldDescriptor |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
|
||
def fieldmask(original, modified): | ||
"""Constructs a field mask from two proto messages. |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
modified (~google.protobuf.message.Message): the modified message. | ||
|
||
Returns: | ||
FieldMask: returns a FieldMask object representing the differences |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
between made from the original message to the modified message. | ||
|
||
Raises: | ||
ValueError: If the ``original`` or ``modified`` are not subclasses of |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
raise ValueError('The parameters passed must be of the same type.') | ||
answer = [] | ||
seen = [] | ||
for field, _ in original.ListFields(): |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
@@ -0,0 +1,28 @@ | |||
// Copyright 2018 Google LLC |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
c515aca
to
012c70d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks mostly good. We can merge once you address my final comments and we can get CI to pass.
|
||
Returns: | ||
google.protobuf.field_mask_pb2.FieldMask: returns a FieldMask instance | ||
representing the differences between between two messages. |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
ValueError: If the ``original`` or ``modified`` are not the same type. | ||
""" | ||
if type(original) != type(modified): | ||
raise ValueError('fieldmask() expects parameters must be of the same type.') |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Hold off on merging. Working out some details with internal feature requester. |
@@ -247,3 +252,45 @@ def setdefault(msg_or_dict, key, value): | |||
""" | |||
if not get(msg_or_dict, key, default=None): | |||
set(msg_or_dict, key, value) | |||
|
|||
|
|||
def fieldmask(original, modified): |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
UpdateI added an update to support the case where a user simply wants a field mask for every non-zero field by adding the ability to use None as a parameter: Example getting all set fields.from google.api_core import protobuf_helpers
...
# All set fields mask
mask = protobuf_helpers.field_mask(None, Resource)
# And conversely
mask = protobuf_helpers.field_mask(Resource, None) |
Now that I'm working with some examples that require some slightly more sophisticated field masks, I've found an issue with the utility. Consider the following case where we want to update a campaign:
It produces the following CampaignOperation:
Note that the update_mask is incorrect, it includes "network_settings", but this value should really be "network_settings.target_search_network". An API error results, trailing metadata includes the following raw description:
In contrast, setting this manually works as expected:
|
…python into api-core-field-mask
Added a commit that should fix the issues raised by @msaniscalchi. @theacodes can you take another look? |
Thank you, @landrito! |
What
Given two messages of the same type, this function will produce a field mask representing the diffs between the two messages.
Example Usage (with a fictional client)
cc: @jbolinger