@autorest/python 6.32.3 → 6.34.0

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 (63) hide show
  1. package/autorest/m2r.py +1 -2
  2. package/autorest/m4reformatter/__init__.py +1 -2
  3. package/autorest/multiapi/models/imports.py +7 -2
  4. package/autorest/multiapi/serializers/__init__.py +5 -1
  5. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
  6. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +13 -2
  7. package/autorest/multiapi/templates/multiapi_utils_init.py.jinja2 +10 -0
  8. package/autorest/preprocess.py +1 -2
  9. package/generator/build/lib/pygen/codegen/models/client.py +39 -2
  10. package/generator/build/lib/pygen/codegen/models/code_model.py +22 -11
  11. package/generator/build/lib/pygen/codegen/models/enum_type.py +2 -2
  12. package/generator/build/lib/pygen/codegen/models/imports.py +13 -9
  13. package/generator/build/lib/pygen/codegen/models/lro_operation.py +1 -1
  14. package/generator/build/lib/pygen/codegen/models/model_type.py +4 -3
  15. package/generator/build/lib/pygen/codegen/models/operation.py +10 -3
  16. package/generator/build/lib/pygen/codegen/models/operation_group.py +27 -31
  17. package/generator/build/lib/pygen/codegen/models/paging_operation.py +3 -1
  18. package/generator/build/lib/pygen/codegen/models/parameter.py +4 -1
  19. package/generator/build/lib/pygen/codegen/models/primitive_types.py +2 -2
  20. package/generator/build/lib/pygen/codegen/models/property.py +1 -1
  21. package/generator/build/lib/pygen/codegen/serializers/__init__.py +31 -29
  22. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +1 -1
  23. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +32 -6
  24. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +57 -35
  25. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +4 -3
  26. package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +6 -1
  27. package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +2 -2
  28. package/generator/build/lib/pygen/codegen/templates/client.py.jinja2 +1 -1
  29. package/generator/build/lib/pygen/codegen/templates/config.py.jinja2 +2 -8
  30. package/generator/build/lib/pygen/codegen/templates/model_dpg.py.jinja2 +1 -1
  31. package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +3 -3
  32. package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +12 -11
  33. package/generator/build/lib/pygen/codegen/templates/{vendor.py.jinja2 → utils.py.jinja2} +11 -12
  34. package/generator/component-detection-pip-report.json +4 -5
  35. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  36. package/generator/pygen/codegen/models/client.py +39 -2
  37. package/generator/pygen/codegen/models/code_model.py +22 -11
  38. package/generator/pygen/codegen/models/enum_type.py +2 -2
  39. package/generator/pygen/codegen/models/imports.py +13 -9
  40. package/generator/pygen/codegen/models/lro_operation.py +1 -1
  41. package/generator/pygen/codegen/models/model_type.py +4 -3
  42. package/generator/pygen/codegen/models/operation.py +10 -3
  43. package/generator/pygen/codegen/models/operation_group.py +27 -31
  44. package/generator/pygen/codegen/models/paging_operation.py +3 -1
  45. package/generator/pygen/codegen/models/parameter.py +4 -1
  46. package/generator/pygen/codegen/models/primitive_types.py +2 -2
  47. package/generator/pygen/codegen/models/property.py +1 -1
  48. package/generator/pygen/codegen/serializers/__init__.py +31 -29
  49. package/generator/pygen/codegen/serializers/builder_serializer.py +1 -1
  50. package/generator/pygen/codegen/serializers/client_serializer.py +32 -6
  51. package/generator/pygen/codegen/serializers/general_serializer.py +57 -35
  52. package/generator/pygen/codegen/serializers/model_serializer.py +4 -3
  53. package/generator/pygen/codegen/serializers/parameter_serializer.py +6 -1
  54. package/generator/pygen/codegen/serializers/sample_serializer.py +2 -2
  55. package/generator/pygen/codegen/templates/client.py.jinja2 +1 -1
  56. package/generator/pygen/codegen/templates/config.py.jinja2 +2 -8
  57. package/generator/pygen/codegen/templates/model_dpg.py.jinja2 +1 -1
  58. package/generator/pygen/codegen/templates/operation_group.py.jinja2 +3 -3
  59. package/generator/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +12 -11
  60. package/generator/pygen/codegen/templates/{vendor.py.jinja2 → utils.py.jinja2} +11 -12
  61. package/generator/pygen.egg-info/SOURCES.txt +1 -1
  62. package/package.json +2 -2
  63. package/scripts/__pycache__/venvtools.cpython-310.pyc +0 -0
