Skip to content

Commit d914456

Browse files
PicardParisparthea
andauthored
feat: Add typing to proto.Message based class attributes (#1474)
* feat: Add typing to proto.Message based class attributes * fix: Apply actual mutable flavor for Sequence/Mapping * fix: Update iterators and all tests * fix: Update client and goldens * fix: Remove goldens to resolve conflicts with updated main branch * fix: Conform with PEP 484 and mypy new default (no_implicit_optional=True) * fix: Conform with PEP 484 and mypy new default (no_implicit_optional=True) Co-authored-by: Anthonios Partheniou <partheniou@google.com>
1 parent f656d40 commit d914456

File tree

84 files changed

+1693
-1668
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1693
-1668
lines changed

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/_mixins.py.j2

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
{% if "ListOperations" in api.mixin_api_methods %}
44
def list_operations(
55
self,
6-
request: operations_pb2.ListOperationsRequest = None,
6+
request: Optional[operations_pb2.ListOperationsRequest] = None,
77
*,
88
retry: OptionalRetry = gapic_v1.method.DEFAULT,
9-
timeout: float = None,
9+
timeout: Optional[float] = None,
1010
metadata: Sequence[Tuple[str, str]] = (),
1111
) -> operations_pb2.ListOperationsResponse:
1212
r"""Lists operations that match the specified filter in the request.
@@ -57,10 +57,10 @@
5757
{% if "GetOperation" in api.mixin_api_methods %}
5858
def get_operation(
5959
self,
60-
request: operations_pb2.GetOperationRequest = None,
60+
request: Optional[operations_pb2.GetOperationRequest] = None,
6161
*,
6262
retry: OptionalRetry = gapic_v1.method.DEFAULT,
63-
timeout: float = None,
63+
timeout: Optional[float] = None,
6464
metadata: Sequence[Tuple[str, str]] = (),
6565
) -> operations_pb2.Operation:
6666
r"""Gets the latest state of a long-running operation.
@@ -110,10 +110,10 @@
110110
{% if "DeleteOperation" in api.mixin_api_methods %}
111111
def delete_operation(
112112
self,
113-
request: operations_pb2.DeleteOperationRequest = None,
113+
request: Optional[operations_pb2.DeleteOperationRequest] = None,
114114
*,
115115
retry: OptionalRetry = gapic_v1.method.DEFAULT,
116-
timeout: float = None,
116+
timeout: Optional[float] = None,
117117
metadata: Sequence[Tuple[str, str]] = (),
118118
) -> None:
119119
r"""Deletes a long-running operation.
@@ -163,10 +163,10 @@
163163
{% if "CancelOperation" in api.mixin_api_methods %}
164164
def cancel_operation(
165165
self,
166-
request: operations_pb2.CancelOperationRequest = None,
166+
request: Optional[operations_pb2.CancelOperationRequest] = None,
167167
*,
168168
retry: OptionalRetry = gapic_v1.method.DEFAULT,
169-
timeout: float = None,
169+
timeout: Optional[float] = None,
170170
metadata: Sequence[Tuple[str, str]] = (),
171171
) -> None:
172172
r"""Starts asynchronous cancellation on a long-running operation.
@@ -215,10 +215,10 @@
215215
{% if "WaitOperation" in api.mixin_api_methods %}
216216
def wait_operation(
217217
self,
218-
request: operations_pb2.WaitOperationRequest = None,
218+
request: Optional[operations_pb2.WaitOperationRequest] = None,
219219
*,
220220
retry: OptionalRetry = gapic_v1.method.DEFAULT,
221-
timeout: float = None,
221+
timeout: Optional[float] = None,
222222
metadata: Sequence[Tuple[str, str]] = (),
223223
) -> operations_pb2.Operation:
224224
r"""Waits until the specified long-running operation is done or reaches at most
@@ -274,10 +274,10 @@
274274
{% if "SetIamPolicy" in api.mixin_api_methods %}
275275
def set_iam_policy(
276276
self,
277-
request: iam_policy_pb2.SetIamPolicyRequest = None,
277+
request: Optional[iam_policy_pb2.SetIamPolicyRequest] = None,
278278
*,
279279
retry: OptionalRetry = gapic_v1.method.DEFAULT,
280-
timeout: float = None,
280+
timeout: Optional[float] = None,
281281
metadata: Sequence[Tuple[str, str]] = (),
282282
) -> policy_pb2.Policy:
283283
r"""Sets the IAM access control policy on the specified function.
@@ -393,10 +393,10 @@
393393
{% if "GetIamPolicy" in api.mixin_api_methods %}
394394
def get_iam_policy(
395395
self,
396-
request: iam_policy_pb2.GetIamPolicyRequest = None,
396+
request: Optional[iam_policy_pb2.GetIamPolicyRequest] = None,
397397
*,
398398
retry: OptionalRetry = gapic_v1.method.DEFAULT,
399-
timeout: float = None,
399+
timeout: Optional[float] = None,
400400
metadata: Sequence[Tuple[str, str]] = (),
401401
) -> policy_pb2.Policy:
402402
r"""Gets the IAM access control policy for a function.
@@ -513,10 +513,10 @@
513513
{% if "TestIamPermissions" in api.mixin_api_methods %}
514514
def test_iam_permissions(
515515
self,
516-
request: iam_policy_pb2.TestIamPermissionsRequest = None,
516+
request: Optional[iam_policy_pb2.TestIamPermissionsRequest] = None,
517517
*,
518518
retry: OptionalRetry = gapic_v1.method.DEFAULT,
519-
timeout: float = None,
519+
timeout: Optional[float] = None,
520520
metadata: Sequence[Tuple[str, str]] = (),
521521
) -> iam_policy_pb2.TestIamPermissionsResponse:
522522
r"""Tests the specified IAM permissions against the IAM access control
@@ -575,10 +575,10 @@
575575
{% if "GetLocation" in api.mixin_api_methods %}
576576
def get_location(
577577
self,
578-
request: locations_pb2.GetLocationRequest = None,
578+
request: Optional[locations_pb2.GetLocationRequest] = None,
579579
*,
580580
retry: OptionalRetry = gapic_v1.method.DEFAULT,
581-
timeout: float = None,
581+
timeout: Optional[float] = None,
582582
metadata: Sequence[Tuple[str, str]] = (),
583583
) -> locations_pb2.Location:
584584
r"""Gets information about a location.
@@ -628,10 +628,10 @@
628628
{% if "ListLocations" in api.mixin_api_methods %}
629629
def list_locations(
630630
self,
631-
request: locations_pb2.ListLocationsRequest = None,
631+
request: Optional[locations_pb2.ListLocationsRequest] = None,
632632
*,
633633
retry: OptionalRetry = gapic_v1.method.DEFAULT,
634-
timeout: float = None,
634+
timeout: Optional[float] = None,
635635
metadata: Sequence[Tuple[str, str]] = (),
636636
) -> locations_pb2.ListLocationsResponse:
637637
r"""Lists information about the supported locations for this service.

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/client.py.j2

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from collections import OrderedDict
66
import os
77
import re
8-
from typing import Callable, Dict, Mapping, Optional, {% if service.any_server_streaming %}Iterable, {% endif %}{% if service.any_client_streaming %}Iterator, {% endif %}Sequence, Tuple, Type, Union, cast
8+
from typing import Callable, Dict, Mapping, MutableMapping, MutableSequence, Optional, {% if service.any_server_streaming %}Iterable, {% endif %}{% if service.any_client_streaming %}Iterator, {% endif %}Sequence, Tuple, Type, Union, cast
99
import pkg_resources
1010
{% if service.any_deprecated %}
1111
import warnings
@@ -68,7 +68,7 @@ class {{ service.client_name }}Meta(type):
6868
{% endif %}
6969

7070
def get_transport_class(cls,
71-
label: str = None,
71+
label: Optional[str] = None,
7272
) -> Type[{{ service.name }}Transport]:
7373
"""Returns an appropriate transport class.
7474

@@ -218,7 +218,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
218218

219219
def __init__(self, *,
220220
credentials: Optional[ga_credentials.Credentials] = None,
221-
transport: Union[str, {{ service.name }}Transport, None] = None,
221+
transport: Optional[Union[str, {{ service.name }}Transport]] = None,
222222
client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
223223
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
224224
) -> None:
@@ -230,7 +230,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
230230
credentials identify the application to the service; if none
231231
are specified, the client will attempt to ascertain the
232232
credentials from the environment.
233-
transport (Union[str, {{ service.name }}Transport]): The
233+
transport (Optional[Union[str, {{ service.name }}Transport]]): The
234234
transport to use. If set to None, a transport is chosen
235235
automatically.
236236
{% if 'rest' in opts.transport and not opts.rest_numeric_enums %}
@@ -340,17 +340,17 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
340340
def {{ method.name|snake_case }}(self,
341341
{% endif %}{# Extended Operations LRO #}
342342
{% if not method.client_streaming %}
343-
request: Union[{{ method.input.ident }}, dict] = None,
343+
request: Optional[Union[{{ method.input.ident }}, dict]] = None,
344344
*,
345345
{% for field in method.flattened_fields.values() %}
346-
{{ field.name }}: {{ field.ident }} = None,
346+
{{ field.name }}: Optional[{{ field.ident }}] = None,
347347
{% endfor %}
348348
{% else %}
349-
requests: Iterator[{{ method.input.ident }}] = None,
349+
requests: Optional[Iterator[{{ method.input.ident }}]] = None,
350350
*,
351351
{% endif %}
352352
retry: OptionalRetry = gapic_v1.method.DEFAULT,
353-
timeout: float = None,
353+
timeout: Optional[float] = None,
354354
metadata: Sequence[Tuple[str, str]] = (),
355355
{% if not method.server_streaming %}
356356
) -> {{ method.client_output.ident }}:
@@ -361,7 +361,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
361361

362362
Args:
363363
{% if not method.client_streaming %}
364-
request (Union[{{ method.input.ident.sphinx }}, dict]):
364+
request (Union[{{ method.input.ident.sphinx }}, dict, None]):
365365
The request object.{{ " " }}
366366
{{- method.input.meta.doc|wrap(width=72, offset=36, indent=16) }}
367367
{% for key, field in method.flattened_fields.items() %}
@@ -516,10 +516,10 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
516516
{% if opts.add_iam_methods %}
517517
def set_iam_policy(
518518
self,
519-
request: iam_policy_pb2.SetIamPolicyRequest = None,
519+
request: Optional[iam_policy_pb2.SetIamPolicyRequest] = None,
520520
*,
521521
retry: OptionalRetry = gapic_v1.method.DEFAULT,
522-
timeout: float = None,
522+
timeout: Optional[float] = None,
523523
metadata: Sequence[Tuple[str, str]] = (),
524524
) -> policy_pb2.Policy:
525525
r"""Sets the IAM access control policy on the specified function.
@@ -633,10 +633,10 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
633633

634634
def get_iam_policy(
635635
self,
636-
request: iam_policy_pb2.GetIamPolicyRequest = None,
636+
request: Optional[iam_policy_pb2.GetIamPolicyRequest] = None,
637637
*,
638638
retry: OptionalRetry = gapic_v1.method.DEFAULT,
639-
timeout: float = None,
639+
timeout: Optional[float] = None,
640640
metadata: Sequence[Tuple[str, str]] = (),
641641
) -> policy_pb2.Policy:
642642
r"""Gets the IAM access control policy for a function.
@@ -750,10 +750,10 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
750750

751751
def test_iam_permissions(
752752
self,
753-
request: iam_policy_pb2.TestIamPermissionsRequest = None,
753+
request: Optional[iam_policy_pb2.TestIamPermissionsRequest] = None,
754754
*,
755755
retry: OptionalRetry = gapic_v1.method.DEFAULT,
756-
timeout: float = None,
756+
timeout: Optional[float] = None,
757757
metadata: Sequence[Tuple[str, str]] = (),
758758
) -> iam_policy_pb2.TestIamPermissionsResponse:
759759
r"""Tests the specified IAM permissions against the IAM access control

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/pagers.py.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class {{ method.name }}Pager:
7878
def get(self, key: str) -> Optional[{{ method.paged_result_field.type.fields.get('value').ident }}]:
7979
return self._response.{{ method.paged_result_field.name }}.get(key)
8080
{% else %}
81-
def __iter__(self) -> {{ method.paged_result_field.ident | replace('Sequence', 'Iterator') }}:
81+
def __iter__(self) -> {{ method.paged_result_field.ident | replace('MutableSequence', 'Iterator') }}:
8282
for page in self.pages:
8383
yield from page.{{ method.paged_result_field.name }}
8484
{% endif %}

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/transports/base.py.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class {{ service.name }}Transport(abc.ABC):
5858
def __init__(
5959
self, *,
6060
host: str = DEFAULT_HOST,
61-
credentials: ga_credentials.Credentials = None,
61+
credentials: Optional[ga_credentials.Credentials] = None,
6262
credentials_file: Optional[str] = None,
6363
scopes: Optional[Sequence[str]] = None,
6464
quota_project_id: Optional[str] = None,

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/transports/grpc.py.j2

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport):
5151

5252
def __init__(self, *,
5353
host: str{% if service.host %} = '{{ service.host }}'{% endif %},
54-
credentials: ga_credentials.Credentials = None,
55-
credentials_file: str = None,
56-
scopes: Sequence[str] = None,
57-
channel: grpc.Channel = None,
58-
api_mtls_endpoint: str = None,
59-
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
60-
ssl_channel_credentials: grpc.ChannelCredentials = None,
61-
client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
54+
credentials: Optional[ga_credentials.Credentials] = None,
55+
credentials_file: Optional[str] = None,
56+
scopes: Optional[Sequence[str]] = None,
57+
channel: Optional[grpc.Channel] = None,
58+
api_mtls_endpoint: Optional[str] = None,
59+
client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
60+
ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
61+
client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
6262
quota_project_id: Optional[str] = None,
6363
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
6464
always_use_jwt_access: Optional[bool] = False,
@@ -186,8 +186,8 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport):
186186
@classmethod
187187
def create_channel(cls,
188188
host: str{% if service.host %} = '{{ service.host }}'{% endif %},
189-
credentials: ga_credentials.Credentials = None,
190-
credentials_file: str = None,
189+
credentials: Optional[ga_credentials.Credentials] = None,
190+
credentials_file: Optional[str] = None,
191191
scopes: Optional[Sequence[str]] = None,
192192
quota_project_id: Optional[str] = None,
193193
**kwargs) -> grpc.Channel:

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/transports/rest.py.j2

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,15 @@ class {{service.name}}RestTransport({{service.name}}Transport):
140140
{# TODO(yon-mg): handle mtls stuff if that is relevant for rest transport #}
141141
def __init__(self, *,
142142
host: str{% if service.host %} = '{{ service.host }}'{% endif %},
143-
credentials: ga_credentials.Credentials=None,
144-
credentials_file: str=None,
145-
scopes: Sequence[str]=None,
146-
client_cert_source_for_mtls: Callable[[
147-
], Tuple[bytes, bytes]]=None,
148-
quota_project_id: Optional[str]=None,
149-
client_info: gapic_v1.client_info.ClientInfo=DEFAULT_CLIENT_INFO,
150-
always_use_jwt_access: Optional[bool]=False,
151-
url_scheme: str='https',
143+
credentials: Optional[ga_credentials.Credentials] = None,
144+
credentials_file: Optional[str] = None,
145+
scopes: Optional[Sequence[str]] = None,
146+
client_cert_source_for_mtls: Optional[Callable[[
147+
], Tuple[bytes, bytes]]] = None,
148+
quota_project_id: Optional[str] = None,
149+
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
150+
always_use_jwt_access: Optional[bool] = False,
151+
url_scheme: str = 'https',
152152
interceptor: Optional[{{ service.name }}RestInterceptor] = None,
153153
) -> None:
154154
"""Instantiate the transport.
@@ -282,9 +282,9 @@ class {{service.name}}RestTransport({{service.name}}Transport):
282282

283283
def __call__(self,
284284
request: {{method.input.ident}}, *,
285-
retry: OptionalRetry=gapic_v1.method.DEFAULT,
286-
timeout: float=None,
287-
metadata: Sequence[Tuple[str, str]]=(),
285+
retry: OptionalRetry = gapic_v1.method.DEFAULT,
286+
timeout: Optional[float] = None,
287+
metadata: Sequence[Tuple[str, str]] = (),
288288
){% if not method.void %} -> {% if not method.server_streaming %}{{method.output.ident}}{% else %}rest_streaming.ResponseIterator{% endif %}{% endif %}:
289289
{% if method.http_options and not method.client_streaming %}
290290
r"""Call the {{- ' ' -}}

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/types/%proto.py.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
{% with p = proto.disambiguate('proto') %}
66
{% if proto.messages|length or proto.all_enums|length %}
7+
from typing import MutableMapping, MutableSequence
8+
79
import proto{% if p != 'proto' %} as {{ p }}{% endif %} # type: ignore
810
{% endif %}
911

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/types/_message.py.j2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class {{ message.name }}({{ p }}.Message):
5151
{% for field in message.fields.values() %}
5252
{% if field.map %}
5353
{% with key_field = field.message.fields['key'], value_field = field.message.fields['value'] %}
54-
{{ field.name }} = {{ p }}.MapField(
54+
{{ field.name }}: MutableMapping[{{ key_field.type.ident.rel(message.ident) }}, {{ value_field.type.ident.rel(message.ident) }}] = {{ p }}.MapField(
5555
{{ p }}.{{ key_field.proto_type }},
5656
{{ p }}.{{ value_field.proto_type }},
5757
number={{ field.number }},
@@ -61,7 +61,7 @@ class {{ message.name }}({{ p }}.Message):
6161
)
6262
{% endwith %}
6363
{% else %}
64-
{{ field.name }} = {{ p }}.{% if field.repeated %}Repeated{% endif %}Field(
64+
{{ field.name }}: {% if field.is_primitive %}{{ field.ident }}{% else %}{% if field.repeated %}MutableSequence[{% endif %}{{ field.type.ident.rel(message.ident) }}{% if field.repeated %}]{% endif %}{% endif %} = {{ p }}.{% if field.repeated %}Repeated{% endif %}Field(
6565
{{ p }}.{{ field.proto_type }},
6666
number={{ field.number }},
6767
{% if field.proto3_optional %}

packages/gapic-generator/gapic/generator/generator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import os
2020
import pathlib
2121
import typing
22-
from typing import Any, DefaultDict, Dict, Mapping, Tuple
22+
from typing import Any, DefaultDict, Dict, Mapping, Optional, Tuple
2323
from hashlib import sha256
2424
from collections import OrderedDict, defaultdict
2525
from gapic.samplegen_utils.utils import coerce_response_name, is_valid_sample_cfg, render_format_string
@@ -362,7 +362,7 @@ def _get_file(
362362
return {fn: cgr_file}
363363

364364
def _get_filename(
365-
self, template_name: str, *, api_schema: api.API, context: dict = None,
365+
self, template_name: str, *, api_schema: api.API, context: Optional[dict] = None,
366366
) -> str:
367367
"""Return the appropriate output filename for this template.
368368

packages/gapic-generator/gapic/samplegen/manifest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import os
1616
import time
17-
from typing import Tuple
17+
from typing import Optional, Tuple
1818

1919
from gapic.samplegen_utils import (types, yaml)
2020
from gapic.utils import case
@@ -45,7 +45,7 @@ def generate(
4545
api_schema,
4646
*,
4747
environment: yaml.Map = PYTHON3_ENVIRONMENT,
48-
manifest_time: int = None
48+
manifest_time: Optional[int] = None
4949
) -> Tuple[str, yaml.Doc]:
5050
"""Generate a samplegen manifest for use by sampletest
5151

0 commit comments

Comments
 (0)