@typespec/http-client-python 0.4.4 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/emitter/emitter.d.ts.map +1 -1
- package/dist/emitter/emitter.js +110 -24
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/http.js +1 -1
- package/dist/emitter/http.js.map +1 -1
- package/dist/emitter/lib.d.ts +1 -0
- package/dist/emitter/lib.d.ts.map +1 -1
- package/dist/emitter/lib.js +1 -0
- package/dist/emitter/lib.js.map +1 -1
- package/dist/emitter/run-python3.d.ts +2 -0
- package/dist/emitter/run-python3.d.ts.map +1 -0
- package/dist/emitter/run-python3.js +19 -0
- package/dist/emitter/run-python3.js.map +1 -0
- package/dist/emitter/system-requirements.d.ts +17 -0
- package/dist/emitter/system-requirements.d.ts.map +1 -0
- package/dist/emitter/system-requirements.js +167 -0
- package/dist/emitter/system-requirements.js.map +1 -0
- package/emitter/src/emitter.ts +111 -23
- package/emitter/src/http.ts +1 -1
- package/emitter/src/lib.ts +2 -0
- package/emitter/src/run-python3.ts +20 -0
- package/emitter/src/system-requirements.ts +261 -0
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/Test-Packages.ps1 +1 -1
- package/eng/scripts/ci/regenerate.ts +20 -8
- package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
- package/eng/scripts/setup/build.ts +16 -0
- package/eng/scripts/setup/build_pygen_wheel.py +40 -0
- package/eng/scripts/setup/install.py +9 -8
- package/eng/scripts/setup/install.ts +12 -0
- package/eng/scripts/setup/prepare.py +3 -1
- package/eng/scripts/setup/prepare.ts +11 -0
- package/eng/scripts/setup/run-python3.ts +1 -6
- package/generator/build/lib/pygen/__init__.py +107 -0
- package/generator/build/lib/pygen/_version.py +7 -0
- package/generator/build/lib/pygen/black.py +71 -0
- package/generator/build/lib/pygen/codegen/__init__.py +357 -0
- package/generator/build/lib/pygen/codegen/_utils.py +17 -0
- package/generator/build/lib/pygen/codegen/models/__init__.py +204 -0
- package/generator/build/lib/pygen/codegen/models/base.py +186 -0
- package/generator/build/lib/pygen/codegen/models/base_builder.py +118 -0
- package/generator/build/lib/pygen/codegen/models/client.py +435 -0
- package/generator/build/lib/pygen/codegen/models/code_model.py +237 -0
- package/generator/build/lib/pygen/codegen/models/combined_type.py +149 -0
- package/generator/build/lib/pygen/codegen/models/constant_type.py +129 -0
- package/generator/build/lib/pygen/codegen/models/credential_types.py +214 -0
- package/generator/build/lib/pygen/codegen/models/dictionary_type.py +127 -0
- package/generator/build/lib/pygen/codegen/models/enum_type.py +238 -0
- package/generator/build/lib/pygen/codegen/models/imports.py +291 -0
- package/generator/build/lib/pygen/codegen/models/list_type.py +143 -0
- package/generator/build/lib/pygen/codegen/models/lro_operation.py +142 -0
- package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +32 -0
- package/generator/build/lib/pygen/codegen/models/model_type.py +357 -0
- package/generator/build/lib/pygen/codegen/models/operation.py +509 -0
- package/generator/build/lib/pygen/codegen/models/operation_group.py +184 -0
- package/generator/build/lib/pygen/codegen/models/paging_operation.py +155 -0
- package/generator/build/lib/pygen/codegen/models/parameter.py +412 -0
- package/generator/build/lib/pygen/codegen/models/parameter_list.py +387 -0
- package/generator/build/lib/pygen/codegen/models/primitive_types.py +659 -0
- package/generator/build/lib/pygen/codegen/models/property.py +170 -0
- package/generator/build/lib/pygen/codegen/models/request_builder.py +189 -0
- package/generator/build/lib/pygen/codegen/models/request_builder_parameter.py +115 -0
- package/generator/build/lib/pygen/codegen/models/response.py +348 -0
- package/generator/build/lib/pygen/codegen/models/utils.py +21 -0
- package/generator/build/lib/pygen/codegen/serializers/__init__.py +574 -0
- package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +21 -0
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +1533 -0
- package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +294 -0
- package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +15 -0
- package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +213 -0
- package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +126 -0
- package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +198 -0
- package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +33 -0
- package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +335 -0
- package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +89 -0
- package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +44 -0
- package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +221 -0
- package/generator/build/lib/pygen/codegen/serializers/patch_serializer.py +19 -0
- package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +52 -0
- package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +168 -0
- package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +292 -0
- package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +31 -0
- package/generator/build/lib/pygen/codegen/serializers/utils.py +68 -0
- package/generator/build/lib/pygen/codegen/templates/client.py.jinja2 +37 -0
- package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +12 -0
- package/generator/build/lib/pygen/codegen/templates/config.py.jinja2 +73 -0
- package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +16 -0
- package/generator/build/lib/pygen/codegen/templates/conftest.py.jinja2 +28 -0
- package/generator/build/lib/pygen/codegen/templates/enum.py.jinja2 +13 -0
- package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +10 -0
- package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +24 -0
- package/generator/build/lib/pygen/codegen/templates/keywords.jinja2 +27 -0
- package/generator/build/lib/pygen/codegen/templates/lro_operation.py.jinja2 +16 -0
- package/generator/build/lib/pygen/codegen/templates/lro_paging_operation.py.jinja2 +18 -0
- package/generator/build/lib/pygen/codegen/templates/macros.jinja2 +12 -0
- package/generator/build/lib/pygen/codegen/templates/metadata.json.jinja2 +167 -0
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +1174 -0
- package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +15 -0
- package/generator/build/lib/pygen/codegen/templates/model_dpg.py.jinja2 +97 -0
- package/generator/build/lib/pygen/codegen/templates/model_init.py.jinja2 +33 -0
- package/generator/build/lib/pygen/codegen/templates/model_msrest.py.jinja2 +92 -0
- package/generator/build/lib/pygen/codegen/templates/operation.py.jinja2 +21 -0
- package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +75 -0
- package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +19 -0
- package/generator/build/lib/pygen/codegen/templates/operation_tools.jinja2 +81 -0
- package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +17 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/CHANGELOG.md.jinja2 +6 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/LICENSE.jinja2 +21 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +8 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +107 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +9 -0
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +108 -0
- package/generator/build/lib/pygen/codegen/templates/paging_operation.py.jinja2 +21 -0
- package/generator/build/lib/pygen/codegen/templates/patch.py.jinja2 +19 -0
- package/generator/build/lib/pygen/codegen/templates/pkgutil_init.py.jinja2 +1 -0
- package/generator/build/lib/pygen/codegen/templates/request_builder.py.jinja2 +28 -0
- package/generator/build/lib/pygen/codegen/templates/request_builders.py.jinja2 +10 -0
- package/generator/build/lib/pygen/codegen/templates/rest_init.py.jinja2 +12 -0
- package/generator/build/lib/pygen/codegen/templates/sample.py.jinja2 +44 -0
- package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +2117 -0
- package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +50 -0
- package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +26 -0
- package/generator/build/lib/pygen/codegen/templates/types.py.jinja2 +7 -0
- package/generator/build/lib/pygen/codegen/templates/validation.py.jinja2 +38 -0
- package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +96 -0
- package/generator/build/lib/pygen/codegen/templates/version.py.jinja2 +4 -0
- package/generator/build/lib/pygen/m2r.py +65 -0
- package/generator/build/lib/pygen/preprocess/__init__.py +515 -0
- package/generator/build/lib/pygen/preprocess/helpers.py +27 -0
- package/generator/build/lib/pygen/preprocess/python_mappings.py +226 -0
- package/generator/build/lib/pygen/utils.py +163 -0
- package/generator/component-detection-pip-report.json +134 -0
- package/generator/dev_requirements.txt +0 -1
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/__init__.py +4 -4
- package/generator/pygen.egg-info/PKG-INFO +7 -4
- package/generator/pygen.egg-info/requires.txt +7 -4
- package/generator/setup.py +7 -4
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_flatten_async.py +1 -1
- package/generator/test/{generic_mock_api_tests/asynctests/test_payload_pageable_async.py → azure/mock_api_tests/asynctests/test_azure_payload_pageable_async.py} +1 -1
- package/generator/test/azure/mock_api_tests/conftest.py +5 -4
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_flatten.py +1 -1
- package/generator/test/{generic_mock_api_tests/test_payload_pageable.py → azure/mock_api_tests/test_azure_payload_pageable.py} +1 -1
- package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_resiliency_srv_driven.py +4 -2
- package/generator/test/{generic_mock_api_tests/asynctests → azure/mock_api_tests}/test_resiliency_srv_driven_async.py +3 -2
- package/generator/test/azure/requirements.txt +9 -8
- package/generator/test/generic_mock_api_tests/conftest.py +9 -4
- package/generator/test/unbranded/mock_api_tests/conftest.py +4 -4
- package/generator/test/unbranded/mock_api_tests/test_unbranded.py +1 -1
- package/generator/test/unbranded/requirements.txt +1 -8
- package/package.json +10 -10
- package/generator/requirements.txt +0 -12
- /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/asynctests/test_client_naming_async.py +0 -0
- /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/asynctests/test_client_structure_async.py +0 -0
- /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_client_naming.py +0 -0
- /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_client_structure.py +0 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
from typing import List
|
|
7
|
+
|
|
8
|
+
from . import utils
|
|
9
|
+
from ..models import Client, ParameterMethodLocation
|
|
10
|
+
from .parameter_serializer import ParameterSerializer, PopKwargType
|
|
11
|
+
from ...utils import build_policies
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ClientSerializer:
|
|
15
|
+
def __init__(self, client: Client) -> None:
|
|
16
|
+
self.client = client
|
|
17
|
+
self.parameter_serializer = ParameterSerializer()
|
|
18
|
+
|
|
19
|
+
def _init_signature(self, async_mode: bool) -> str:
|
|
20
|
+
pylint_disable = ""
|
|
21
|
+
if not self.client.parameters.credential:
|
|
22
|
+
pylint_disable = " # pylint: disable=missing-client-constructor-parameter-credential"
|
|
23
|
+
return self.parameter_serializer.serialize_method(
|
|
24
|
+
function_def="def",
|
|
25
|
+
method_name="__init__",
|
|
26
|
+
need_self_param=True,
|
|
27
|
+
method_param_signatures=self.client.parameters.method_signature(async_mode),
|
|
28
|
+
pylint_disable=pylint_disable,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def init_signature_and_response_type_annotation(self, async_mode: bool) -> str:
|
|
32
|
+
init_signature = self._init_signature(async_mode)
|
|
33
|
+
return utils.method_signature_and_response_type_annotation_template(
|
|
34
|
+
method_signature=init_signature,
|
|
35
|
+
response_type_annotation="None",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def pop_kwargs_from_signature(self) -> List[str]:
|
|
39
|
+
return self.parameter_serializer.pop_kwargs_from_signature(
|
|
40
|
+
self.client.parameters.kwargs_to_pop,
|
|
41
|
+
check_kwarg_dict=False,
|
|
42
|
+
pop_headers_kwarg=PopKwargType.NO,
|
|
43
|
+
pop_params_kwarg=PopKwargType.NO,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def class_definition(self) -> str:
|
|
47
|
+
class_name = self.client.name
|
|
48
|
+
base_class = ""
|
|
49
|
+
if self.client.has_mixin:
|
|
50
|
+
base_class = f"{class_name}OperationsMixin"
|
|
51
|
+
pylint_disable = self.client.pylint_disable()
|
|
52
|
+
if base_class:
|
|
53
|
+
return f"class {class_name}({base_class}):{pylint_disable}"
|
|
54
|
+
return f"class {class_name}:{pylint_disable}"
|
|
55
|
+
|
|
56
|
+
def property_descriptions(self, async_mode: bool) -> List[str]:
|
|
57
|
+
retval: List[str] = []
|
|
58
|
+
operations_folder = ".aio.operations." if async_mode else ".operations."
|
|
59
|
+
for og in [og for og in self.client.operation_groups if not og.is_mixin]:
|
|
60
|
+
retval.append(f":ivar {og.property_name}: {og.class_name} operations")
|
|
61
|
+
property_type = f"{self.client.code_model.namespace}{operations_folder}{og.class_name}"
|
|
62
|
+
retval.append(f":vartype {og.property_name}: {property_type}")
|
|
63
|
+
for param in self.client.parameters.method:
|
|
64
|
+
retval.append(f":{param.description_keyword} {param.client_name}: {param.description}")
|
|
65
|
+
retval.append(
|
|
66
|
+
f":{param.docstring_type_keyword} {param.client_name}: {param.docstring_type(async_mode=async_mode)}"
|
|
67
|
+
)
|
|
68
|
+
if self.client.has_public_lro_operations:
|
|
69
|
+
retval.append(
|
|
70
|
+
":keyword int polling_interval: Default waiting time between two polls for LRO operations "
|
|
71
|
+
"if no Retry-After header is present."
|
|
72
|
+
)
|
|
73
|
+
retval = [s.replace("\\", "\\\\") for s in retval]
|
|
74
|
+
retval.append('"""')
|
|
75
|
+
return retval
|
|
76
|
+
|
|
77
|
+
def initialize_config(self) -> str:
|
|
78
|
+
config_name = f"{self.client.name}Configuration"
|
|
79
|
+
config_call = ", ".join(
|
|
80
|
+
[
|
|
81
|
+
f"{p.client_name}={p.client_name}"
|
|
82
|
+
for p in self.client.config.parameters.method
|
|
83
|
+
if p.method_location != ParameterMethodLocation.KWARG
|
|
84
|
+
]
|
|
85
|
+
+ ["**kwargs"]
|
|
86
|
+
)
|
|
87
|
+
return f"self._config = {config_name}({config_call})"
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def host_variable_name(self) -> str:
|
|
91
|
+
try:
|
|
92
|
+
return next(p for p in self.client.parameters if p.is_host).client_name
|
|
93
|
+
except StopIteration:
|
|
94
|
+
return "_endpoint"
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def should_init_super(self) -> bool:
|
|
98
|
+
return any(og for og in self.client.operation_groups if og.is_mixin and og.has_abstract_operations)
|
|
99
|
+
|
|
100
|
+
def initialize_pipeline_client(self, async_mode: bool) -> List[str]:
|
|
101
|
+
result = []
|
|
102
|
+
pipeline_client_name = self.client.pipeline_class(async_mode)
|
|
103
|
+
endpoint_name = "base_url" if self.client.code_model.is_azure_flavor else "endpoint"
|
|
104
|
+
params = {
|
|
105
|
+
endpoint_name: self.host_variable_name,
|
|
106
|
+
"policies": "_policies",
|
|
107
|
+
}
|
|
108
|
+
if not self.client.code_model.is_legacy and self.client.request_id_header_name:
|
|
109
|
+
result.append(f'kwargs["request_id_header_name"] = "{self.client.request_id_header_name}"')
|
|
110
|
+
policies = build_policies(
|
|
111
|
+
self.client.code_model.options["azure_arm"],
|
|
112
|
+
async_mode,
|
|
113
|
+
is_azure_flavor=self.client.code_model.is_azure_flavor,
|
|
114
|
+
tracing=self.client.code_model.options["tracing"],
|
|
115
|
+
)
|
|
116
|
+
result.extend(
|
|
117
|
+
[
|
|
118
|
+
"_policies = kwargs.pop('policies', None)",
|
|
119
|
+
"if _policies is None:",
|
|
120
|
+
f' _policies = [{",".join(policies)}]',
|
|
121
|
+
f"self._client: {pipeline_client_name} = {pipeline_client_name}("
|
|
122
|
+
f"{', '.join(f'{k}={v}' for k, v in params.items())}, **kwargs)",
|
|
123
|
+
]
|
|
124
|
+
)
|
|
125
|
+
return result
|
|
126
|
+
|
|
127
|
+
def serializers_and_operation_groups_properties(self) -> List[str]:
|
|
128
|
+
retval = []
|
|
129
|
+
|
|
130
|
+
def _get_client_models_value(models_dict_name: str) -> str:
|
|
131
|
+
if self.client.code_model.model_types:
|
|
132
|
+
return f"{{k: v for k, v in {models_dict_name}.__dict__.items() if isinstance(v, type)}}"
|
|
133
|
+
return "{}"
|
|
134
|
+
|
|
135
|
+
is_msrest_model = self.client.code_model.options["models_mode"] == "msrest"
|
|
136
|
+
if is_msrest_model:
|
|
137
|
+
add_private_models = len(self.client.code_model.model_types) != len(
|
|
138
|
+
self.client.code_model.public_model_types
|
|
139
|
+
)
|
|
140
|
+
model_dict_name = f"_models.{self.client.code_model.models_filename}" if add_private_models else "_models"
|
|
141
|
+
retval.append(
|
|
142
|
+
f"client_models{': Dict[str, Any]' if not self.client.code_model.model_types else ''}"
|
|
143
|
+
f" = {_get_client_models_value(model_dict_name)}"
|
|
144
|
+
)
|
|
145
|
+
if add_private_models and self.client.code_model.model_types:
|
|
146
|
+
update_dict = "{k: v for k, v in _models.__dict__.items() if isinstance(v, type)}"
|
|
147
|
+
retval.append(f"client_models.update({update_dict})")
|
|
148
|
+
client_models_str = "client_models" if is_msrest_model else ""
|
|
149
|
+
retval.append(f"self._serialize = Serializer({client_models_str})")
|
|
150
|
+
retval.append(f"self._deserialize = Deserializer({client_models_str})")
|
|
151
|
+
if not self.client.code_model.options["client_side_validation"]:
|
|
152
|
+
retval.append("self._serialize.client_side_validation = False")
|
|
153
|
+
operation_groups = [og for og in self.client.operation_groups if not og.is_mixin]
|
|
154
|
+
for og in operation_groups:
|
|
155
|
+
if og.code_model.options["multiapi"]:
|
|
156
|
+
api_version = f", '{og.api_versions[0]}'" if og.api_versions else ", None"
|
|
157
|
+
else:
|
|
158
|
+
api_version = ""
|
|
159
|
+
retval.extend(
|
|
160
|
+
[
|
|
161
|
+
f"self.{og.property_name} = {og.class_name}(",
|
|
162
|
+
f" self._client, self._config, self._serialize, self._deserialize{api_version}",
|
|
163
|
+
")",
|
|
164
|
+
]
|
|
165
|
+
)
|
|
166
|
+
return retval
|
|
167
|
+
|
|
168
|
+
def _send_request_signature(self) -> str:
|
|
169
|
+
send_request_signature = [
|
|
170
|
+
"request: HttpRequest, *, stream: bool = False,"
|
|
171
|
+
] + self.client.parameters.method_signature_kwargs
|
|
172
|
+
return self.parameter_serializer.serialize_method(
|
|
173
|
+
function_def="def",
|
|
174
|
+
method_name=self.client.send_request_name,
|
|
175
|
+
need_self_param=True,
|
|
176
|
+
method_param_signatures=send_request_signature,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
def send_request_signature_and_response_type_annotation(self, async_mode: bool) -> str:
|
|
180
|
+
send_request_signature = self._send_request_signature()
|
|
181
|
+
return utils.method_signature_and_response_type_annotation_template(
|
|
182
|
+
method_signature=send_request_signature,
|
|
183
|
+
response_type_annotation=("Awaitable[AsyncHttpResponse]" if async_mode else "HttpResponse"),
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
def _example_make_call(self, async_mode: bool) -> List[str]:
|
|
187
|
+
http_response = "AsyncHttpResponse" if async_mode else "HttpResponse"
|
|
188
|
+
retval = [f">>> response = {'await ' if async_mode else ''}client.{self.client.send_request_name}(request)"]
|
|
189
|
+
retval.append(f"<{http_response}: 200 OK>")
|
|
190
|
+
return retval
|
|
191
|
+
|
|
192
|
+
def _request_builder_example(self, async_mode: bool) -> List[str]:
|
|
193
|
+
retval = [
|
|
194
|
+
"We have helper methods to create requests specific to this service in "
|
|
195
|
+
+ f"`{self.client.code_model.namespace}.{self.client.code_model.rest_layer_name}`."
|
|
196
|
+
]
|
|
197
|
+
retval.append("Use these helper methods to create the request you pass to this method.")
|
|
198
|
+
retval.append("")
|
|
199
|
+
|
|
200
|
+
request_builder = self.client.request_builders[0]
|
|
201
|
+
request_builder_signature = ", ".join(request_builder.parameters.call)
|
|
202
|
+
if request_builder.group_name:
|
|
203
|
+
rest_imported = request_builder.group_name
|
|
204
|
+
request_builder_name = f"{request_builder.group_name}.{request_builder.name}"
|
|
205
|
+
else:
|
|
206
|
+
rest_imported = request_builder.name
|
|
207
|
+
request_builder_name = request_builder.name
|
|
208
|
+
full_path = f"{self.client.code_model.namespace}.{self.client.code_model.rest_layer_name}"
|
|
209
|
+
retval.append(f">>> from {full_path} import {rest_imported}")
|
|
210
|
+
retval.append(f">>> request = {request_builder_name}({request_builder_signature})")
|
|
211
|
+
retval.append(f"<HttpRequest [{request_builder.method}], url: '{request_builder.url}'>")
|
|
212
|
+
retval.extend(self._example_make_call(async_mode))
|
|
213
|
+
return retval
|
|
214
|
+
|
|
215
|
+
def _rest_request_example(self, async_mode: bool) -> List[str]:
|
|
216
|
+
retval = [f">>> from {self.client.code_model.core_library}.rest import HttpRequest"]
|
|
217
|
+
retval.append('>>> request = HttpRequest("GET", "https://www.example.org/")')
|
|
218
|
+
retval.append("<HttpRequest [GET], url: 'https://www.example.org/'>")
|
|
219
|
+
retval.extend(self._example_make_call(async_mode))
|
|
220
|
+
return retval
|
|
221
|
+
|
|
222
|
+
def send_request_description(self, async_mode: bool) -> List[str]:
|
|
223
|
+
rest_library = f"{self.client.code_model.core_library}.rest"
|
|
224
|
+
retval = ['"""Runs the network request through the client\'s chained policies.']
|
|
225
|
+
retval.append("")
|
|
226
|
+
if self.client.code_model.options["builders_visibility"] != "embedded":
|
|
227
|
+
retval.extend(self._request_builder_example(async_mode))
|
|
228
|
+
else:
|
|
229
|
+
retval.extend(self._rest_request_example(async_mode))
|
|
230
|
+
retval.append("")
|
|
231
|
+
retval.append("For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request")
|
|
232
|
+
retval.append("")
|
|
233
|
+
retval.append(":param request: The network request you want to make. Required.")
|
|
234
|
+
retval.append(f":type request: ~{rest_library}.HttpRequest")
|
|
235
|
+
retval.append(":keyword bool stream: Whether the response payload will be streamed. Defaults to False.")
|
|
236
|
+
retval.append(":return: The response of your network call. Does not do error handling on your response.")
|
|
237
|
+
http_response = "AsyncHttpResponse" if async_mode else "HttpResponse"
|
|
238
|
+
retval.append(f":rtype: ~{rest_library}.{http_response}")
|
|
239
|
+
retval.append('"""')
|
|
240
|
+
return retval
|
|
241
|
+
|
|
242
|
+
def serialize_path(self) -> List[str]:
|
|
243
|
+
return self.parameter_serializer.serialize_path(self.client.parameters.path, "self._serialize")
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
class ConfigSerializer:
|
|
247
|
+
def __init__(self, client: Client) -> None:
|
|
248
|
+
self.client = client
|
|
249
|
+
self.parameter_serializer = ParameterSerializer()
|
|
250
|
+
|
|
251
|
+
def _init_signature(self, async_mode: bool) -> str:
|
|
252
|
+
return self.parameter_serializer.serialize_method(
|
|
253
|
+
function_def="def",
|
|
254
|
+
method_name="__init__",
|
|
255
|
+
need_self_param=True,
|
|
256
|
+
method_param_signatures=self.client.config.parameters.method_signature(async_mode),
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def init_signature_and_response_type_annotation(self, async_mode: bool) -> str:
|
|
260
|
+
init_signature = self._init_signature(async_mode)
|
|
261
|
+
return utils.method_signature_and_response_type_annotation_template(
|
|
262
|
+
method_signature=init_signature,
|
|
263
|
+
response_type_annotation="None",
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
def pop_kwargs_from_signature(self) -> List[str]:
|
|
267
|
+
return self.parameter_serializer.pop_kwargs_from_signature(
|
|
268
|
+
self.client.config.parameters.kwargs_to_pop,
|
|
269
|
+
check_kwarg_dict=False,
|
|
270
|
+
pop_headers_kwarg=PopKwargType.NO,
|
|
271
|
+
pop_params_kwarg=PopKwargType.NO,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def set_constants(self) -> List[str]:
|
|
275
|
+
return [
|
|
276
|
+
f"self.{p.client_name} = {p.client_default_value_declaration}"
|
|
277
|
+
for p in self.client.config.parameters.constant
|
|
278
|
+
if p not in self.client.config.parameters.method
|
|
279
|
+
]
|
|
280
|
+
|
|
281
|
+
def check_required_parameters(self) -> List[str]:
|
|
282
|
+
return [
|
|
283
|
+
f"if {p.client_name} is None:\n" f" raise ValueError(\"Parameter '{p.client_name}' must not be None.\")"
|
|
284
|
+
for p in self.client.config.parameters.method
|
|
285
|
+
if not (p.optional or p.constant)
|
|
286
|
+
]
|
|
287
|
+
|
|
288
|
+
def property_descriptions(self, async_mode: bool) -> List[str]:
|
|
289
|
+
retval: List[str] = []
|
|
290
|
+
for p in self.client.config.parameters.method:
|
|
291
|
+
retval.append(f":{p.description_keyword} {p.client_name}: {p.description}")
|
|
292
|
+
retval.append(f":{p.docstring_type_keyword} {p.client_name}: {p.docstring_type(async_mode=async_mode)}")
|
|
293
|
+
retval.append('"""')
|
|
294
|
+
return retval
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
from .base_serializer import BaseSerializer
|
|
8
|
+
from ..models import FileImport
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class EnumSerializer(BaseSerializer):
|
|
12
|
+
def serialize(self) -> str:
|
|
13
|
+
# Generate the enum file
|
|
14
|
+
template = self.env.get_template("enum_container.py.jinja2")
|
|
15
|
+
return template.render(code_model=self.code_model, file_import=FileImport(self.code_model))
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
import json
|
|
7
|
+
from typing import Any, List
|
|
8
|
+
from jinja2 import Environment
|
|
9
|
+
from .import_serializer import FileImportSerializer, TypingSection
|
|
10
|
+
from ..models.imports import MsrestImportType, FileImport
|
|
11
|
+
from ..models import (
|
|
12
|
+
ImportType,
|
|
13
|
+
CodeModel,
|
|
14
|
+
TokenCredentialType,
|
|
15
|
+
Client,
|
|
16
|
+
)
|
|
17
|
+
from .client_serializer import ClientSerializer, ConfigSerializer
|
|
18
|
+
from .base_serializer import BaseSerializer
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class GeneralSerializer(BaseSerializer):
|
|
22
|
+
"""General serializer for SDK root level files"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, code_model: CodeModel, env: Environment, async_mode: bool):
|
|
25
|
+
super().__init__(code_model, env)
|
|
26
|
+
self.async_mode = async_mode
|
|
27
|
+
|
|
28
|
+
def serialize_setup_file(self) -> str:
|
|
29
|
+
template = self.env.get_template("packaging_templates/setup.py.jinja2")
|
|
30
|
+
params = {}
|
|
31
|
+
params.update(self.code_model.options)
|
|
32
|
+
return template.render(code_model=self.code_model, **params)
|
|
33
|
+
|
|
34
|
+
def serialize_package_file(self, template_name: str, **kwargs: Any) -> str:
|
|
35
|
+
template = self.env.get_template(template_name)
|
|
36
|
+
package_parts = (self.code_model.options["package_name"] or "").split("-")[:-1]
|
|
37
|
+
token_credential = any(
|
|
38
|
+
c for c in self.code_model.clients if isinstance(getattr(c.credential, "type", None), TokenCredentialType)
|
|
39
|
+
)
|
|
40
|
+
version = self.code_model.options["package_version"]
|
|
41
|
+
if any(x in version for x in ["a", "b", "rc"]) or version[0] == "0":
|
|
42
|
+
dev_status = "4 - Beta"
|
|
43
|
+
else:
|
|
44
|
+
dev_status = "5 - Production/Stable"
|
|
45
|
+
params = {
|
|
46
|
+
"code_model": self.code_model,
|
|
47
|
+
"dev_status": dev_status,
|
|
48
|
+
"token_credential": token_credential,
|
|
49
|
+
"pkgutil_names": [".".join(package_parts[: i + 1]) for i in range(len(package_parts))],
|
|
50
|
+
"init_names": ["/".join(package_parts[: i + 1]) + "/__init__.py" for i in range(len(package_parts))],
|
|
51
|
+
"client_name": self.code_model.clients[0].name,
|
|
52
|
+
"namespace": self.code_model.namespace,
|
|
53
|
+
}
|
|
54
|
+
params.update(self.code_model.options)
|
|
55
|
+
params.update(kwargs)
|
|
56
|
+
return template.render(file_import=FileImport(self.code_model), **params)
|
|
57
|
+
|
|
58
|
+
def serialize_pkgutil_init_file(self) -> str:
|
|
59
|
+
template = self.env.get_template("pkgutil_init.py.jinja2")
|
|
60
|
+
return template.render()
|
|
61
|
+
|
|
62
|
+
def serialize_init_file(self, clients: List[Client]) -> str:
|
|
63
|
+
template = self.env.get_template("init.py.jinja2")
|
|
64
|
+
return template.render(
|
|
65
|
+
code_model=self.code_model,
|
|
66
|
+
clients=clients,
|
|
67
|
+
async_mode=self.async_mode,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def serialize_service_client_file(self, clients: List[Client]) -> str:
|
|
71
|
+
template = self.env.get_template("client_container.py.jinja2")
|
|
72
|
+
|
|
73
|
+
imports = FileImport(self.code_model)
|
|
74
|
+
for client in clients:
|
|
75
|
+
imports.merge(client.imports(self.async_mode))
|
|
76
|
+
|
|
77
|
+
return template.render(
|
|
78
|
+
code_model=self.code_model,
|
|
79
|
+
clients=clients,
|
|
80
|
+
async_mode=self.async_mode,
|
|
81
|
+
get_serializer=ClientSerializer,
|
|
82
|
+
imports=FileImportSerializer(imports),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def serialize_vendor_file(self, clients: List[Client]) -> str:
|
|
86
|
+
template = self.env.get_template("vendor.py.jinja2")
|
|
87
|
+
|
|
88
|
+
# configure imports
|
|
89
|
+
file_import = FileImport(self.code_model)
|
|
90
|
+
if self.code_model.need_mixin_abc:
|
|
91
|
+
file_import.add_submodule_import(
|
|
92
|
+
"abc",
|
|
93
|
+
"ABC",
|
|
94
|
+
ImportType.STDLIB,
|
|
95
|
+
)
|
|
96
|
+
file_import.add_submodule_import(
|
|
97
|
+
"" if self.code_model.is_azure_flavor else "runtime",
|
|
98
|
+
f"{'Async' if self.async_mode else ''}PipelineClient",
|
|
99
|
+
ImportType.SDKCORE,
|
|
100
|
+
TypingSection.TYPING,
|
|
101
|
+
)
|
|
102
|
+
file_import.add_msrest_import(
|
|
103
|
+
relative_path=".." if self.async_mode else ".",
|
|
104
|
+
msrest_import_type=MsrestImportType.SerializerDeserializer,
|
|
105
|
+
typing_section=TypingSection.TYPING,
|
|
106
|
+
)
|
|
107
|
+
for client in clients:
|
|
108
|
+
if client.has_mixin:
|
|
109
|
+
file_import.add_submodule_import(
|
|
110
|
+
"._configuration",
|
|
111
|
+
f"{client.name}Configuration",
|
|
112
|
+
ImportType.LOCAL,
|
|
113
|
+
)
|
|
114
|
+
if self.code_model.has_etag:
|
|
115
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
|
|
116
|
+
file_import.add_submodule_import(
|
|
117
|
+
"",
|
|
118
|
+
"MatchConditions",
|
|
119
|
+
ImportType.SDKCORE,
|
|
120
|
+
)
|
|
121
|
+
if self.code_model.has_form_data and self.code_model.options["models_mode"] == "dpg" and not self.async_mode:
|
|
122
|
+
file_import.add_submodule_import("typing", "IO", ImportType.STDLIB)
|
|
123
|
+
file_import.add_submodule_import("typing", "Tuple", ImportType.STDLIB)
|
|
124
|
+
file_import.add_submodule_import("typing", "Union", ImportType.STDLIB)
|
|
125
|
+
file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
|
|
126
|
+
file_import.add_submodule_import("typing", "Mapping", ImportType.STDLIB)
|
|
127
|
+
file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB)
|
|
128
|
+
file_import.add_submodule_import("typing", "Any", ImportType.STDLIB)
|
|
129
|
+
file_import.add_submodule_import("typing", "List", ImportType.STDLIB)
|
|
130
|
+
file_import.add_submodule_import(
|
|
131
|
+
"._model_base",
|
|
132
|
+
"SdkJSONEncoder",
|
|
133
|
+
ImportType.LOCAL,
|
|
134
|
+
)
|
|
135
|
+
file_import.add_submodule_import(
|
|
136
|
+
"._model_base",
|
|
137
|
+
"Model",
|
|
138
|
+
ImportType.LOCAL,
|
|
139
|
+
)
|
|
140
|
+
file_import.add_import("json", ImportType.STDLIB)
|
|
141
|
+
|
|
142
|
+
return template.render(
|
|
143
|
+
code_model=self.code_model,
|
|
144
|
+
imports=FileImportSerializer(
|
|
145
|
+
file_import,
|
|
146
|
+
),
|
|
147
|
+
async_mode=self.async_mode,
|
|
148
|
+
clients=clients,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def serialize_config_file(self, clients: List[Client]) -> str:
|
|
152
|
+
template = self.env.get_template("config_container.py.jinja2")
|
|
153
|
+
imports = FileImport(self.code_model)
|
|
154
|
+
for client in self.code_model.clients:
|
|
155
|
+
imports.merge(client.config.imports(self.async_mode))
|
|
156
|
+
return template.render(
|
|
157
|
+
code_model=self.code_model,
|
|
158
|
+
async_mode=self.async_mode,
|
|
159
|
+
imports=FileImportSerializer(imports),
|
|
160
|
+
get_serializer=ConfigSerializer,
|
|
161
|
+
clients=clients,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def serialize_version_file(self) -> str:
|
|
165
|
+
template = self.env.get_template("version.py.jinja2")
|
|
166
|
+
return template.render(code_model=self.code_model)
|
|
167
|
+
|
|
168
|
+
def serialize_serialization_file(self) -> str:
|
|
169
|
+
template = self.env.get_template("serialization.py.jinja2")
|
|
170
|
+
return template.render(
|
|
171
|
+
code_model=self.code_model,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
def serialize_model_base_file(self) -> str:
|
|
175
|
+
template = self.env.get_template("model_base.py.jinja2")
|
|
176
|
+
return template.render(code_model=self.code_model, file_import=FileImport(self.code_model))
|
|
177
|
+
|
|
178
|
+
def serialize_validation_file(self) -> str:
|
|
179
|
+
template = self.env.get_template("validation.py.jinja2")
|
|
180
|
+
return template.render(code_model=self.code_model)
|
|
181
|
+
|
|
182
|
+
def serialize_cross_language_definition_file(self) -> str:
|
|
183
|
+
cross_langauge_def_dict = {
|
|
184
|
+
f"{self.code_model.namespace}.models.{model.name}": model.cross_language_definition_id
|
|
185
|
+
for model in self.code_model.public_model_types
|
|
186
|
+
}
|
|
187
|
+
cross_langauge_def_dict.update(
|
|
188
|
+
{
|
|
189
|
+
f"{self.code_model.namespace}.models.{enum.name}": enum.cross_language_definition_id
|
|
190
|
+
for enum in self.code_model.enums
|
|
191
|
+
if not enum.internal
|
|
192
|
+
}
|
|
193
|
+
)
|
|
194
|
+
cross_langauge_def_dict.update(
|
|
195
|
+
{
|
|
196
|
+
(
|
|
197
|
+
f"{self.code_model.namespace}.{client.name}."
|
|
198
|
+
+ ("" if operation_group.is_mixin else f"{operation_group.property_name}.")
|
|
199
|
+
+ f"{operation.name}"
|
|
200
|
+
): operation.cross_language_definition_id
|
|
201
|
+
for client in self.code_model.clients
|
|
202
|
+
for operation_group in client.operation_groups
|
|
203
|
+
for operation in operation_group.operations
|
|
204
|
+
if not operation.name.startswith("_")
|
|
205
|
+
}
|
|
206
|
+
)
|
|
207
|
+
return json.dumps(
|
|
208
|
+
{
|
|
209
|
+
"CrossLanguagePackageId": self.code_model.cross_language_package_id,
|
|
210
|
+
"CrossLanguageDefinitionId": cross_langauge_def_dict,
|
|
211
|
+
},
|
|
212
|
+
indent=4,
|
|
213
|
+
)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# -------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
+
# license information.
|
|
5
|
+
# --------------------------------------------------------------------------
|
|
6
|
+
from copy import deepcopy
|
|
7
|
+
from typing import List
|
|
8
|
+
from ..models.imports import (
|
|
9
|
+
ImportType,
|
|
10
|
+
FileImport,
|
|
11
|
+
ImportModel,
|
|
12
|
+
TypingSection,
|
|
13
|
+
TypeDefinition,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _serialize_package(imports: List[ImportModel], delimiter: str) -> str:
|
|
18
|
+
buffer = []
|
|
19
|
+
if any(i for i in imports if i.submodule_name is None):
|
|
20
|
+
buffer.append(f"import {imports[0].module_name}{f' as {imports[0].alias}' if imports[0].alias else ''}")
|
|
21
|
+
else:
|
|
22
|
+
import_str = ", ".join(
|
|
23
|
+
sorted(
|
|
24
|
+
set(
|
|
25
|
+
f"{i.submodule_name} as {i.alias}" if i.alias else i.submodule_name for i in imports # type: ignore
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
buffer.append(f"from {imports[0].module_name} import {import_str}")
|
|
30
|
+
return delimiter.join(buffer)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _serialize_versioned_package(i: ImportModel, delimiter: str) -> str:
|
|
34
|
+
if not i.version_modules:
|
|
35
|
+
return ""
|
|
36
|
+
buffer = []
|
|
37
|
+
for n, (version, module_name, comment) in enumerate(i.version_modules):
|
|
38
|
+
buffer.append("{} sys.version_info >= {}:".format("if" if n == 0 else "elif", version))
|
|
39
|
+
buffer.append(
|
|
40
|
+
f" from {module_name} import {i.submodule_name}{f' as {i.alias}' if i.alias else ''}"
|
|
41
|
+
f"{f' # {comment}' if comment else ''}"
|
|
42
|
+
)
|
|
43
|
+
buffer.append("else:")
|
|
44
|
+
buffer.append(
|
|
45
|
+
f" from {i.module_name} import {i.submodule_name}{f' as {i.alias}' if i.alias else ''}" " # type: ignore"
|
|
46
|
+
)
|
|
47
|
+
return delimiter.join(buffer)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _serialize_import_type(imports: List[ImportModel], delimiter: str) -> str:
|
|
51
|
+
"""Serialize a given import type."""
|
|
52
|
+
import_list = []
|
|
53
|
+
for module_name in sorted(set(i.module_name for i in imports)):
|
|
54
|
+
normal_imports = [i for i in imports if i.module_name == module_name and not i.version_modules]
|
|
55
|
+
versioned_imports = [i for i in imports if i.module_name == module_name and i.version_modules]
|
|
56
|
+
if normal_imports:
|
|
57
|
+
import_list.append(_serialize_package(normal_imports, delimiter))
|
|
58
|
+
for i in versioned_imports:
|
|
59
|
+
import_list.append(_serialize_versioned_package(i, delimiter))
|
|
60
|
+
return delimiter.join(import_list)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _get_import_clauses(imports: List[ImportModel], delimiter: str) -> List[str]:
|
|
64
|
+
import_clause = []
|
|
65
|
+
for import_type in ImportType:
|
|
66
|
+
imports_with_import_type = [i for i in imports if i.import_type == import_type]
|
|
67
|
+
if imports_with_import_type:
|
|
68
|
+
import_clause.append(_serialize_import_type(imports_with_import_type, delimiter))
|
|
69
|
+
return import_clause
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class FileImportSerializer:
|
|
73
|
+
def __init__(self, file_import: FileImport, async_mode: bool = False) -> None:
|
|
74
|
+
self.file_import = file_import
|
|
75
|
+
self.async_mode = async_mode
|
|
76
|
+
|
|
77
|
+
def _get_imports_list(self, baseline_typing_section: TypingSection, add_conditional_typing: bool):
|
|
78
|
+
# If this is a python 3 file, our regular imports include the CONDITIONAL category
|
|
79
|
+
# If this is not a python 3 file, our typing imports include the CONDITIONAL category
|
|
80
|
+
file_import_copy = deepcopy(self.file_import)
|
|
81
|
+
if add_conditional_typing and any(self.file_import.get_imports_from_section(TypingSection.CONDITIONAL)):
|
|
82
|
+
# we switch the TypingSection key for the CONDITIONAL typing imports so we can merge
|
|
83
|
+
# the imports together
|
|
84
|
+
for i in file_import_copy.imports:
|
|
85
|
+
if i.typing_section == TypingSection.CONDITIONAL:
|
|
86
|
+
i.typing_section = baseline_typing_section
|
|
87
|
+
return file_import_copy.get_imports_from_section(baseline_typing_section)
|
|
88
|
+
|
|
89
|
+
def _add_type_checking_import(self):
|
|
90
|
+
if any(self.file_import.get_imports_from_section(TypingSection.TYPING)):
|
|
91
|
+
self.file_import.add_submodule_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
|
|
92
|
+
|
|
93
|
+
def get_typing_definitions(self) -> str:
|
|
94
|
+
def declare_definition(type_name: str, type_definition: TypeDefinition) -> List[str]:
|
|
95
|
+
ret: List[str] = []
|
|
96
|
+
definition_value = type_definition.async_definition if self.async_mode else type_definition.sync_definition
|
|
97
|
+
ret.append("{} = {}".format(type_name, definition_value))
|
|
98
|
+
return ret
|
|
99
|
+
|
|
100
|
+
if not self.file_import.type_definitions:
|
|
101
|
+
return ""
|
|
102
|
+
declarations: List[str] = [""]
|
|
103
|
+
for type_name, value in self.file_import.type_definitions.items():
|
|
104
|
+
declarations.extend(declare_definition(type_name, value))
|
|
105
|
+
return "\n".join(declarations)
|
|
106
|
+
|
|
107
|
+
def __str__(self) -> str:
|
|
108
|
+
self._add_type_checking_import()
|
|
109
|
+
regular_imports = ""
|
|
110
|
+
regular_imports_list = self._get_imports_list(
|
|
111
|
+
baseline_typing_section=TypingSection.REGULAR,
|
|
112
|
+
add_conditional_typing=True,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
if regular_imports_list:
|
|
116
|
+
regular_imports = "\n\n".join(_get_import_clauses(regular_imports_list, "\n"))
|
|
117
|
+
|
|
118
|
+
typing_imports = ""
|
|
119
|
+
typing_imports_list = self._get_imports_list(
|
|
120
|
+
baseline_typing_section=TypingSection.TYPING,
|
|
121
|
+
add_conditional_typing=False,
|
|
122
|
+
)
|
|
123
|
+
if typing_imports_list:
|
|
124
|
+
typing_imports += "\n\nif TYPE_CHECKING:\n "
|
|
125
|
+
typing_imports += "\n\n ".join(_get_import_clauses(typing_imports_list, "\n "))
|
|
126
|
+
return regular_imports + typing_imports + self.get_typing_definitions()
|