@typespec/http-client-python 0.5.1 → 0.6.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.
Files changed (146) hide show
  1. package/dist/emitter/code-model.d.ts.map +1 -1
  2. package/dist/emitter/code-model.js +10 -7
  3. package/dist/emitter/code-model.js.map +1 -1
  4. package/dist/emitter/emitter.d.ts.map +1 -1
  5. package/dist/emitter/emitter.js +4 -1
  6. package/dist/emitter/emitter.js.map +1 -1
  7. package/dist/emitter/lib.d.ts +1 -0
  8. package/dist/emitter/lib.d.ts.map +1 -1
  9. package/dist/emitter/lib.js +1 -0
  10. package/dist/emitter/lib.js.map +1 -1
  11. package/dist/emitter/types.d.ts.map +1 -1
  12. package/dist/emitter/types.js +7 -4
  13. package/dist/emitter/types.js.map +1 -1
  14. package/dist/emitter/utils.d.ts +1 -0
  15. package/dist/emitter/utils.d.ts.map +1 -1
  16. package/dist/emitter/utils.js +19 -0
  17. package/dist/emitter/utils.js.map +1 -1
  18. package/emitter/src/code-model.ts +16 -6
  19. package/emitter/src/emitter.ts +4 -1
  20. package/emitter/src/lib.ts +4 -0
  21. package/emitter/src/types.ts +16 -4
  22. package/emitter/src/utils.ts +27 -0
  23. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  24. package/eng/scripts/ci/regenerate.ts +7 -0
  25. package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
  26. package/generator/build/lib/pygen/black.py +2 -2
  27. package/generator/build/lib/pygen/codegen/__init__.py +2 -0
  28. package/generator/build/lib/pygen/codegen/_utils.py +4 -0
  29. package/generator/build/lib/pygen/codegen/models/base.py +2 -3
  30. package/generator/build/lib/pygen/codegen/models/base_builder.py +5 -3
  31. package/generator/build/lib/pygen/codegen/models/client.py +28 -19
  32. package/generator/build/lib/pygen/codegen/models/code_model.py +200 -33
  33. package/generator/build/lib/pygen/codegen/models/combined_type.py +8 -5
  34. package/generator/build/lib/pygen/codegen/models/constant_type.py +2 -3
  35. package/generator/build/lib/pygen/codegen/models/credential_types.py +2 -3
  36. package/generator/build/lib/pygen/codegen/models/dictionary_type.py +2 -3
  37. package/generator/build/lib/pygen/codegen/models/enum_type.py +47 -24
  38. package/generator/build/lib/pygen/codegen/models/imports.py +14 -12
  39. package/generator/build/lib/pygen/codegen/models/list_type.py +2 -3
  40. package/generator/build/lib/pygen/codegen/models/lro_operation.py +8 -4
  41. package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +2 -2
  42. package/generator/build/lib/pygen/codegen/models/model_type.py +34 -19
  43. package/generator/build/lib/pygen/codegen/models/operation.py +66 -29
  44. package/generator/build/lib/pygen/codegen/models/operation_group.py +56 -11
  45. package/generator/build/lib/pygen/codegen/models/paging_operation.py +9 -6
  46. package/generator/build/lib/pygen/codegen/models/parameter.py +10 -10
  47. package/generator/build/lib/pygen/codegen/models/parameter_list.py +7 -7
  48. package/generator/build/lib/pygen/codegen/models/primitive_types.py +23 -43
  49. package/generator/build/lib/pygen/codegen/models/property.py +7 -7
  50. package/generator/build/lib/pygen/codegen/models/request_builder.py +9 -15
  51. package/generator/build/lib/pygen/codegen/models/response.py +6 -8
  52. package/generator/build/lib/pygen/codegen/models/utils.py +11 -0
  53. package/generator/build/lib/pygen/codegen/serializers/__init__.py +201 -242
  54. package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +19 -1
  55. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +53 -35
  56. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +9 -5
  57. package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +17 -3
  58. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +26 -14
  59. package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +26 -8
  60. package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +9 -4
  61. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +63 -23
  62. package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +19 -16
  63. package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +5 -10
  64. package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +10 -7
  65. package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +10 -1
  66. package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +7 -10
  67. package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +24 -28
  68. package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +6 -1
  69. package/generator/build/lib/pygen/codegen/serializers/utils.py +1 -15
  70. package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +1 -1
  71. package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +1 -1
  72. package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +1 -1
  73. package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +1 -1
  74. package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +1 -1
  75. package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +2 -4
  76. package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +3 -3
  77. package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +2 -2
  78. package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +4 -4
  79. package/generator/build/lib/pygen/preprocess/__init__.py +0 -4
  80. package/generator/component-detection-pip-report.json +2 -2
  81. package/generator/dev_requirements.txt +2 -2
  82. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  83. package/generator/pygen/black.py +2 -2
  84. package/generator/pygen/codegen/__init__.py +2 -0
  85. package/generator/pygen/codegen/_utils.py +4 -0
  86. package/generator/pygen/codegen/models/base.py +2 -3
  87. package/generator/pygen/codegen/models/base_builder.py +5 -3
  88. package/generator/pygen/codegen/models/client.py +28 -19
  89. package/generator/pygen/codegen/models/code_model.py +200 -33
  90. package/generator/pygen/codegen/models/combined_type.py +8 -5
  91. package/generator/pygen/codegen/models/constant_type.py +2 -3
  92. package/generator/pygen/codegen/models/credential_types.py +2 -3
  93. package/generator/pygen/codegen/models/dictionary_type.py +2 -3
  94. package/generator/pygen/codegen/models/enum_type.py +47 -24
  95. package/generator/pygen/codegen/models/imports.py +14 -12
  96. package/generator/pygen/codegen/models/list_type.py +2 -3
  97. package/generator/pygen/codegen/models/lro_operation.py +8 -4
  98. package/generator/pygen/codegen/models/lro_paging_operation.py +2 -2
  99. package/generator/pygen/codegen/models/model_type.py +34 -19
  100. package/generator/pygen/codegen/models/operation.py +66 -29
  101. package/generator/pygen/codegen/models/operation_group.py +56 -11
  102. package/generator/pygen/codegen/models/paging_operation.py +9 -6
  103. package/generator/pygen/codegen/models/parameter.py +10 -10
  104. package/generator/pygen/codegen/models/parameter_list.py +7 -7
  105. package/generator/pygen/codegen/models/primitive_types.py +23 -43
  106. package/generator/pygen/codegen/models/property.py +7 -7
  107. package/generator/pygen/codegen/models/request_builder.py +9 -15
  108. package/generator/pygen/codegen/models/response.py +6 -8
  109. package/generator/pygen/codegen/models/utils.py +11 -0
  110. package/generator/pygen/codegen/serializers/__init__.py +201 -242
  111. package/generator/pygen/codegen/serializers/base_serializer.py +19 -1
  112. package/generator/pygen/codegen/serializers/builder_serializer.py +53 -35
  113. package/generator/pygen/codegen/serializers/client_serializer.py +9 -5
  114. package/generator/pygen/codegen/serializers/enum_serializer.py +17 -3
  115. package/generator/pygen/codegen/serializers/general_serializer.py +26 -14
  116. package/generator/pygen/codegen/serializers/metadata_serializer.py +26 -8
  117. package/generator/pygen/codegen/serializers/model_init_serializer.py +9 -4
  118. package/generator/pygen/codegen/serializers/model_serializer.py +63 -23
  119. package/generator/pygen/codegen/serializers/operation_groups_serializer.py +19 -16
  120. package/generator/pygen/codegen/serializers/operations_init_serializer.py +5 -10
  121. package/generator/pygen/codegen/serializers/parameter_serializer.py +10 -7
  122. package/generator/pygen/codegen/serializers/request_builders_serializer.py +10 -1
  123. package/generator/pygen/codegen/serializers/sample_serializer.py +7 -10
  124. package/generator/pygen/codegen/serializers/test_serializer.py +24 -28
  125. package/generator/pygen/codegen/serializers/types_serializer.py +6 -1
  126. package/generator/pygen/codegen/serializers/utils.py +1 -15
  127. package/generator/pygen/codegen/templates/client_container.py.jinja2 +1 -1
  128. package/generator/pygen/codegen/templates/config_container.py.jinja2 +1 -1
  129. package/generator/pygen/codegen/templates/enum_container.py.jinja2 +1 -1
  130. package/generator/pygen/codegen/templates/init.py.jinja2 +1 -1
  131. package/generator/pygen/codegen/templates/model_container.py.jinja2 +1 -1
  132. package/generator/pygen/codegen/templates/operations_folder_init.py.jinja2 +2 -4
  133. package/generator/pygen/codegen/templates/test.py.jinja2 +3 -3
  134. package/generator/pygen/codegen/templates/testpreparer.py.jinja2 +2 -2
  135. package/generator/pygen/codegen/templates/vendor.py.jinja2 +4 -4
  136. package/generator/pygen/preprocess/__init__.py +0 -4
  137. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_access_async.py +1 -1
  138. package/generator/test/azure/mock_api_tests/asynctests/test_client_namespace_async.py +31 -0
  139. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_access.py +1 -1
  140. package/generator/test/azure/mock_api_tests/test_client_namespace.py +29 -0
  141. package/generator/test/azure/mock_api_tests/test_resiliency_srv_driven_async.py +1 -0
  142. package/generator/test/azure/requirements.txt +3 -2
  143. package/generator/test/azure/tox.ini +2 -2
  144. package/generator/test/unbranded/requirements.txt +2 -2
  145. package/generator/test/unbranded/tox.ini +2 -2
  146. package/package.json +1 -1