@@ -30,9 +30,11 @@ class TypingSection(str, Enum):
30
30
 
31
31
 
32
32
  class MsrestImportType(Enum):
33
- Module = auto() # import _serialization.py or msrest.serialization as Module
34
- Serializer = auto() # from _serialization.py or msrest.serialization import Serializer
35
- SerializerDeserializer = auto() # from _serialization.py or msrest.serialization import Serializer and Deserializer
33
+ Module = auto() # import _utils/serialization.py or msrest.serialization as Module
34
+ Serializer = auto() # from _utils/serialization.py or msrest.serialization import Serializer
35
+ SerializerDeserializer = (
36
+ auto()
37
+ ) # from _utils/serialization.py or msrest.serialization import Serializer and Deserializer
36
38
 
37
39
 
38
40
  class ImportModel:
@@ -261,21 +263,23 @@ class FileImport:
261
263
  if msrest_import_type == MsrestImportType.SerializerDeserializer:
262
264
  self.add_submodule_import("msrest", "Deserializer", ImportType.THIRDPARTY, typing_section)
263
265
  else:
264
- # _serialization.py is always in root namespace
265
- imported_namespace = self.code_model.namespace
266
+ # _utils/serialization.py is always in root namespace
267
+ imported_namespace = f"{self.code_model.namespace}._utils"
266
268
  if self.code_model.options["multiapi"]:
267
- # for multiapi, the namespace is azure.mgmt.xxx.v20XX_XX_XX while _serialization.py is in azure.mgmt.xxx
268
- imported_namespace = get_parent_namespace(imported_namespace)
269
+ # for multiapi, the namespace is azure.mgmt.xxx.v20XX_XX_XX
270
+ # while _utils/serialization.py is in azure.mgmt.xxx
271
+ imported_namespace = f"{get_parent_namespace(imported_namespace)}._utils"
269
272
  if msrest_import_type == MsrestImportType.Module:
270
273
  self.add_submodule_import(
271
274
  self.code_model.get_relative_import_path(serialize_namespace, imported_namespace),
272
- "_serialization",
275
+ "serialization",
273
276
  ImportType.LOCAL,
274
277
  typing_section,
278
+ alias="_serialization",
275
279
  )
276
280
  else:
277
281
  relative_path = self.code_model.get_relative_import_path(
278
- serialize_namespace, imported_namespace, module_name="_serialization"
282
+ serialize_namespace, f"{self.code_model.namespace}._utils.serialization"
279
283
  )
280
284
  self.add_submodule_import(relative_path, "Serializer", ImportType.LOCAL, typing_section)
281
285
  if msrest_import_type == MsrestImportType.SerializerDeserializer:
@@ -134,7 +134,7 @@ class LROOperationBase(OperationBase[LROResponseType]):
134
134
  # but final call returns a model
135
135
  serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
136
136
  file_import.add_submodule_import(
137
- self.code_model.get_relative_import_path(serialize_namespace, module_name="_model_base"),
137
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_utils.model_base"),
138
138
  "_deserialize",
139
139
  ImportType.LOCAL,
140
140
  )
@@ -292,7 +292,7 @@ class GeneratedModelType(ModelType):
292
292
 
293
293
  def docstring_type(self, **kwargs: Any) -> str:
294
294
  type_annotation = self.type_annotation(need_model_alias=False, skip_quote=True, **kwargs)
295
- return f"~{self.code_model.namespace}.models.{type_annotation}"
295
+ return f"~{self.client_namespace}.models.{type_annotation}"
296
296
 
297
297
  def docstring_text(self, **kwargs: Any) -> str:
298
298
  return self.name
@@ -318,9 +318,10 @@ class GeneratedModelType(ModelType):
318
318
  )
319
319
  if self.is_form_data:
320
320
  file_import.add_submodule_import(
321
- self.code_model.get_relative_import_path(serialize_namespace),
322
- "_model_base",
321
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_utils.model_base"),
322
+ "Model",
323
323
  ImportType.LOCAL,
324
+ alias="_Model",
324
325
  )
325
326
  elif serialize_namespace_type == NamespaceType.TYPES_FILE or (
326
327
  serialize_namespace_type == NamespaceType.MODEL and called_by_property
@@ -391,7 +391,9 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
391
391
  ImportType.SDKCORE,
392
392
  )
