File tree Expand file tree Collapse file tree 3 files changed +31
-33
lines changed
Expand file tree Collapse file tree 3 files changed +31
-33
lines changed Original file line number Diff line number Diff line change @@ -34,10 +34,14 @@ def to_proto(self, value):
3434 try :
3535 # Try the fast path first.
3636 return self ._descriptor (** value )
37- except TypeError as ex :
38- # If we have a type error ,
37+ except ( TypeError , ValueError ) as ex :
38+ # If we have a TypeError or Valueerror ,
3939 # try the slow path in case the error
40- # was an int64/string issue
40+ # was:
41+ # - an int64/string issue.
42+ # - a missing key issue in case a key only exists with a `_` suffix.
43+ # See related issue: https://github.com/googleapis/python-api-core/issues/227.
44+ # - a missing key issue due to nested struct. See: b/321905145.
4145 return self ._wrapper (value )._pb
4246 return value
4347
Original file line number Diff line number Diff line change @@ -725,36 +725,7 @@ def __init__(
725725 "Unknown field for {}: {}" .format (self .__class__ .__name__ , key )
726726 )
727727
728- try :
729- pb_value = marshal .to_proto (pb_type , value )
730- except ValueError :
731- # Underscores may be appended to field names
732- # that collide with python or proto-plus keywords.
733- # In case a key only exists with a `_` suffix, coerce the key
734- # to include the `_` suffix. It's not possible to
735- # natively define the same field with a trailing underscore in protobuf.
736- # See related issue
737- # https://github.com/googleapis/python-api-core/issues/227
738- if isinstance (value , dict ):
739- if _upb :
740- # In UPB, pb_type is MessageMeta which doesn't expose attrs like it used to in Python/CPP.
741- keys_to_update = [
742- item
743- for item in value
744- if item not in pb_type .DESCRIPTOR .fields_by_name
745- and f"{ item } _" in pb_type .DESCRIPTOR .fields_by_name
746- ]
747- else :
748- keys_to_update = [
749- item
750- for item in value
751- if not hasattr (pb_type , item )
752- and hasattr (pb_type , f"{ item } _" )
753- ]
754- for item in keys_to_update :
755- value [f"{ item } _" ] = value .pop (item )
756-
757- pb_value = marshal .to_proto (pb_type , value )
728+ pb_value = marshal .to_proto (pb_type , value )
758729
759730 if pb_value is not None :
760731 params [key ] = pb_value
Original file line number Diff line number Diff line change @@ -243,3 +243,26 @@ class Foo(proto.Message):
243243 detached ["bacon" ] = True
244244 foo .value = detached
245245 assert foo .value == {"foo" : "bar" , "bacon" : True }
246+
247+
248+ def test_struct_nested ():
249+ class Foo (proto .Message ):
250+ struct_field : struct_pb2 .Struct = proto .Field (
251+ proto .MESSAGE ,
252+ number = 1 ,
253+ message = struct_pb2 .Struct ,
254+ )
255+
256+ class Bar (proto .Message ):
257+ foo_field : Foo = proto .Field (
258+ proto .MESSAGE ,
259+ number = 1 ,
260+ message = Foo ,
261+ )
262+
263+ foo = Foo ({"struct_field" : {"foo" : "bagel" }})
264+ assert foo .struct_field == {"foo" : "bagel" }
265+
266+ bar = Bar ({"foo_field" : {"struct_field" : {"foo" : "cheese" }}})
267+ assert bar .foo_field == Foo ({"struct_field" : {"foo" : "cheese" }})
268+ assert bar .foo_field .struct_field == {"foo" : "cheese" }
You can’t perform that action at this time.
0 commit comments