@@ -3,13 +3,14 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
- from typing import List
6
+ from typing import List, Optional
7
7
  from abc import ABC, abstractmethod
8
8
 
9
9
  from ..models import ModelType, Property, ConstantType, EnumValue
10
10
  from ..models.imports import FileImport, TypingSection, MsrestImportType, ImportType
11
11
  from .import_serializer import FileImportSerializer
12
12
  from .base_serializer import BaseSerializer
13
+ from ..models.utils import NamespaceType
13
14
 
14
15
 
15
16
  def _documentation_string(prop: Property, description_keyword: str, docstring_type_keyword: str) -> List[str]:
@@ -22,6 +23,12 @@ def _documentation_string(prop: Property, description_keyword: str, docstring_ty
22
23
 
23
24
 
24
25
  class _ModelSerializer(BaseSerializer, ABC):
26
+ def __init__(
27
+ self, code_model, env, async_mode=False, *, models: List[ModelType], client_namespace: Optional[str] = None
28
+ ):
29
+ super().__init__(code_model, env, async_mode, client_namespace=client_namespace)
30
+ self.models = models
31
+
25
32
  @abstractmethod
26
33
  def imports(self) -> FileImport: ...
27
34
 
@@ -33,6 +40,7 @@ class _ModelSerializer(BaseSerializer, ABC):
33
40
  imports=FileImportSerializer(self.imports()),
34
41
  str=str,
35
42
  serializer=self,
43
+ models=self.models,
36
44
  )