393
393
  if not async_mode:
394
- relative_path = self.code_model.get_relative_import_path(serialize_namespace, module_name="_vendor")
394
+ relative_path = self.code_model.get_relative_import_path(
395
+ serialize_namespace, module_name="_utils.utils"
396
+ )
395
397
  file_import.add_submodule_import(
396
398
  relative_path,
397
399
  "prep_if_match",
@@ -436,12 +438,17 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
436
438
  if self.overloads:
437
439
  file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
438
440
  if self.code_model.options["models_mode"] == "dpg":
439
- relative_path = self.code_model.get_relative_import_path(serialize_namespace, module_name="_model_base")
441
+ relative_path = self.code_model.get_relative_import_path(
442
+ serialize_namespace, module_name="_utils.model_base"
443
+ )
440
444
  body_param = self.parameters.body_parameter if self.parameters.has_body else None
441
445
  if body_param and not isinstance(body_param.type, BinaryType):
442
446
  if self.has_form_data_body:
443
447
  file_import.add_submodule_import(
444
- self.code_model.get_relative_import_path(serialize_namespace), "_model_base", ImportType.LOCAL
448
+ relative_path,
449
+ "Model",
450
+ ImportType.LOCAL,
451
+ alias="_Model",
445
452
  )
446
453
  elif xml_serializable(self.parameters.body_parameter.default_content_type):
447
454
  file_import.add_submodule_import(
@@ -63,11 +63,11 @@ class OperationGroup(BaseModel):
63
63
  operation_group.has_non_abstract_operations for operation_group in self.operation_groups
64
64
  )
65
65
 
66
- @property
67
- def base_class(self) -> str:
66
+ def base_class(self, async_mode: bool) -> str:
67
+ pipeline_client = f"{'Async' if async_mode else ''}PipelineClient"
68
68
  base_classes: List[str] = []
69
69
  if self.is_mixin:
70
- base_classes.append(f"{self.client.name}MixinABC")
70
+ base_classes.append(f"ClientMixinABC[{pipeline_client}, {self.client.name}Configuration]")
71
71
  return ", ".join(base_classes)
72
72
 
73
73
  def imports_for_multiapi(self, async_mode: bool, **kwargs) -> FileImport:
@@ -100,8 +100,12 @@ class OperationGroup(BaseModel):
100
100
 
101
101
  def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
102
102
  file_import = FileImport(self.code_model)
103
-
104
103
  serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
104
+ utils_path = self.code_model.get_relative_import_path(
105
+ serialize_namespace,
106
+ f"{self.code_model.namespace}._utils.utils",
107
+ )
108
+
105
109
  for operation in self.operations:
106
110
  file_import.merge(operation.imports(async_mode, **kwargs))
107
111
  if not self.code_model.options["combine_operation_files"]:
@@ -141,32 +145,28 @@ class OperationGroup(BaseModel):
141
145
  ImportType.LOCAL,
142
146
  alias="_models",
143
147
  )
148
+ file_import.add_submodule_import(
149
+ self.code_model.get_relative_import_path(
150
+ serialize_namespace,
151
+ self.code_model.get_imported_namespace_for_client(self.client.client_namespace, async_mode),
152
+ module_name="_configuration",
153
+ ),
154
+ f"{self.client.name}Configuration",
155
+ ImportType.LOCAL,
156
+ )
157
+ file_import.add_submodule_import(
158
+ "" if self.code_model.is_azure_flavor else "runtime",
159
+ f"{'Async' if async_mode else ''}PipelineClient",
160
+ ImportType.SDKCORE,
161
+ )
144
162
  if self.is_mixin:
145
163
  file_import.add_submodule_import(
146
- # XxxMixinABC is always defined in _vendor of client namespace
147
- self.code_model.get_relative_import_path(
148
- serialize_namespace,
149
- self.code_model.get_imported_namespace_for_client(self.client.client_namespace, async_mode),
150
- module_name="_vendor",
151
- ),
152
- f"{self.client.name}MixinABC",
164
+ # XxxMixinABC is always defined in _utils of client namespace
165
+ utils_path,
166
+ "ClientMixinABC",
153
167
  ImportType.LOCAL,
154
168
  )
155
169
  else:
