@@ -530,7 +530,7 @@ def __init__(
530530 # Underscores may be appended to field names
531531 # that collide with python or proto-plus keywords.
532532 # In case a key only exists with a `_` suffix, coerce the key
533- # to include the `_` suffix. Is not possible to
533+ # to include the `_` suffix. It's not possible to
534534 # natively define the same field with a trailing underscore in protobuf.
535535 # See related issue
536536 # https://github.com/googleapis/python-api-core/issues/227
@@ -545,7 +545,27 @@ def __init__(
545545 "Unknown field for {}: {}" .format (self .__class__ .__name__ , key )
546546 )
547547
548- pb_value = marshal .to_proto (pb_type , value )
548+ try :
549+ pb_value = marshal .to_proto (pb_type , value )
550+ except ValueError :
551+ # Underscores may be appended to field names
552+ # that collide with python or proto-plus keywords.
553+ # In case a key only exists with a `_` suffix, coerce the key
554+ # to include the `_` suffix. It's not possible to
555+ # natively define the same field with a trailing underscore in protobuf.
556+ # See related issue
557+ # https://github.com/googleapis/python-api-core/issues/227
558+ if isinstance (value , dict ):
559+ keys_to_update = []
560+ for item in value :
561+ if not hasattr (pb_type , item ) and hasattr (pb_type , f"{ item } _" ):
562+ keys_to_update .append (item )
563+ for item in keys_to_update :
564+ value [f"{ item } _" ] = value [item ]
565+ del value [item ]
566+
567+ pb_value = marshal .to_proto (pb_type , value )
568+
549569 if pb_value is not None :
550570 params [key ] = pb_value
551571
@@ -662,7 +682,24 @@ def __getattr__(self, key):
662682 more details.
663683 """
664684 try :
665- pb_type = self ._meta .fields [key ].pb_type
685+ try :
686+ pb_type = self ._meta .fields [key ].pb_type
687+ except KeyError :
688+ # Underscores may be appended to field names
689+ # that collide with python or proto-plus keywords.
690+ # In case a key only exists with a `_` suffix, coerce the key
691+ # to include the `_` suffix. It's not possible to
692+ # natively define the same field with a trailing underscore in protobuf.
693+ # See related issue
694+ # https://github.com/googleapis/python-api-core/issues/227
695+ if f"{ key } _" in self ._meta .fields :
696+ key = f"{ key } _"
697+ pb_type = self ._meta .fields [key ].pb_type
698+ else :
699+ raise KeyError (
700+ "Unknown field for {}: {}" .format (self .__class__ .__name__ , key )
701+ )
702+
666703 pb_value = getattr (self ._pb , key )
667704 marshal = self ._meta .marshal
668705 return marshal .to_python (pb_type , pb_value , absent = key not in self )
@@ -685,7 +722,24 @@ def __setattr__(self, key, value):
685722 if key [0 ] == "_" :
686723 return super ().__setattr__ (key , value )
687724 marshal = self ._meta .marshal
688- pb_type = self ._meta .fields [key ].pb_type
725+ try :
726+ pb_type = self ._meta .fields [key ].pb_type
727+ except KeyError :
728+ # Underscores may be appended to field names
729+ # that collide with python or proto-plus keywords.
730+ # In case a key only exists with a `_` suffix, coerce the key
731+ # to include the `_` suffix. It's not possible to
732+ # natively define the same field with a trailing underscore in protobuf.
733+ # See related issue
734+ # https://github.com/googleapis/python-api-core/issues/227
735+ if f"{ key } _" in self ._meta .fields :
736+ key = f"{ key } _"
737+ pb_type = self ._meta .fields [key ].pb_type
738+ else :
739+ raise KeyError (
740+ "Unknown field for {}: {}" .format (self .__class__ .__name__ , key )
741+ )
742+
689743 pb_value = marshal .to_proto (pb_type , value )
690744
691745 # Clear the existing field.
0 commit comments