37
45
 
38
46
  @abstractmethod
@@ -63,12 +71,12 @@ class _ModelSerializer(BaseSerializer, ABC):
63
71
  typing = "str"
64
72
  return f"self.{prop.client_name}: {typing} = {discriminator_value}"
65
73
 
66
- @staticmethod
67
- def initialize_standard_property(prop: Property):
74
+ def initialize_standard_property(self, prop: Property):
68
75
  if not (prop.optional or prop.client_default_value is not None):
69
- return f"{prop.client_name}: {prop.type_annotation()},{prop.pylint_disable()}"
76
+ type_annotation = prop.type_annotation(serialize_namespace=self.serialize_namespace)
77
+ return f"{prop.client_name}: {type_annotation},{prop.pylint_disable()}"
70
78
  return (
71
- f"{prop.client_name}: {prop.type_annotation()} = "
79
+ f"{prop.client_name}: {prop.type_annotation(serialize_namespace=self.serialize_namespace)} = "
72
80
  f"{prop.client_default_value_declaration},{prop.pylint_disable()}"
73
81
  )
74
82
 
@@ -108,7 +116,7 @@ class _ModelSerializer(BaseSerializer, ABC):
108
116
  def initialize_properties(self, model: ModelType) -> List[str]: ...
109
117
 
110
118
  def need_init(self, model: ModelType) -> bool:
111
- return (not model.internal) and bool(self.init_line(model) or model.discriminator)
119
+ return bool(self.init_line(model) or model.discriminator)
112
120
 
113
121
  def pylint_disable_items(self, model: ModelType) -> List[str]:
114
122
  if model.flattened_property or self.initialize_properties(model):
@@ -127,19 +135,29 @@ class _ModelSerializer(BaseSerializer, ABC):
127
135
  def global_pylint_disables(self) -> str:
128
136
  return ""
129
137
 
138
+ @property
139
+ def serialize_namespace(self) -> str:
140
+ return self.code_model.get_serialize_namespace(self.client_namespace, client_namespace_type=NamespaceType.MODEL)
141
+
130
142
 
131
143
  class MsrestModelSerializer(_ModelSerializer):
132
144
  def imports(self) -> FileImport:
133
145
  file_import = FileImport(self.code_model)
134
146
  file_import.add_msrest_import(
135
- relative_path="..",
147
+ serialize_namespace=self.serialize_namespace,
136
148
  msrest_import_type=MsrestImportType.Module,
137
149
  typing_section=TypingSection.REGULAR,
138
150
  )
139
- for model in self.code_model.model_types:
151
+ for model in self.models:
140
152
  file_import.merge(model.imports(is_operation_file=False))
141
153
  for param in self._init_line_parameters(model):
142
- file_import.merge(param.imports())
154
+ file_import.merge(
155
+ param.imports(
156
+ serialize_namespace=self.serialize_namespace,
157
+ serialize_namespace_type=NamespaceType.MODEL,
158
+ called_by_property=True,
159
+ )
160
+ )
143
161
 
144
162
  return file_import
145
163
 
@@ -209,19 +227,41 @@ class DpgModelSerializer(_ModelSerializer):
209
227
 
210
228
  def imports(self) -> FileImport:
211
229
  file_import = FileImport(self.code_model)