156
- file_import.add_submodule_import(
157
- "" if self.code_model.is_azure_flavor else "runtime",
158
- f"{'Async' if async_mode else ''}PipelineClient",
159
- ImportType.SDKCORE,
160
- )
161
- file_import.add_submodule_import(
162
- self.code_model.get_relative_import_path(
163
- serialize_namespace,
164
- self.code_model.get_imported_namespace_for_client(self.client.client_namespace, async_mode),
165
- module_name="_configuration",
166
- ),
167
- f"{self.client.name}Configuration",
168
- ImportType.LOCAL,
169
- )
170
170
  file_import.add_msrest_import(
171
171
  serialize_namespace=kwargs.get("serialize_namespace", self.code_model.namespace),
172
172
  msrest_import_type=MsrestImportType.Serializer,
@@ -179,12 +179,8 @@ class OperationGroup(BaseModel):
179
179
  )
180
180
  if self.has_abstract_operations:
181
181
  file_import.add_submodule_import(
182
- # raise_if_not_implemented is always defined in _vendor of top namespace
183
- self.code_model.get_relative_import_path(
184
- serialize_namespace,
185
- self.code_model.get_imported_namespace_for_client(self.code_model.namespace, async_mode),
186
- module_name="_vendor",
187
- ),
182
+ # raise_if_not_implemented is always defined in _utils of top namespace
183
+ utils_path,
188
184
  "raise_if_not_implemented",
189
185
  ImportType.LOCAL,
190
186
  )
@@ -157,7 +157,9 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
157
157
  ImportType.SDKCORE,
158
158
  )
159
159
  if self.code_model.options["models_mode"] == "dpg":
160
- relative_path = self.code_model.get_relative_import_path(serialize_namespace, module_name="_model_base")
160
+ relative_path = self.code_model.get_relative_import_path(
161
+ serialize_namespace, module_name="_utils.model_base"
162
+ )
161
163
  file_import.merge(self.item_type.imports(**kwargs))
162
164
  if self.default_error_deserialization or self.need_deserialize:
163
165
  file_import.add_submodule_import(relative_path, "_deserialize", ImportType.LOCAL)
@@ -275,7 +275,7 @@ class BodyParameter(_ParameterBase):
275
275
  if self.is_form_data:
276
276
  serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
277
277
  file_import.add_submodule_import(
278
- self.code_model.get_relative_import_path(serialize_namespace, module_name="_vendor"),
278
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_utils.utils"),
279
279
  "prepare_multipart_form_data",
280
280
  ImportType.LOCAL,
281
281
  )
@@ -357,6 +357,9 @@ class Parameter(_ParameterBase):
357
357
  )
358
358
  if self.code_model.options["only_path_and_body_params_positional"] and query_or_header:
359
359
  return ParameterMethodLocation.KEYWORD_ONLY
360
+ # for optional path parameter, we need to use keyword only
361
+ if self.location == ParameterLocation.PATH and self.optional:
362
+ return ParameterMethodLocation.KEYWORD_ONLY
360
363
  return ParameterMethodLocation.POSITIONAL
361
364
 
362
365
  @classmethod
@@ -618,13 +618,13 @@ class MultiPartFileType(PrimitiveType):
618
618
  return self.name
619
619
 
620
620
  def docstring_type(self, **kwargs: Any) -> str:
621
- return f"~{self.code_model.namespace}._vendor.{self.name}"
621
+ return f"~{self.code_model.namespace}._utils.utils.{self.name}"
622
622
 
623
623
  def imports(self, **kwargs: Any) -> FileImport:
624
624
  file_import = super().imports(**kwargs)
625
625
  serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
626
626
  file_import.add_submodule_import(
627
- self.code_model.get_relative_import_path(serialize_namespace, module_name="_vendor"),
627
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_utils.utils"),
628
628
  self.name,
629
629
  ImportType.LOCAL,
630
630
  )
@@ -149,7 +149,7 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
149
149
  if self.code_model.options["models_mode"] == "dpg":
150
150
  serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
151
151
  file_import.add_submodule_import(
152
- self.code_model.get_relative_import_path(serialize_namespace, module_name="_model_base"),
152
+ self.code_model.get_relative_import_path(serialize_namespace, module_name="_utils.model_base"),
153
153
  "rest_discriminator" if self.is_discriminator else "rest_field",
154
154
  ImportType.LOCAL,
155
155
  )
@@ -153,7 +153,7 @@ class JinjaSerializer(ReaderAndWriter):
153
153
  general_serializer.serialize_pkgutil_init_file(),
154
154
  )
155
155
 
