Skip to content

Commit

Permalink
fix: disambiguate field headers whose names are reserved python words (
Browse files Browse the repository at this point in the history
…#1178)

* fix: disambiguate field headers whose names are reserved python words

* Add FieldHeader class

* update tests and templates
  • Loading branch information
parthea authored Feb 12, 2022
1 parent 246bfe2 commit 98aa690
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
gapic_v1.routing_header.to_grpc_metadata((
{% for field_header in method.field_headers %}
{% if not method.client_streaming %}
("{{ field_header }}", request.{{ field_header }}),
("{{ field_header.raw }}", request.{{ field_header.disambiguated }}),
{% endif %}
{% endfor %}
)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ def test_{{ method_name }}_field_headers():
request = {{ method.input.ident }}()

{% for field_header in method.field_headers %}
request.{{ field_header }} = '{{ field_header }}/value'
request.{{ field_header.disambiguated }} = '{{ field_header.raw }}/value'
{% endfor %}

# Mock the actual call within the gRPC stub, and fake the request.
Expand Down Expand Up @@ -623,7 +623,7 @@ def test_{{ method_name }}_field_headers():
assert (
'x-goog-request-params',
'{% for field_header in method.field_headers -%}
{{ field_header }}={{ field_header }}/value
{{ field_header.raw }}={{ field_header.raw }}/value
{%- if not loop.last %}&{% endif %}
{%- endfor -%}',
) in kw['metadata']
Expand Down Expand Up @@ -783,7 +783,7 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
gapic_v1.routing_header.to_grpc_metadata((
{% for field_header in method.field_headers %}
{% if not method.client_streaming %}
('{{ field_header }}', ''),
('{{ field_header.raw }}', ''),
{% endif %}
{% endfor %}
)),
Expand Down
21 changes: 18 additions & 3 deletions gapic/schema/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,15 @@ def with_context(
)


@dataclasses.dataclass(frozen=True)
class FieldHeader:
raw: str

@property
def disambiguated(self) -> str:
return self.raw + "_" if self.raw in utils.RESERVED_NAMES else self.raw


@dataclasses.dataclass(frozen=True)
class Oneof:
"""Description of a field."""
Expand Down Expand Up @@ -1070,8 +1079,9 @@ def is_deprecated(self) -> bool:
# e.g. doesn't work with basic case of gRPC transcoding

@property
def field_headers(self) -> Sequence[str]:
def field_headers(self) -> Sequence[FieldHeader]:
"""Return the field headers defined for this method."""

http = self.options.Extensions[annotations_pb2.http]

pattern = re.compile(r'\{([a-z][\w\d_.]+)=')
Expand All @@ -1084,8 +1094,13 @@ def field_headers(self) -> Sequence[str]:
http.patch,
http.custom.path,
]

return next((tuple(pattern.findall(verb)) for verb in potential_verbs if verb), ())
field_headers = (
tuple(FieldHeader(field_header)
for field_header in pattern.findall(verb))
for verb in potential_verbs
if verb
)
return next(field_headers, ())

@property
def explicit_routing(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ class {{ service.async_client_name }}:
gapic_v1.routing_header.to_grpc_metadata((
{% for field_header in method.field_headers %}
{% if not method.client_streaming %}
("{{ field_header }}", request.{{ field_header }}),
("{{ field_header.raw }}", request.{{ field_header.disambiguated }}),
{% endif %}
{% endfor %}
)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
gapic_v1.routing_header.to_grpc_metadata((
{% for field_header in method.field_headers %}
{% if not method.client_streaming %}
("{{ field_header }}", request.{{ field_header }}),
("{{ field_header.raw }}", request.{{ field_header.disambiguated }}),
{% endif %}
{% endfor %}
)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ def test_{{ method_name }}_field_headers():
request = {{ method.input.ident }}()

{% for field_header in method.field_headers %}
request.{{ field_header }} = '{{ field_header }}/value'
request.{{ field_header.disambiguated }} = '{{ field_header.raw }}/value'
{% endfor %}

# Mock the actual call within the gRPC stub, and fake the request.
Expand Down Expand Up @@ -833,7 +833,7 @@ def test_{{ method_name }}_field_headers():
assert (
'x-goog-request-params',
'{% for field_header in method.field_headers -%}
{{ field_header }}={{ field_header }}/value
{{ field_header.raw }}={{ field_header.raw }}/value
{%- if not loop.last %}&{% endif %}
{%- endfor -%}',
) in kw['metadata']
Expand All @@ -850,7 +850,7 @@ async def test_{{ method_name }}_field_headers_async():
request = {{ method.input.ident }}()

{% for field_header in method.field_headers %}
request.{{ field_header }} = '{{ field_header }}/value'
request.{{ field_header.disambiguated }} = '{{ field_header.raw }}/value'
{% endfor %}

# Mock the actual call within the gRPC stub, and fake the request.
Expand Down Expand Up @@ -879,7 +879,7 @@ async def test_{{ method_name }}_field_headers_async():
assert (
'x-goog-request-params',
'{% for field_header in method.field_headers -%}
{{ field_header }}={{ field_header }}/value
{{ field_header.raw }}={{ field_header.raw }}/value
{%- if not loop.last %}&{% endif %}
{%- endfor -%}',
) in kw['metadata']
Expand Down Expand Up @@ -1128,7 +1128,7 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
gapic_v1.routing_header.to_grpc_metadata((
{% for field_header in method.field_headers %}
{% if not method.client_streaming %}
('{{ field_header }}', ''),
('{{ field_header.raw }}', ''),
{% endif %}
{% endfor %}
)),
Expand Down
11 changes: 10 additions & 1 deletion tests/unit/schema/wrappers/test_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,16 @@ def test_method_field_headers_present():
for v in verbs:
rule = http_pb2.HttpRule(**{v: '/v1/{parent=projects/*}/topics'})
method = make_method('DoSomething', http_rule=rule)
assert method.field_headers == ('parent',)
assert method.field_headers == (wrappers.FieldHeader('parent'),)
assert method.field_headers[0].raw == 'parent'
assert method.field_headers[0].disambiguated == 'parent'

# test that reserved keyword in field header is disambiguated
rule = http_pb2.HttpRule(**{v: '/v1/{object=objects/*}/topics'})
method = make_method('DoSomething', http_rule=rule)
assert method.field_headers == (wrappers.FieldHeader('object'),)
assert method.field_headers[0].raw == 'object'
assert method.field_headers[0].disambiguated == 'object_'


def test_method_routing_rule():
Expand Down

0 comments on commit 98aa690

Please sign in to comment.