212
- file_import.add_submodule_import(
213
- "..",
214
- "_model_base",
215
- ImportType.LOCAL,
216
- TypingSection.REGULAR,
217
- )
218
-
219
- for model in self.code_model.model_types:
230
+ if any(not m.parents for m in self.models):
231
+ file_import.add_submodule_import(
232
+ self.code_model.get_relative_import_path(self.serialize_namespace),
233
+ "_model_base",
234
+ ImportType.LOCAL,
235
+ TypingSection.REGULAR,
236
+ )
237
+ for model in self.models:
220
238
  if model.base == "json":
221
239
  continue
222
- file_import.merge(model.imports(is_operation_file=False))
240
+ file_import.merge(
241
+ model.imports(
242
+ is_operation_file=False,
243
+ serialize_namespace=self.serialize_namespace,
244
+ serialize_namespace_type=NamespaceType.MODEL,
245
+ )
246
+ )
223
247
  for prop in model.properties:
224
- file_import.merge(prop.imports())
248
+ file_import.merge(
249
+ prop.imports(
250
+ serialize_namespace=self.serialize_namespace,
251
+ serialize_namespace_type=NamespaceType.MODEL,
252
+ called_by_property=True,
253
+ )
254
+ )
255
+ for parent in model.parents:
256
+ if parent.client_namespace != model.client_namespace:
257
+ file_import.add_submodule_import(
258
+ self.code_model.get_relative_import_path(
259
+ self.serialize_namespace,
260
+ self.code_model.get_imported_namespace_for_model(parent.client_namespace),
261
+ ),
262
+ parent.name,
263
+ ImportType.LOCAL,
264
+ )
225
265
  if model.is_polymorphic:
226
266
  file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB)
227
267
  if not model.internal and self.init_line(model):
@@ -258,8 +298,7 @@ class DpgModelSerializer(_ModelSerializer):
258
298
  raise ValueError("We do not generate anonymous properties")
259
299
  return properties_to_declare
260
300
 
261
- @staticmethod
262
- def declare_property(prop: Property) -> str:
301
+ def declare_property(self, prop: Property) -> str:
263
302
  args = []
264
303
  if prop.client_name != prop.wire_name or prop.is_discriminator:
265
304
  args.append(f'name="{prop.wire_name}"')
@@ -283,7 +322,8 @@ class DpgModelSerializer(_ModelSerializer):
283
322
  if prop.is_discriminator and isinstance(prop.type, (ConstantType, EnumValue)) and prop.type.value
284
323
  else ""
285
324
  )
286
- generated_code = f'{prop.client_name}: {prop.type_annotation()} = {field}({", ".join(args)})'
325
+ type_annotation = prop.type_annotation(serialize_namespace=self.serialize_namespace)
326
+ generated_code = f'{prop.client_name}: {type_annotation} = {field}({", ".join(args)})'
287
327
  # there is 4 spaces indentation so original line length limit 120 - 4 = 116