156
- # _model_base.py/_serialization.py/_vendor.py/py.typed/_types.py/_validation.py
156
+ # _utils/py.typed/_types.py/_validation.py
157
157
  # is always put in top level namespace
158
158
  if self.code_model.is_top_namespace(client_namespace):
159
159
  self._serialize_and_write_top_level_folder(env=env, namespace=client_namespace)
@@ -404,25 +404,41 @@ class JinjaSerializer(ReaderAndWriter):
404
404
  general_serializer.serialize_config_file(clients),
405
405
  )
406
406
 
407
- # sometimes we need define additional Mixin class for client in _vendor.py
408
- self._serialize_and_write_vendor_file(env, namespace)
407
+ # sometimes we need define additional Mixin class for client in _utils.py
408
+ self._serialize_and_write_utils_folder(env, namespace)
409
409
 
410
- def _serialize_and_write_vendor_file(self, env: Environment, namespace: str) -> None:
410
+ def _serialize_and_write_utils_folder(self, env: Environment, namespace: str) -> None:
411
411
  exec_path = self.exec_path(namespace)
412
- # write _vendor.py
413
- for async_mode, async_path in self.serialize_loop:
414
- if self.code_model.need_vendored_code(async_mode=async_mode, client_namespace=namespace):
415
- self.write_file(
416
- exec_path / Path(f"{async_path}_vendor.py"),
417
- GeneralSerializer(
418
- code_model=self.code_model, env=env, async_mode=async_mode, client_namespace=namespace
419
- ).serialize_vendor_file(),
420
- )
412
+ general_serializer = GeneralSerializer(code_model=self.code_model, env=env, async_mode=False)
413
+ utils_folder_path = exec_path / Path("_utils")
414
+ if self.code_model.need_utils_folder(async_mode=False, client_namespace=namespace):
415
+ self.write_file(
416
+ utils_folder_path / Path("__init__.py"),
417
+ self.code_model.license_header,
418
+ )
419
+ if self.code_model.need_utils_utils(async_mode=False, client_namespace=namespace):
420
+ self.write_file(
421
+ utils_folder_path / Path("utils.py"),
422
+ general_serializer.need_utils_utils_file(),
423
+ )
424
+ # write _utils/serialization.py
425
+ if self.code_model.need_utils_serialization:
426
+ self.write_file(
427
+ utils_folder_path / Path("serialization.py"),
428
+ general_serializer.serialize_serialization_file(),
429
+ )
430
+
431
+ # write _model_base.py
432
+ if self.code_model.options["models_mode"] == "dpg":
433
+ self.write_file(
434
+ utils_folder_path / Path("model_base.py"),
435
+ general_serializer.serialize_model_base_file(),
436
+ )
421
437
 
422
438
  def _serialize_and_write_top_level_folder(self, env: Environment, namespace: str) -> None:
423
439
  exec_path = self.exec_path(namespace)
424
- # write _vendor.py
425
- self._serialize_and_write_vendor_file(env, namespace)
440
+ # write _utils folder
441
+ self._serialize_and_write_utils_folder(env, namespace)
426
442
 
427
443
  general_serializer = GeneralSerializer(code_model=self.code_model, env=env, async_mode=False)
428
444
 
@@ -432,20 +448,6 @@ class JinjaSerializer(ReaderAndWriter):
432
448
  # write the empty py.typed file
433
449
  self.write_file(exec_path / Path("py.typed"), "# Marker file for PEP 561.")
434
450
 
435
- # write _serialization.py
436
- if not self.code_model.options["client_side_validation"] and not self.code_model.options["multiapi"]:
437
- self.write_file(
438
- exec_path / Path("_serialization.py"),
439
- general_serializer.serialize_serialization_file(),
440
- )
441
-
442
- # write _model_base.py
443
- if self.code_model.options["models_mode"] == "dpg":
444
- self.write_file(
445
- exec_path / Path("_model_base.py"),
446
- general_serializer.serialize_model_base_file(),
447
- )
448
-
449
451
  # write _validation.py
450
452
  if any(og for client in self.code_model.clients for og in client.operation_groups if og.need_validation):
