@@ -563,10 +563,11 @@ def write_messages(
563563 if is_scalar (field ) and field .label != d .FieldDescriptorProto .LABEL_REPEATED :
564564 # Scalar non repeated fields are r/w, generate getter and setter if deprecated
565565 scl_field = scl + [d .DescriptorProto .FIELD_FIELD_NUMBER , idx ]
566+ deprecation_scl_field = scl_field + [d .FieldDescriptorProto .OPTIONS_FIELD_NUMBER ] + [d .FieldOptions .DEPRECATED_FIELD_NUMBER ]
566567 if field .options .deprecated :
567568 wl ("@property" )
568569 self ._write_deprecation_warning (
569- scl_field + [ d . FieldDescriptorProto . OPTIONS_FIELD_NUMBER ] + [ d . FieldOptions . DEPRECATED_FIELD_NUMBER ] ,
570+ deprecation_scl_field ,
570571 "This field has been marked as deprecated using proto field options." ,
571572 )
572573 body = " ..." if not self ._has_comments (scl_field ) else ""
@@ -577,7 +578,7 @@ def write_messages(
577578 wl ("" )
578579 wl (f"@{ field .name } .setter" )
579580 self ._write_deprecation_warning (
580- scl_field + [ d . FieldDescriptorProto . OPTIONS_FIELD_NUMBER ] + [ d . FieldOptions . DEPRECATED_FIELD_NUMBER ] ,
581+ deprecation_scl_field ,
581582 "This field has been marked as deprecated using proto field options." ,
582583 )
583584 body = " ..." if not self ._has_comments (scl_field ) else ""
@@ -936,7 +937,7 @@ def write_grpc_servicer_context(self) -> None:
936937 wl ("..." )
937938 wl ("" )
938939
939- def write_grpc_stub_methods (self , service : d .ServiceDescriptorProto , scl_prefix : SourceCodeLocation , * , is_async : bool , both : bool = False , ignore_override_errors : bool = False ) -> None :
940+ def write_grpc_stub_methods (self , service : d .ServiceDescriptorProto , scl_prefix : SourceCodeLocation , * , is_async : bool , both : bool = False , ignore_type_error : bool = False ) -> None :
940941 wl = self ._write_line
941942 methods = [(i , m ) for i , m in enumerate (service .method ) if m .name not in PYTHON_RESERVED ]
942943 if not methods :
@@ -947,20 +948,30 @@ def type_str(method: d.MethodDescriptorProto, is_async: bool) -> str:
947948
948949 for i , method in methods :
949950 scl = scl_prefix + [d .ServiceDescriptorProto .METHOD_FIELD_NUMBER , i ]
950- wl ("@property" )
951- if method .options .deprecated :
951+ is_deprecated = method .options .deprecated
952+ has_comments = self ._has_comments (scl )
953+
954+ # Generate type annotation once
955+ if both :
956+ type_annotation = f"{ self ._import ('typing' , 'Union' )} [{ type_str (method , is_async = False )} , { type_str (method , is_async = True )} ]"
957+ else :
958+ type_annotation = type_str (method , is_async = is_async )
959+
960+ if is_deprecated :
961+ wl ("@property" )
952962 self ._write_deprecation_warning (
953- scl + [d .MethodDescriptorProto .OPTIONS_FIELD_NUMBER ] + [ d .MethodOptions .DEPRECATED_FIELD_NUMBER ],
963+ scl + [d .MethodDescriptorProto .OPTIONS_FIELD_NUMBER , d .MethodOptions .DEPRECATED_FIELD_NUMBER ],
954964 "This method has been marked as deprecated using proto method options." ,
955965 )
956- if both :
957- wl ("def {}(self) -> {}[{}, {}]:{}" , method .name , self ._import ("typing" , "Union" ), type_str (method , is_async = False ), type_str (method , is_async = True ), " ..." if not self ._has_comments (scl ) else " " )
966+ wl (f"def { method .name } (self) -> { type_annotation } :{ ' ...' if not has_comments else '' } { ' # type: ignore[override]' if ignore_type_error else '' } " )
967+
968+ if has_comments :
969+ with self ._indent ():
970+ if not self ._write_comments (scl ):
971+ wl ("..." )
958972 else :
959- wl ("def {}(self) -> {}:{}{}" , method .name , type_str (method , is_async = is_async ), " ..." if not self ._has_comments (scl ) else "" , "" if not ignore_override_errors else " # type: ignore[override]" )
960- if self ._has_comments (scl ):
961- with self ._indent ():
962- if not self ._write_comments (scl ):
963- wl ("..." )
973+ wl (f"{ method .name } : { type_annotation } { ' # type: ignore[assignment]' if ignore_type_error else '' } " )
974+ self ._write_comments (scl )
964975
965976 def write_grpc_methods (self , service : d .ServiceDescriptorProto , scl_prefix : SourceCodeLocation ) -> None :
966977 wl = self ._write_line
@@ -1077,7 +1088,7 @@ def write_grpc_services(
10771088 if self ._write_comments (scl ):
10781089 wl ("" )
10791090 wl ("def __init__(self, channel: {}) -> None: ..." , self ._import ("grpc.aio" , "Channel" ))
1080- self .write_grpc_stub_methods (service , scl , is_async = True , ignore_assignment_errors = True )
1091+ self .write_grpc_stub_methods (service , scl , is_async = True , ignore_type_error = True )
10811092 else :
10821093 # ASYNC only - use Stub name (not AsyncStub) since there's only one type
10831094 wl ("class {}:" , class_name )
0 commit comments