288
328
  pylint_disable = (
289
329
  " # pylint: disable=line-too-long"
@@ -324,7 +364,7 @@ class DpgModelSerializer(_ModelSerializer):
324
364
 
325
365
  def global_pylint_disables(self) -> str:
326
366
  result = []
327
- for model in self.code_model.model_types:
367
+ for model in self.models:
328
368
  if self.need_init(model):
329
369
  for item in self.pylint_disable_items(model):
330
370
  if item:
@@ -7,15 +7,14 @@ from typing import Optional, List, Union
7
7
  import functools
8
8
  from jinja2 import Environment
9
9
 
10
- from .utils import get_all_operation_groups_recursively
11
10
  from ..models import (
12
11
  CodeModel,
13
12
  OperationGroup,
14
13
  RequestBuilder,
15
14
  OverloadedRequestBuilder,
16
- Client,
17
15
  FileImport,
18
16
  )
17
+ from ..models.utils import NamespaceType
19
18
  from .import_serializer import FileImportSerializer
20
19
  from .builder_serializer import (
21
20
  get_operation_serializer,
@@ -28,23 +27,22 @@ class OperationGroupsSerializer(BaseSerializer):
28
27
  def __init__(
29
28
  self,
30
29
  code_model: CodeModel,
31
- clients: List[Client],
30
+ operation_groups: List[OperationGroup],
32
31
  env: Environment,
33
32
  async_mode: bool,
34
- operation_group: Optional[OperationGroup] = None,
33
+ *,
34
+ client_namespace: Optional[str] = None,
35
35
  ):
36
- super().__init__(code_model, env)
37
- self.clients = clients
36
+ super().__init__(code_model, env, async_mode, client_namespace=client_namespace)
37
+ self.operation_groups = operation_groups
38
38
  self.async_mode = async_mode
39
- self.operation_group = operation_group
40
39
 
41
40
  def _get_request_builders(
42
41
  self, operation_group: OperationGroup
43
42
  ) -> List[Union[OverloadedRequestBuilder, RequestBuilder]]:
44
43
  return [
45
44
  r
46
- for client in self.clients
47
- for r in client.request_builders
45
+ for r in operation_group.client.request_builders
48
46
  if r.client.name == operation_group.client.name
49
47
  and r.group_name == operation_group.identify_name
50
48
  and not r.is_overload
@@ -52,17 +50,20 @@ class OperationGroupsSerializer(BaseSerializer):
52
50
  and not r.is_lro # lro has already initial builder
53
51
  ]
54
52
 
55
- def serialize(self) -> str:
56
- if self.operation_group:
57
- operation_groups = [self.operation_group]
58
- else:
59
- operation_groups = get_all_operation_groups_recursively(self.clients)
53
+ @property
54
+ def serialize_namespace(self) -> str:
55
+ return self.code_model.get_serialize_namespace(
56
+ self.client_namespace, async_mode=self.async_mode, client_namespace_type=NamespaceType.OPERATION
57
+ )
60
58
 
59
+ def serialize(self) -> str:
61
60
  imports = FileImport(self.code_model)
62
- for operation_group in operation_groups:
61
+ for operation_group in self.operation_groups:
63
62
  imports.merge(
64
63
  operation_group.imports(
65
64
  async_mode=self.async_mode,
65
+ serialize_namespace=self.serialize_namespace,
66
+ serialize_namespace_type=NamespaceType.OPERATION,
66
67
  )
67
68
  )
68
69
 
@@ -70,7 +71,7 @@ class OperationGroupsSerializer(BaseSerializer):
70
71
 
71
72
  return template.render(
72
73
  code_model=self.code_model,
73
- operation_groups=operation_groups,
74
+ operation_groups=self.operation_groups,
74
75
  imports=FileImportSerializer(
75
76
  imports,
76
77
  async_mode=self.async_mode,
@@ -80,10 +81,12 @@ class OperationGroupsSerializer(BaseSerializer):
80
81
  get_operation_serializer,
81
82
  code_model=self.code_model,
82
83
  async_mode=self.async_mode,
84
+ client_namespace=self.client_namespace,
83
85
  ),
84
86
  request_builder_serializer=RequestBuilderSerializer(
85
87
  self.code_model,
86
88
  async_mode=False,
89
+ client_namespace=self.client_namespace,
87
90
  ),
88
91
  get_request_builders=self._get_request_builders,
89
92
  )
@@ -6,20 +6,19 @@
6
6
  from typing import List
7
7
  from jinja2 import Environment
8
8
 
9
- from ..models.operation_group import OperationGroup
10
- from ..models import CodeModel, Client
9
+ from ..models import CodeModel, OperationGroup
11
10
 
12
11
 
13
12
  class OperationsInitSerializer:
14
13
  def __init__(
15
14
  self,
16
15
  code_model: CodeModel,
17
- clients: List[Client],
16
+ operation_groups: List[OperationGroup],
18
17
  env: Environment,
19
18
  async_mode: bool,
20
19
  ) -> None:
21
20
  self.code_model = code_model
22
- self.clients = clients
21
+ self.operation_groups = [og for og in operation_groups if not og.has_parent_operation_group]
23
22
  self.env = env
24
23
  self.async_mode = async_mode
25
24
 
@@ -27,11 +26,7 @@ class OperationsInitSerializer:
27
26
  def _get_filename(operation_group: OperationGroup) -> str:
28
27
  return "_operations" if self.code_model.options["combine_operation_files"] else operation_group.filename
29
28
 
30
- return [
31
- f"from .{_get_filename(og)} import {og.class_name} # type: ignore"
32
- for client in self.clients
33
- for og in client.operation_groups
34
- ]
29
+ return [f"from .{_get_filename(og)} import {og.class_name} # type: ignore" for og in self.operation_groups]
35
30
 
36
31
  def serialize(self) -> str:
37
32
  operation_group_init_template = self.env.get_template("operations_folder_init.py.jinja2")
@@ -40,5 +35,5 @@ class OperationsInitSerializer:
40
35
  code_model=self.code_model,
41
36
  async_mode=self.async_mode,
42
37
  operation_group_imports=self.operation_group_imports,
43
- clients=self.clients,
38
+ operation_groups=self.operation_groups,
44
39
  )
@@ -52,8 +52,11 @@ SPECIAL_HEADER_SERIALIZATION: Dict[str, List[str]] = {
52
52
 
53
53
 
54
54
  class ParameterSerializer:
55
- @staticmethod
56
- def serialize_parameter(parameter: ParameterType, serializer_name: str) -> str:
55
+
56
+ def __init__(self, serialize_namespace: str) -> None:
57
+ self.serialize_namespace = serialize_namespace
58
+
59
+ def serialize_parameter(self, parameter: ParameterType, serializer_name: str) -> str:
57
60
  optional_parameters = []
58
61
 
59
62
  if parameter.skip_url_encoding:
@@ -88,7 +91,7 @@ class ParameterSerializer:
88
91
  parameters = [
89
92
  f'"{origin_name.lstrip("_")}"',
90
93
  "q" if parameter.explode else origin_name,
91
- f"'{type.serialization_type}'",
94
+ f"'{type.serialization_type(serialize_namespace=self.serialize_namespace)}'",
92
95
  *optional_parameters,
93
96
  ]
94
97
  parameters_line = ", ".join(parameters)
@@ -106,8 +109,8 @@ class ParameterSerializer:
106
109
  return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
107
110
  return serialize_line
108
111
 
109
- @staticmethod
110
112
  def serialize_path(
113
+ self,
111
114
  parameters: Union[
112
115
  List[Parameter],
113
116
  List[RequestBuilderParameter],
@@ -121,7 +124,7 @@ class ParameterSerializer:
121
124
  [
122
125
  ' "{}": {},'.format(
123
126
  path_parameter.wire_name,
124
- ParameterSerializer.serialize_parameter(path_parameter, serializer_name),
127
+ self.serialize_parameter(path_parameter, serializer_name),
125
128
  )
126
129
  for path_parameter in parameters
127
130
  ]
@@ -129,8 +132,8 @@ class ParameterSerializer:
129
132
  retval.append("}")
130
133
  return retval
131
134
 
132
- @staticmethod
133
135
  def serialize_query_header(
136
+ self,
134
137
  param: Parameter,
135
138
  kwarg_name: str,
136
139
  serializer_name: str,
@@ -146,7 +149,7 @@ class ParameterSerializer:
146
149
  set_parameter = "_{}['{}'] = {}".format(
147
150
  kwarg_name,
148
151
  param.wire_name,
149
- ParameterSerializer.serialize_parameter(param, serializer_name),
152
+ self.serialize_parameter(param, serializer_name),
150
153
  )
151
154
  if not param.optional and (param.in_method_signature or param.constant):
152
155
  retval = [set_parameter]
@@ -7,6 +7,7 @@ from typing import List
7
7
  from jinja2 import Environment
8
8
 
9
9
  from ..models import FileImport
10
+ from ..models.utils import NamespaceType
10
11
  from .import_serializer import FileImportSerializer
11
12
  from ..models import CodeModel, RequestBuilderType
12
13
  from .builder_serializer import RequestBuilderSerializer
@@ -39,6 +40,12 @@ class RequestBuildersSerializer(BaseSerializer):
39
40
  request_builders=[r for r in self.request_builders if not r.is_overload],
40
41
  )
41
42
 
43
+ @property
44
+ def serialize_namespace(self) -> str:
45
+ return self.code_model.get_serialize_namespace(
46
+ self.client_namespace, client_namespace_type=NamespaceType.OPERATION
47
+ )
48
+
42
49
  def serialize_request_builders(self) -> str:
43
50
  template = self.env.get_template("request_builders.py.jinja2")
44
51
 
@@ -48,5 +55,7 @@ class RequestBuildersSerializer(BaseSerializer):
48
55
  imports=FileImportSerializer(
49
56
  self.imports,
50
57
  ),
51
- request_builder_serializer=RequestBuilderSerializer(self.code_model, async_mode=False),
58
+ request_builder_serializer=RequestBuilderSerializer(
59
+ self.code_model, async_mode=False, client_namespace=self.client_namespace
60
+ ),
52
61
  )
@@ -20,7 +20,7 @@ from ..models import (
20
20
  BodyParameter,
21
21
  FileImport,
22
22
  )
23
- from .utils import get_namespace_config, get_namespace_from_package_name
23
+ from .._utils import get_parent_namespace
24
24
 
25
25
  _LOGGER = logging.getLogger(__name__)
26
26
 
@@ -44,15 +44,12 @@ class SampleSerializer(BaseSerializer):
44
44
 
45
45
  def _imports(self) -> FileImportSerializer:
46
46
  imports = FileImport(self.code_model)
47
- namespace_from_package_name = get_namespace_from_package_name(self.code_model.options["package_name"])
48
- namespace_config = get_namespace_config(self.code_model.namespace, self.code_model.options["multiapi"])
49
- namespace = namespace_from_package_name or namespace_config
50
- # mainly for "azure-mgmt-rdbms"
51
- if not self.code_model.options["multiapi"] and namespace_config.count(".") > namespace_from_package_name.count(
52
- "."
53
- ):
54
- namespace = namespace_config
55
- client = self.code_model.clients[0]
47
+ client = self.operation_group.client
48
+ namespace = (
49
+ get_parent_namespace(client.client_namespace)
50
+ if self.code_model.options["multiapi"]
51
+ else client.client_namespace
52
+ )
56
53
  imports.add_submodule_import(namespace, client.name, ImportType.LOCAL)
57
54
  credential_type = getattr(client.credential, "type", None)
58
55
  if isinstance(credential_type, TokenCredentialType):
@@ -35,18 +35,18 @@ def is_common_operation(operation_type: str) -> bool:
35
35
 
36
36
 
37
37
  class TestName:
38
- def __init__(self, code_model: CodeModel, client_name: str, *, is_async: bool = False) -> None:
38
+ def __init__(self, code_model: CodeModel, client_name: str, *, async_mode: bool = False) -> None:
39
39
  self.code_model = code_model
40
40
  self.client_name = client_name
41
- self.is_async = is_async
41
+ self.async_mode = async_mode
42
42
 
43
43
  @property
44
44
  def async_suffix_capt(self) -> str:
45
- return "Async" if self.is_async else ""
45
+ return "Async" if self.async_mode else ""
46
46
 
47
47
  @property
48
48
  def create_client_name(self) -> str:
49
- return "create_async_client" if self.is_async else "create_client"
49
+ return "create_async_client" if self.async_mode else "create_client"
50
50
 
51
51
  @property
52
52
  def prefix(self) -> str:
@@ -72,12 +72,12 @@ class TestCase:
72
72
  params: Dict[str, Any],
73
73
  operation: OperationType,
74
74
  *,
75
- is_async: bool = False,
75
+ async_mode: bool = False,
76
76
  ) -> None:
77
77
  self.operation_groups = operation_groups
78
78
  self.params = params
79
79
  self.operation = operation
80
- self.is_async = is_async
80
+ self.async_mode = async_mode
81
81
 
82
82
  @property
83
83
  def name(self) -> str:
@@ -93,7 +93,7 @@ class TestCase:
93
93
 
94
94
  @property
95
95
  def response(self) -> str:
96
- if self.is_async:
96
+ if self.async_mode:
97
97
  if is_lro(self.operation.operation_type):
98
98
  return "response = await (await "
99
99
  if is_common_operation(self.operation.operation_type):
@@ -107,14 +107,14 @@ class TestCase:
107
107
  @property
108
108
  def operation_suffix(self) -> str:
109
109
  if is_lro(self.operation.operation_type):
110
- extra = ")" if self.is_async else ""
110
+ extra = ")" if self.async_mode else ""
111
111
  return f"{extra}.result(){self.lro_comment}"
112
112
  return ""
113
113
 
114
114
  @property
115
115
  def extra_operation(self) -> str:
116
116
  if is_paging(self.operation.operation_type):
117
- async_str = "async " if self.is_async else ""
117
+ async_str = "async " if self.async_mode else ""
118
118
  return f"result = [r {async_str}for r in response]"
119
119
  return ""
120
120
 
@@ -128,43 +128,39 @@ class Test(TestName):
128
128
  testcases: List[TestCase],
129
129
  test_class_name: str,
130
130
  *,
131
- is_async: bool = False,
131
+ async_mode: bool = False,
132
132
  ) -> None:
133
- super().__init__(code_model, client_name, is_async=is_async)
133
+ super().__init__(code_model, client_name, async_mode=async_mode)
134
134
  self.operation_group = operation_group
135
135
  self.testcases = testcases
136
136
  self.test_class_name = test_class_name
137
137
 
138
138
 
139
139
  class TestGeneralSerializer(BaseSerializer):
140
- def __init__(self, code_model: CodeModel, env: Environment, *, is_async: bool = False) -> None:
141
- super().__init__(code_model, env)
142
- self.is_async = is_async
143
140
 
144
141
  @property
145
142
  def aio_str(self) -> str:
146
- return ".aio" if self.is_async else ""
143
+ return ".aio" if self.async_mode else ""
147
144
 
148
145
  @property
149
146
  def test_names(self) -> List[TestName]:
150
- return [TestName(self.code_model, c.name, is_async=self.is_async) for c in self.code_model.clients]
147
+ return [TestName(self.code_model, c.name, async_mode=self.async_mode) for c in self.code_model.clients]
151
148
 
152
149
  def add_import_client(self, imports: FileImport) -> None:
153
- namespace = get_namespace_from_package_name(self.code_model.options["package_name"])
154
150
  for client in self.code_model.clients:
155
- imports.add_submodule_import(namespace + self.aio_str, client.name, ImportType.STDLIB)
151
+ imports.add_submodule_import(client.client_namespace + self.aio_str, client.name, ImportType.STDLIB)
156
152
 
157
153
  @property
158
154
  def import_clients(self) -> FileImportSerializer:
159
155
  imports = self.init_file_import()
160
156
 
161
157
  imports.add_submodule_import("devtools_testutils", "AzureRecordedTestCase", ImportType.STDLIB)
162
- if not self.is_async:
158
+ if not self.async_mode:
163
159
  imports.add_import("functools", ImportType.STDLIB)
164
160
  imports.add_submodule_import("devtools_testutils", "PowerShellPreparer", ImportType.STDLIB)
165
161
  self.add_import_client(imports)
166
162
 
167
- return FileImportSerializer(imports, self.is_async)
163
+ return FileImportSerializer(imports, self.async_mode)
168
164
 
169
165
  def serialize_conftest(self) -> str:
170
166
  return self.env.get_template("conftest.py.jinja2").render(
@@ -188,17 +184,17 @@ class TestSerializer(TestGeneralSerializer):
188
184
  *,
189
185
  client: Client,
190
186
  operation_group: OperationGroup,
191
- is_async: bool = False,
187
+ async_mode: bool = False,
192
188
  ) -> None:
193
- super().__init__(code_model, env, is_async=is_async)
189
+ super().__init__(code_model, env, async_mode=async_mode)
194
190
  self.client = client
195
191
  self.operation_group = operation_group
196
192
 
197
193
  @property
198
194
  def import_test(self) -> FileImportSerializer:
199
195
  imports = self.init_file_import()
200
- test_name = TestName(self.code_model, self.client.name, is_async=self.is_async)
201
- async_suffix = "_async" if self.is_async else ""
196
+ test_name = TestName(self.code_model, self.client.name, async_mode=self.async_mode)
197
+ async_suffix = "_async" if self.async_mode else ""
202
198
  imports.add_submodule_import(
203
199
  "devtools_testutils" if self.code_model.options["azure_arm"] else "testpreparer" + async_suffix,
204
200
  test_name.base_test_class_name,
@@ -216,7 +212,7 @@ class TestSerializer(TestGeneralSerializer):
216
212
  )
217
213
  if self.code_model.options["azure_arm"]:
218
214
  self.add_import_client(imports)
219
- return FileImportSerializer(imports, self.is_async)
215
+ return FileImportSerializer(imports, self.async_mode)
220
216
 
221
217
  @property
222
218
  def breadth_search_operation_group(self) -> List[List[OperationGroup]]:
@@ -263,7 +259,7 @@ class TestSerializer(TestGeneralSerializer):
263
259
  operation_groups=operation_groups,
264
260
  params=operation_params,
265
261
  operation=operation,
266
- is_async=self.is_async,
262
+ async_mode=self.async_mode,
267
263
  )