451
453
  self.write_file(
@@ -672,7 +672,7 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
672
672
  [
673
673
  "_body = (",
674
674
  f" {body_param.client_name}.as_dict()",
675
- f" if isinstance({body_param.client_name}, _model_base.Model) else",
675
+ f" if isinstance({body_param.client_name}, _Model) else",
676
676
  f" {body_param.client_name}",
677
677
  ")",
678
678
  f"_file_fields: List[str] = {file_fields}",
@@ -3,10 +3,10 @@
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, cast
7
7
 
8
8
  from . import utils
9
- from ..models import Client, ParameterMethodLocation
9
+ from ..models import Client, ParameterMethodLocation, Parameter, ParameterLocation
10
10
  from .parameter_serializer import ParameterSerializer, PopKwargType
11
11
  from ...utils import build_policies
12
12
 
@@ -77,17 +77,40 @@ class ClientSerializer:
77
77
  retval.append('"""')
78
78
  return retval
79
79
 
80
- def initialize_config(self) -> str:
80
+ def initialize_config(self) -> List[str]:
81
+ retval = []
82
+ additional_signatures = []
83
+ if self.client.need_cloud_setting:
84
+ additional_signatures.append("credential_scopes=credential_scopes")
85
+ endpoint_parameter = cast(Parameter, self.client.endpoint_parameter)
86
+ retval.extend(
87
+ [
88
+ '_cloud = kwargs.pop("cloud_setting", None) or settings.current.azure_cloud # type: ignore',
89
+ "_endpoints = get_arm_endpoints(_cloud)",
90
+ f"if not {endpoint_parameter.client_name}:",
91
+ f' {endpoint_parameter.client_name} = _endpoints["resource_manager"]',
92
+ 'credential_scopes = kwargs.pop("credential_scopes", _endpoints["credential_scopes"])',
93
+ ]
94
+ )
81
95
  config_name = f"{self.client.name}Configuration"
82
96
  config_call = ", ".join(
83
97
  [
84
- f"{p.client_name}={p.client_name}"
98
+ (
99
+ f"{p.client_name}="
100
+ + (
101
+ f"cast(str, {p.client_name})"
102
+ if self.client.need_cloud_setting and p.location == ParameterLocation.ENDPOINT_PATH
103
+ else p.client_name
104
+ )
105
+ )
85
106
  for p in self.client.config.parameters.method
86
107
  if p.method_location != ParameterMethodLocation.KWARG
87
108
  ]
109
+ + additional_signatures
88
110
  + ["**kwargs"]
89
111
  )
90
- return f"self._config = {config_name}({config_call})"
112
+ retval.append(f"self._config = {config_name}({config_call})")
113
+ return retval
91
114
 
92
115
  @property
93
116
  def host_variable_name(self) -> str:
@@ -104,8 +127,11 @@ class ClientSerializer:
104
127
  result = []
105
128
  pipeline_client_name = self.client.pipeline_class(async_mode)
106
129
  endpoint_name = "base_url" if self.client.code_model.is_azure_flavor else "endpoint"
130
+ host_variable_name = (
131
+ f"cast(str, {self.host_variable_name})" if self.client.need_cloud_setting else self.host_variable_name
132
+ )
107
133
  params = {
108
- endpoint_name: self.host_variable_name,
134
+ endpoint_name: host_variable_name,
109
135
  "policies": "_policies",
110
136
  }
111
137
  if not self.client.code_model.is_legacy and self.client.request_id_header_name:
@@ -16,13 +16,29 @@ from ..models.utils import NamespaceType
16
16
  from .client_serializer import ClientSerializer, ConfigSerializer
17
17
  from .base_serializer import BaseSerializer
18
18
 
19
+ VERSION_MAP = {
20
+ "msrest": "0.7.1",
21
+ "isodate": "0.6.1",
22
+ "azure-mgmt-core": "1.5.0",
23
+ "azure-core": "1.30.0",
24
+ "typing-extensions": "4.6.0",
25
+ "corehttp": "1.0.0b6",
26
+ }
27
+
28
+ MIN_PYTHON_VERSION = "3.9"
29
+ MAX_PYTHON_VERSION = "3.12"
30
+
19
31
 
20
32
  class GeneralSerializer(BaseSerializer):
21
33
  """General serializer for SDK root level files"""
22
34
 
23
35
  def serialize_setup_file(self) -> str:
24
36
  template = self.env.get_template("packaging_templates/setup.py.jinja2")
25
- params = {}
37
+ params = {
38
+ "VERSION_MAP": VERSION_MAP,
39
+ "MIN_PYTHON_VERSION": MIN_PYTHON_VERSION,
40
+ "MAX_PYTHON_VERSION": MAX_PYTHON_VERSION,
41
+ }
26
42
  params.update(self.code_model.options)
27
43
  return template.render(code_model=self.code_model, **params)
28
44
 
@@ -48,6 +64,9 @@ class GeneralSerializer(BaseSerializer):
48
64
  "pkgutil_names": [".".join(package_parts[: i + 1]) for i in range(len(package_parts))],
49
65
  "init_names": ["/".join(package_parts[: i + 1]) + "/__init__.py" for i in range(len(package_parts))],
50
66
  "client_name": self.code_model.clients[0].name,
67
+ "VERSION_MAP": VERSION_MAP,
68
+ "MIN_PYTHON_VERSION": MIN_PYTHON_VERSION,
69
+ "MAX_PYTHON_VERSION": MAX_PYTHON_VERSION,
51
70
  }
52
71
  params.update(self.code_model.options)
53
72
  params.update(kwargs)
@@ -88,44 +107,33 @@ class GeneralSerializer(BaseSerializer):
88
107
  serialize_namespace=self.serialize_namespace,
89
108
  )
