-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix for lazy import feature in alternative templates (#399)
This change places lazy imports only at the top levels of the generated GAPIC. The resulting surface is easier to test and maintains operational simplicity.
- Loading branch information
1 parent
1b30037
commit 920e419
Showing
11 changed files
with
294 additions
and
279 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 0 additions & 52 deletions
52
gapic/ads-templates/%namespace/%name/%version/%sub/types/__init__.py.j2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1 @@ | ||
{% extends '_base.py.j2' %} | ||
|
||
{% block content %} | ||
{% if opts.lazy_import -%} {# lazy import #} | ||
import importlib | ||
import sys | ||
|
||
|
||
if sys.version_info < (3, 7): | ||
raise ImportError('This module requires Python 3.7 or later.') # pragma: NO COVER | ||
|
||
|
||
_lazy_type_to_package_map = { | ||
{%- filter sort_lines %} | ||
{%- for proto in api.protos.values() if proto.meta.address.subpackage == api.subpackage_view %}{%- for message in proto.messages.values() %} | ||
'{{ message.name }}': '{% if api.naming.module_namespace %}{{ api.naming.module_namespace|join(".") }}.{% endif -%}{{ api.naming.versioned_module_name }}.types.{{ proto.module_name }}', | ||
{%- endfor %} | ||
{%- for enum in proto.enums.values() %} | ||
'{{ enum.name }}': '{% if api.naming.module_namespace %}{{ api.naming.module_namespace|join(".") }}.{% endif -%}{{ api.naming.versioned_module_name }}.types.{{ proto.module_name }}', | ||
{%- endfor %}{%- endfor %}{%- endfilter %} | ||
} | ||
|
||
|
||
# Background on how this behaves: https://www.python.org/dev/peps/pep-0562/ | ||
def __getattr__(name): # Requires Python >= 3.7 | ||
if name == '__all__': | ||
all_names = globals()['__all__'] = sorted(_lazy_type_to_package_map) | ||
return all_names | ||
elif name in _lazy_type_to_package_map: | ||
module = importlib.import_module(f'{_lazy_type_to_package_map[name]}') | ||
klass = getattr(module, name) | ||
{# new_klass = type(name, (klass,), {'__doc__': klass.__doc__}) #} | ||
globals()[name] = klass | ||
return klass | ||
else: | ||
raise AttributeError(f'unknown sub-module {name!r}.') | ||
|
||
|
||
def __dir__(): | ||
return globals().get('__all__') or __getattr__('__all__') | ||
|
||
{% else -%} | ||
{% for p in api.protos.values() if p.file_to_generate and p.messages -%} | ||
from .{{p.module_name }} import ({% for m in p.messages.values() %}{{ m.name }}, {% endfor %}) | ||
{% endfor %} | ||
|
||
__all__ = ( | ||
{%- for p in api.protos.values() if p.file_to_generate %}{% for m in p.messages.values() %} | ||
'{{ m.name }}', | ||
{%- endfor %}{% endfor %} | ||
) | ||
{% endif -%} {# lazy import #} | ||
{% endblock %} |
112 changes: 112 additions & 0 deletions
112
gapic/ads-templates/%namespace/%name/%version/__init__.py.j2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
{% extends '_base.py.j2' %} | ||
{% block content %} | ||
{% if opts.lazy_import -%} {# lazy import #} | ||
import importlib | ||
import sys | ||
|
||
|
||
if sys.version_info < (3, 7): | ||
raise ImportError('This module requires Python 3.7 or later.') | ||
|
||
|
||
_lazy_type_to_package_map = { | ||
# Message types | ||
{%- for message in api.top_level_messages.values() %} | ||
'{{ message.name }}': '{{ message.ident.package|join('.') }}.types.{{ message.ident.module }}', | ||
{%- endfor %} | ||
|
||
# Enum types | ||
{%- for enum in api.top_level_enums.values() %} | ||
'{{ enum.name }}': '{{ enum.ident.package|join('.') }}.types.{{enum.ident.module }}', | ||
{%- endfor %} | ||
|
||
# Client classes and transports | ||
{%- for service in api.services.values() %} | ||
'{{ service.client_name }}': '{{ service.meta.address.package|join('.') }}.services.{{ service.meta.address.module }}', | ||
'{{ service.transport_name }}': '{{ service.meta.address.package|join('.') }}.services.{{ service.meta.address.module }}.transports', | ||
'{{ service.grpc_transport_name }}': '{{ service.meta.address.package|join('.') }}.services.{{ service.meta.address.module }}.transports', | ||
{%- endfor %} | ||
} | ||
|
||
|
||
# Background on how this behaves: https://www.python.org/dev/peps/pep-0562/ | ||
def __getattr__(name): # Requires Python >= 3.7 | ||
if name == '__all__': | ||
all_names = globals()['__all__'] = sorted(_lazy_type_to_package_map) | ||
return all_names | ||
elif name in _lazy_type_to_package_map: | ||
module = importlib.import_module(f'{_lazy_type_to_package_map[name]}') | ||
klass = getattr(module, name) | ||
{# new_klass = type(name, (klass,), {'__doc__': klass.__doc__}) #} | ||
globals()[name] = klass | ||
return klass | ||
else: | ||
raise AttributeError(f'unknown type {name!r}.') | ||
|
||
|
||
def __dir__(): | ||
return globals().get('__all__') or __getattr__('__all__') | ||
{% else -%} {# do not use lazy import #} | ||
{# Import subpackages. -#} | ||
{% filter sort_lines -%} | ||
{% for subpackage in api.subpackages.keys() -%} | ||
from {% if api.naming.module_namespace %}{{ api.naming.module_namespace|join('.') }}.{% endif -%} | ||
{{ api.naming.versioned_module_name }} import {{ subpackage }} | ||
{% endfor -%} | ||
|
||
{# Import services for this package. -#} | ||
{% for service in api.services.values()|sort(attribute='name') | ||
if service.meta.address.subpackage == api.subpackage_view -%} | ||
from {% if api.naming.module_namespace %}{{ api.naming.module_namespace|join('.') }}.{% endif -%} | ||
{{ api.naming.versioned_module_name }}.services.{{ service.name|snake_case }}.client import {{ service.client_name }} | ||
{% endfor -%} | ||
|
||
{# Import messages and enums from each proto. | ||
It is safe to import all of the messages into the same namespace here, | ||
because protocol buffers itself enforces selector uniqueness within | ||
a proto package. | ||
-#} | ||
{# Import messages from each proto. | ||
It is safe to import all of the messages into the same namespace here, | ||
because protocol buffers itself enforces selector uniqueness within | ||
a proto package. | ||
-#} | ||
{% for proto in api.protos.values()|sort(attribute='module_name') | ||
if proto.meta.address.subpackage == api.subpackage_view -%} | ||
{% for message in proto.messages.values()|sort(attribute='name') -%} | ||
from {% if api.naming.module_namespace %}{{ api.naming.module_namespace|join('.') }}.{% endif -%} | ||
{{ api.naming.versioned_module_name }}.types.{{ proto.module_name }} import {{ message.name }} | ||
{% endfor -%} | ||
{% for enum in proto.enums.values()|sort(attribute='name') -%} | ||
from {% if api.naming.module_namespace %}{{ api.naming.module_namespace|join('.') }}.{% endif -%} | ||
{{ api.naming.versioned_module_name }}.types.{{ proto.module_name }} import {{ enum.name }} | ||
{% endfor %}{% endfor -%} | ||
{% endfilter %} | ||
{# Define __all__. | ||
This requires the full set of imported names, so we iterate over | ||
them again. | ||
-#} | ||
__all__ = ( | ||
{%- filter indent %} | ||
{% filter sort_lines -%} | ||
{% for subpackage in api.subpackages.keys() -%} | ||
'{{ subpackage }}', | ||
{% endfor -%} | ||
{% for service in api.services.values()|sort(attribute='name') | ||
if service.meta.address.subpackage == api.subpackage_view -%} | ||
'{{ service.client_name }}', | ||
{% endfor -%} | ||
{% for proto in api.protos.values()|sort(attribute='module_name') | ||
if proto.meta.address.subpackage == api.subpackage_view -%} | ||
{% for message in proto.messages.values()|sort(attribute='name') -%} | ||
'{{ message.name }}', | ||
{% endfor -%} | ||
{% for enum in proto.enums.values()|sort(attribute='name') | ||
if proto.meta.address.subpackage == api.subpackage_view -%} | ||
'{{ enum.name }}', | ||
{% endfor -%}{% endfor -%} | ||
{% endfilter -%} | ||
{% endfilter -%} | ||
) | ||
{% endif -%} {# lazy import #} | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.