268
264
  testcases.append(testcase)
269
265
  if not testcases:
@@ -275,12 +271,12 @@ class TestSerializer(TestGeneralSerializer):
275
271
  operation_group=self.operation_group,
276
272
  testcases=testcases,
277
273
  test_class_name=self.test_class_name,
278
- is_async=self.is_async,
274
+ async_mode=self.async_mode,
279
275
  )
280
276
 
281
277
  @property
282
278
  def test_class_name(self) -> str:
283
- test_name = TestName(self.code_model, self.client.name, is_async=self.is_async)
279
+ test_name = TestName(self.code_model, self.client.name, async_mode=self.async_mode)
284
280
  class_name = "" if self.operation_group.is_mixin else self.operation_group.class_name
285
281
  return f"Test{test_name.prefix}{class_name}{test_name.async_suffix_capt}"
286
282
 
@@ -4,6 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from ..models.imports import FileImport, ImportType
7
+ from ..models.utils import NamespaceType
7
8
  from .import_serializer import FileImportSerializer
8
9
  from .base_serializer import BaseSerializer
9
10
 
@@ -18,7 +19,11 @@ class TypesSerializer(BaseSerializer):
18
19
  ImportType.STDLIB,
19
20
  )
20
21
  for nu in self.code_model.named_unions:
21
- file_import.merge(nu.imports(relative_path=".", model_typing=True, is_types_file=True))
22
+ file_import.merge(
23
+ nu.imports(
24
+ serialize_namespace=self.serialize_namespace, serialize_namespace_type=NamespaceType.TYPES_FILE
25
+ )
26
+ )
22
27
  return file_import
23
28
 
24
29
  def serialize(self) -> str:
@@ -4,11 +4,9 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  import json
7
- from typing import Optional, List, Any
7
+ from typing import Optional, Any
8
8
  from pathlib import Path
9
9
 
10
- from ..models import Client, OperationGroup
11
-
12
10
 
13
11
  def method_signature_and_response_type_annotation_template(
14
12
  *,
@@ -35,18 +33,6 @@ def get_namespace_from_package_name(package_name: Optional[str]) -> str:
35
33
  return (package_name or "").replace("-", ".")
36
34
 
37
35
 
38
- def get_all_operation_groups_recursively(clients: List[Client]) -> List[OperationGroup]:
39
- operation_groups = []
40
- queue = []
41
- for client in clients:
42
- queue.extend(client.operation_groups)
43
- while queue:
44
- operation_groups.append(queue.pop(0))
45
- if operation_groups[-1].operation_groups:
46
- queue.extend(operation_groups[-1].operation_groups)
47
- return operation_groups
48
-
49
-
50
36
  def _improve_json_string(template_representation: str) -> Any:
51
37
  origin = template_representation.split("\n")
52
38
  final = []
@@ -7,6 +7,6 @@
7
7
  {{ imports }}
8
8
 
9
9
  {% for client in clients %}
10
- {% set serializer = get_serializer(client) %}
10
+ {% set serializer = get_serializer(client, serialize_namespace) %}
11
11
  {% include "client.py.jinja2" %}
12
12
  {% endfor %}