90
109
 
91
- def serialize_vendor_file(self) -> str:
92
- template = self.env.get_template("vendor.py.jinja2")
110
+ def need_utils_utils_file(self) -> str:
111
+ template = self.env.get_template("utils.py.jinja2")
93
112
  clients = self.code_model.get_clients(self.client_namespace)
94
113
 
95
114
  # configure imports
96
115
  file_import = FileImport(self.code_model)
97
- if self.code_model.need_vendored_mixin(self.client_namespace):
116
+ if self.code_model.need_utils_mixin:
98
117
  file_import.add_submodule_import(
99
118
  "abc",
100
119
  "ABC",
101
120
  ImportType.STDLIB,
102
121
  )
103
- file_import.add_submodule_import(
104
- "" if self.code_model.is_azure_flavor else "runtime",
105
- f"{'Async' if self.async_mode else ''}PipelineClient",
106
- ImportType.SDKCORE,
107
- TypingSection.TYPING,
108
- )
109
122
  file_import.add_msrest_import(
110
- serialize_namespace=self.serialize_namespace,
123
+ serialize_namespace=f"{self.serialize_namespace}._utils",
111
124
  msrest_import_type=MsrestImportType.SerializerDeserializer,
112
125
  typing_section=TypingSection.TYPING,
113
126
  )
114
- for client in clients:
115
- if client.has_mixin:
116
- file_import.add_submodule_import(
117
- "._configuration",
118
- f"{client.name}Configuration",
119
- ImportType.LOCAL,
120
- )
121
- if self.code_model.need_vendored_etag(self.client_namespace):
127
+ file_import.add_submodule_import("typing", "TypeVar", ImportType.STDLIB)
128
+ file_import.add_submodule_import("typing", "Generic", ImportType.STDLIB)
129
+ if self.code_model.need_utils_etag(self.client_namespace):
122
130
  file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
123
131
  file_import.add_submodule_import(
124
132
  "",
125
133
  "MatchConditions",
126
134
  ImportType.SDKCORE,
127
135
  )
128
- if self.code_model.need_vendored_form_data(self.async_mode, self.client_namespace):
136
+ if self.code_model.need_utils_form_data(self.async_mode, self.client_namespace):
129
137
  file_import.add_submodule_import("typing", "IO", ImportType.STDLIB)
130
138
  file_import.add_submodule_import("typing", "Tuple", ImportType.STDLIB)
131
139
  file_import.add_submodule_import("typing", "Union", ImportType.STDLIB)
@@ -135,12 +143,12 @@ class GeneralSerializer(BaseSerializer):
135
143
  file_import.add_submodule_import("typing", "Any", ImportType.STDLIB)
136
144
  file_import.add_submodule_import("typing", "List", ImportType.STDLIB)
137
145
  file_import.add_submodule_import(
138
- "._model_base",
146
+ ".._utils.model_base",
139
147
  "SdkJSONEncoder",
140
148
  ImportType.LOCAL,
141
149
  )
142
150
  file_import.add_submodule_import(
143
- "._model_base",
151
+ ".._utils.model_base",
144
152
  "Model",
145
153
  ImportType.LOCAL,
146
154
  )
@@ -206,19 +214,33 @@ class GeneralSerializer(BaseSerializer):
206
214
  if not enum.internal
207
215
  }
208
216
  )
209
- cross_langauge_def_dict.update(
210
- {
211
- (
212
- f"{self.code_model.namespace}.{client.name}."
213
- + ("" if operation_group.is_mixin else f"{operation_group.property_name}.")
214
- + f"{operation.name}"
215
- ): operation.cross_language_definition_id
216
- for client in self.code_model.clients
217
- for operation_group in client.operation_groups
218
- for operation in operation_group.operations
219
- if not operation.name.startswith("_")
220
- }
221
- )
217
+ for client in self.code_model.clients:
218
+ for operation_group in client.operation_groups:
219
+ for operation in operation_group.operations:
220
+ if operation.name.startswith("_"):
221
+ continue
222
+ cross_langauge_def_dict.update(
223
+ {
224
+ f"{self.code_model.namespace}."
225
+ + (
226
+ f"{client.name}."
227
+ if operation_group.is_mixin
228
+ else f"operations.{operation_group.class_name}."
229
+ )
230
+ + f"{operation.name}": operation.cross_language_definition_id
231
+ }
232
+ )
233
+ cross_langauge_def_dict.update(
234
+ {
235
+ f"{self.code_model.namespace}.aio."
236
+ + (
237
+ f"{client.name}."
238
+ if operation_group.is_mixin
239
+ else f"operations.{operation_group.class_name}."
240
+ )
241
+ + f"{operation.name}": operation.cross_language_definition_id
242
+ }
243
+ )
222
244
  return json.dumps(
223
245
  {
224
246
  "CrossLanguagePackageId": self.code_model.cross_language_package_id,
@@ -230,10 +230,11 @@ class DpgModelSerializer(_ModelSerializer):
230
230
  file_import = FileImport(self.code_model)
231
231
  if any(not m.parents for m in self.models):
232
232
  file_import.add_submodule_import(
233
- self.code_model.get_relative_import_path(self.serialize_namespace),
234
- "_model_base",
233
+ self.code_model.get_relative_import_path(self.serialize_namespace, module_name="_utils.model_base"),
234
+ "Model",
235
235
  ImportType.LOCAL,
236
236
  TypingSection.REGULAR,
237
+ alias="_Model",
237
238
  )
238
239
  for model in self.models:
239
240
  if model.base == "json":
@@ -272,7 +273,7 @@ class DpgModelSerializer(_ModelSerializer):
272
273
  return file_import
273
274
 
274
275
  def declare_model(self, model: ModelType) -> str:
275
- basename = "_model_base.Model"
276
+ basename = "_Model"
276
277
  if model.parents:
277
278
  basename = ", ".join([m.name for m in model.parents])
278
279
  if model.discriminator_value:
@@ -109,6 +109,7 @@ class ParameterSerializer:
109
109
  return f"[{serialize_line} if q is not None else '' for q in {origin_name}]"
110
110
  return serialize_line
111
111
 
112
+ # pylint: disable=line-too-long
112
113
  def serialize_path(
113
114
  self,
114
115
  parameters: Union[
@@ -124,7 +125,11 @@ class ParameterSerializer:
124
125
  [
125
126
  ' "{}": {},'.format(
126
127
  path_parameter.wire_name,
127
- self.serialize_parameter(path_parameter, serializer_name),
128
+ (
129
+ f'"" if {path_parameter.full_client_name} is None else "/" + {self.serialize_parameter(path_parameter, serializer_name)}'
130
+ if path_parameter.optional and isinstance(path_parameter, RequestBuilderParameter)
131
+ else self.serialize_parameter(path_parameter, serializer_name)
132
+ ),
128
133
  )
129
134
  for path_parameter in parameters
130
135
  ]
@@ -62,7 +62,7 @@ class SampleSerializer(BaseSerializer):
62
62
  ImportType.SDKCORE,
63
63
  )
64
64
  for param in self.operation.parameters.positional + self.operation.parameters.keyword_only:
65
- if not param.client_default_value and not param.optional and param.wire_name in self.sample_params:
65
+ if param.client_default_value is None and not param.optional and param.wire_name in self.sample_params:
66
66
  imports.merge(param.type.imports_for_sample())
67
67
  return FileImportSerializer(imports, True)
68
68
 
@@ -80,7 +80,7 @@ class SampleSerializer(BaseSerializer):
80
80
  for p in (
81
81
  self.code_model.clients[0].parameters.positional + self.code_model.clients[0].parameters.keyword_only
82
82
  )
83
- if not (p.optional or p.client_default_value)
83
+ if not p.optional and p.client_default_value is None
84
84
  ]
85
85
  client_params = {
86
86
  p.client_name: special_param.get(