@typespec/http-client-python 0.13.0-dev.1 → 0.13.0-dev.3

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 (128) hide show
  1. package/dist/emitter/types.d.ts.map +1 -1
  2. package/dist/emitter/types.js +12 -5
  3. package/dist/emitter/types.js.map +1 -1
  4. package/emitter/src/types.ts +14 -7
  5. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  6. package/eng/scripts/setup/__pycache__/package_manager.cpython-39.pyc +0 -0
  7. package/eng/scripts/setup/__pycache__/venvtools.cpython-39.pyc +0 -0
  8. package/eng/scripts/setup/build_pygen_wheel.py +9 -10
  9. package/eng/scripts/setup/install.py +13 -17
  10. package/eng/scripts/setup/package_manager.py +139 -0
  11. package/eng/scripts/setup/prepare.py +4 -12
  12. package/eng/scripts/setup/venvtools.py +1 -42
  13. package/generator/build/lib/pygen/__init__.py +176 -2
  14. package/generator/build/lib/pygen/black.py +1 -1
  15. package/generator/build/lib/pygen/codegen/__init__.py +4 -256
  16. package/generator/build/lib/pygen/codegen/_utils.py +0 -3
  17. package/generator/build/lib/pygen/codegen/models/__init__.py +1 -1
  18. package/generator/build/lib/pygen/codegen/models/base_builder.py +1 -1
  19. package/generator/build/lib/pygen/codegen/models/client.py +12 -12
  20. package/generator/build/lib/pygen/codegen/models/code_model.py +10 -9
  21. package/generator/build/lib/pygen/codegen/models/enum_type.py +4 -4
  22. package/generator/build/lib/pygen/codegen/models/imports.py +1 -1
  23. package/generator/build/lib/pygen/codegen/models/list_type.py +6 -6
  24. package/generator/build/lib/pygen/codegen/models/lro_operation.py +1 -1
  25. package/generator/build/lib/pygen/codegen/models/operation.py +16 -16
  26. package/generator/build/lib/pygen/codegen/models/operation_group.py +4 -4
  27. package/generator/build/lib/pygen/codegen/models/paging_operation.py +4 -4
  28. package/generator/build/lib/pygen/codegen/models/parameter.py +8 -8
  29. package/generator/build/lib/pygen/codegen/models/property.py +7 -1
  30. package/generator/build/lib/pygen/codegen/models/request_builder.py +2 -2
  31. package/generator/build/lib/pygen/codegen/models/request_builder_parameter.py +2 -2
  32. package/generator/build/lib/pygen/codegen/models/response.py +3 -3
  33. package/generator/build/lib/pygen/codegen/serializers/__init__.py +27 -28
  34. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +31 -31
  35. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +4 -4
  36. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +4 -4
  37. package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +1 -1
  38. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +1 -1
  39. package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +1 -1
  40. package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +1 -1
  41. package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +5 -5
  42. package/generator/build/lib/pygen/codegen/templates/config.py.jinja2 +1 -1
  43. package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +1 -1
  44. package/generator/build/lib/pygen/codegen/templates/conftest.py.jinja2 +1 -1
  45. package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +1 -1
  46. package/generator/build/lib/pygen/codegen/templates/metadata.json.jinja2 +2 -2
  47. package/generator/build/lib/pygen/codegen/templates/model_dpg.py.jinja2 +2 -2
  48. package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +1 -1
  49. package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  50. package/generator/build/lib/pygen/codegen/templates/operation_tools.jinja2 +1 -1
  51. package/generator/build/lib/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +1 -1
  52. package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +38 -7
  53. package/generator/build/lib/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +1 -1
  54. package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +9 -9
  55. package/generator/build/lib/pygen/codegen/templates/request_builder.py.jinja2 +1 -1
  56. package/generator/build/lib/pygen/codegen/templates/sample.py.jinja2 +1 -1
  57. package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +6 -6
  58. package/generator/build/lib/pygen/codegen/templates/version.py.jinja2 +1 -1
  59. package/generator/build/lib/pygen/preprocess/__init__.py +1 -1
  60. package/generator/build/lib/pygen/utils.py +4 -0
  61. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  62. package/generator/pygen/__init__.py +176 -2
  63. package/generator/pygen/black.py +1 -1
  64. package/generator/pygen/codegen/__init__.py +4 -256
  65. package/generator/pygen/codegen/_utils.py +0 -3
  66. package/generator/pygen/codegen/models/__init__.py +1 -1
  67. package/generator/pygen/codegen/models/base_builder.py +1 -1
  68. package/generator/pygen/codegen/models/client.py +12 -12
  69. package/generator/pygen/codegen/models/code_model.py +10 -9
  70. package/generator/pygen/codegen/models/enum_type.py +4 -4
  71. package/generator/pygen/codegen/models/imports.py +1 -1
  72. package/generator/pygen/codegen/models/list_type.py +6 -6
  73. package/generator/pygen/codegen/models/lro_operation.py +1 -1
  74. package/generator/pygen/codegen/models/operation.py +16 -16
  75. package/generator/pygen/codegen/models/operation_group.py +4 -4
  76. package/generator/pygen/codegen/models/paging_operation.py +4 -4
  77. package/generator/pygen/codegen/models/parameter.py +8 -8
  78. package/generator/pygen/codegen/models/property.py +7 -1
  79. package/generator/pygen/codegen/models/request_builder.py +2 -2
  80. package/generator/pygen/codegen/models/request_builder_parameter.py +2 -2
  81. package/generator/pygen/codegen/models/response.py +3 -3
  82. package/generator/pygen/codegen/serializers/__init__.py +27 -28
  83. package/generator/pygen/codegen/serializers/builder_serializer.py +31 -31
  84. package/generator/pygen/codegen/serializers/client_serializer.py +4 -4
  85. package/generator/pygen/codegen/serializers/general_serializer.py +4 -4
  86. package/generator/pygen/codegen/serializers/metadata_serializer.py +1 -1
  87. package/generator/pygen/codegen/serializers/model_serializer.py +1 -1
  88. package/generator/pygen/codegen/serializers/operations_init_serializer.py +1 -1
  89. package/generator/pygen/codegen/serializers/sample_serializer.py +1 -1
  90. package/generator/pygen/codegen/serializers/test_serializer.py +5 -5
  91. package/generator/pygen/codegen/templates/config.py.jinja2 +1 -1
  92. package/generator/pygen/codegen/templates/config_container.py.jinja2 +1 -1
  93. package/generator/pygen/codegen/templates/conftest.py.jinja2 +1 -1
  94. package/generator/pygen/codegen/templates/init.py.jinja2 +1 -1
  95. package/generator/pygen/codegen/templates/metadata.json.jinja2 +2 -2
  96. package/generator/pygen/codegen/templates/model_dpg.py.jinja2 +2 -2
  97. package/generator/pygen/codegen/templates/operation_group.py.jinja2 +1 -1
  98. package/generator/pygen/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  99. package/generator/pygen/codegen/templates/operation_tools.jinja2 +1 -1
  100. package/generator/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +1 -1
  101. package/generator/pygen/codegen/templates/packaging_templates/README.md.jinja2 +38 -7
  102. package/generator/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +1 -1
  103. package/generator/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +9 -9
  104. package/generator/pygen/codegen/templates/request_builder.py.jinja2 +1 -1
  105. package/generator/pygen/codegen/templates/sample.py.jinja2 +1 -1
  106. package/generator/pygen/codegen/templates/test.py.jinja2 +6 -6
  107. package/generator/pygen/codegen/templates/version.py.jinja2 +1 -1
  108. package/generator/pygen/preprocess/__init__.py +1 -1
  109. package/generator/pygen/utils.py +4 -0
  110. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_commonproperties_async.py +31 -0
  111. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_largeheader_async.py +30 -0
  112. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_nonresource_async.py +36 -0
  113. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_initialization_async.py +9 -0
  114. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_deserialize_empty_string_as_null_async.py +20 -0
  115. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_usage_async.py +7 -0
  116. package/generator/test/azure/mock_api_tests/asynctests/test_azure_encode_duration_async.py +19 -0
  117. package/generator/test/azure/mock_api_tests/test_azure_arm_commonproperties.py +29 -0
  118. package/generator/test/azure/mock_api_tests/test_azure_arm_largeheader.py +27 -0
  119. package/generator/test/azure/mock_api_tests/test_azure_arm_nonresource.py +34 -0
  120. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_initialization.py +8 -0
  121. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_deserialize_empty_string_as_null.py +19 -0
  122. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_usage.py +4 -0
  123. package/generator/test/azure/mock_api_tests/test_azure_encode_duration.py +18 -0
  124. package/generator/test/azure/requirements.txt +4 -0
  125. package/generator/test/unittests/test_optional_return_type.py +5 -5
  126. package/generator/test/unittests/test_parameter_ordering.py +5 -5
  127. package/generator/test/unittests/test_sort_schema.py +4 -4
  128. package/package.json +1 -1
@@ -124,7 +124,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
124
124
  return successful_response_with_body and successful_response_without_body
125
125
 
126
126
  def response_type_annotation(self, **kwargs) -> str:
127
- if self.code_model.options["head_as_boolean"] and self.request_builder.method.lower() == "head":
127
+ if self.code_model.options["head-as-boolean"] and self.request_builder.method.lower() == "head":
128
128
  return "bool"
129
129
  response_type_annotations: OrderedSet[str] = {
130
130
  response.type_annotation(**kwargs): None for response in self.responses if response.type
@@ -148,13 +148,13 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
148
148
  return retval
149
149
 
150
150
  def cls_type_annotation(self, *, async_mode: bool, **kwargs: Any) -> str:
151
- if self.request_builder.method.lower() == "head" and self.code_model.options["head_as_boolean"]:
151
+ if self.request_builder.method.lower() == "head" and self.code_model.options["head-as-boolean"]:
152
152
  return "ClsType[None]"
153
153
  return f"ClsType[{self.response_type_annotation(async_mode=async_mode, **kwargs)}]"
154
154
 
155
155
  def _response_docstring_helper(self, attr_name: str, **kwargs: Any) -> str:
156
156
  responses_with_body = [r for r in self.responses if r.type]
157
- if self.request_builder.method.lower() == "head" and self.code_model.options["head_as_boolean"]:
157
+ if self.request_builder.method.lower() == "head" and self.code_model.options["head-as-boolean"]:
158
158
  return "bool"
159
159
  if responses_with_body:
160
160
  response_docstring_values: OrderedSet[str] = {
@@ -170,9 +170,9 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
170
170
 
171
171
  def response_docstring_text(self, **kwargs) -> str:
172
172
  retval = self._response_docstring_helper("docstring_text", **kwargs)
173
- if not self.code_model.options["version_tolerant"]:
173
+ if not self.code_model.options["version-tolerant"]:
174
174
  retval += " or the result of cls(response)"
175
- if self.code_model.options["models_mode"] == "dpg" and any(
175
+ if self.code_model.options["models-mode"] == "dpg" and any(
176
176
  isinstance(r.type, ModelType) for r in self.responses
177
177
  ):
178
178
  r = next(r for r in self.responses if isinstance(r.type, ModelType))
@@ -202,7 +202,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
202
202
  exception_schema = default_exceptions[0].type
203
203
  if isinstance(exception_schema, ModelType):
204
204
  return exception_schema.type_annotation(skip_quote=True)
205
- return None if self.code_model.options["models_mode"] == "dpg" else "'object'"
205
+ return None if self.code_model.options["models-mode"] == "dpg" else "'object'"
206
206
 
207
207
  @property
208
208
  def non_default_errors(self) -> List[Response]:
@@ -248,7 +248,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
248
248
  async_mode=async_mode, need_import_iobase=self.need_import_iobase, **kwargs
249
249
  )
250
250
  )
251
- if self.code_model.options["models_mode"]:
251
+ if self.code_model.options["models-mode"]:
252
252
  for exception in self.exceptions:
253
253
  file_import.merge(
254
254
  exception.imports_for_multiapi(
@@ -275,7 +275,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
275
275
  @property
276
276
  def need_validation(self) -> bool:
277
277
  """Whether we need parameter / operation validation. For API version."""
278
- return self.code_model.options["validate_versioning"] and (
278
+ return self.code_model.options["validate-versioning"] and (
279
279
  bool(self.added_on) or any(p for p in self.parameters if p.added_on)
280
280
  )
281
281
 
@@ -287,7 +287,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
287
287
  ) -> FileImport:
288
288
  """Helper method to get a request builder import."""
289
289
  file_import = FileImport(self.code_model)
290
- if self.code_model.options["builders_visibility"] != "embedded":
290
+ if self.code_model.options["builders-visibility"] != "embedded":
291
291
  group_name = request_builder.group_name
292
292
  rest_import_path = "..." if async_mode else ".."
293
293
  if group_name:
@@ -304,7 +304,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
304
304
  import_type=ImportType.LOCAL,
305
305
  alias="rest",
306
306
  )
307
- if self.code_model.options["builders_visibility"] == "embedded" and async_mode:
307
+ if self.code_model.options["builders-visibility"] == "embedded" and async_mode:
308
308
  file_import.add_submodule_import(
309
309
  self.code_model.get_relative_import_path(
310
310
  serialize_namespace,
@@ -341,7 +341,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
341
341
  file_import.merge(
342
342
  response.imports(async_mode=async_mode, need_import_iobase=self.need_import_iobase, **kwargs)
343
343
  )
344
- if self.code_model.options["models_mode"]:
344
+ if self.code_model.options["models-mode"]:
345
345
  for exception in self.exceptions:
346
346
  file_import.merge(exception.imports(async_mode=async_mode, **kwargs))
347
347
 
@@ -369,7 +369,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
369
369
  errors.extend(["StreamConsumedError", "StreamClosedError"])
370
370
  for error in errors:
371
371
  file_import.add_submodule_import("exceptions", error, ImportType.SDKCORE)
372
- if self.code_model.options["azure_arm"]:
372
+ if self.code_model.options["azure-arm"]:
373
373
  file_import.add_submodule_import("azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.SDKCORE)
374
374
  file_import.add_mutable_mapping_import()
375
375
 
@@ -418,7 +418,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
418
418
  "HttpResponse",
419
419
  ImportType.SDKCORE,
420
420
  )
421
- if self.code_model.options["builders_visibility"] == "embedded" and not async_mode:
421
+ if self.code_model.options["builders-visibility"] == "embedded" and not async_mode:
422
422
  file_import.merge(self.request_builder.imports(**kwargs))
423
423
  file_import.add_submodule_import(
424
424
  f"{'' if self.code_model.is_azure_flavor else 'runtime.'}pipeline",
@@ -439,7 +439,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
439
439
  file_import.merge(self.get_request_builder_import(self.request_builder, async_mode, serialize_namespace))
440
440
  if self.overloads:
441
441
  file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
442
- if self.code_model.options["models_mode"] == "dpg":
442
+ if self.code_model.options["models-mode"] == "dpg":
443
443
  relative_path = self.code_model.get_relative_import_path(
444
444
  serialize_namespace, module_name="_utils.model_base"
445
445
  )
@@ -491,7 +491,7 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
491
491
  # in a mixin
492
492
  basename = self.code_model.clients[0].legacy_filename
493
493
 
494
- if basename == "operations" or self.code_model.options["combine_operation_files"]:
494
+ if basename == "operations" or self.code_model.options["combine-operation-files"]:
495
495
  return "_operations"
496
496
  return f"_{basename}_operations"
497
497
 
@@ -543,7 +543,7 @@ class Operation(OperationBase[Response]):
543
543
  "distributed_trace_async",
544
544
  ImportType.SDKCORE,
545
545
  )
546
- if self.has_response_body and not self.has_optional_return_type and not self.code_model.options["models_mode"]:
546
+ if self.has_response_body and not self.has_optional_return_type and not self.code_model.options["models-mode"]:
547
547
  file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
548
548
 
549
549
  return file_import
@@ -40,7 +40,7 @@ class OperationGroup(BaseModel):
40
40
  self.operations = operations
41
41
  self.api_versions = api_versions
42
42
  self.operation_groups: List[OperationGroup] = []
43
- if self.code_model.options["show_operations"]:
43
+ if self.code_model.options["show-operations"]:
44
44
  self.operation_groups = [
45
45
  OperationGroup.from_yaml(op_group, code_model, client)
46
46
  for op_group in self.yaml_data.get("operationGroups", [])
@@ -78,7 +78,7 @@ class OperationGroup(BaseModel):
78
78
  for operation in self.operations:
79
79
  file_import.merge(operation.imports_for_multiapi(async_mode, **kwargs))
80
80
  if (self.code_model.model_types or self.code_model.enums) and self.code_model.options[
81
- "models_mode"
81
+ "models-mode"
82
82
  ] == "msrest":
83
83
  file_import.add_submodule_import(relative_path, "models", ImportType.LOCAL, alias="_models")
84
84
  return file_import
@@ -110,7 +110,7 @@ class OperationGroup(BaseModel):
110
110
 
111
111
  for operation in self.operations:
112
112
  file_import.merge(operation.imports(async_mode, **kwargs))
113
- if not self.code_model.options["combine_operation_files"]:
113
+ if not self.code_model.options["combine-operation-files"]:
114
114
  for og in self.operation_groups:
115
115
  file_import.add_submodule_import(
116
116
  self.code_model.get_relative_import_path(
@@ -138,7 +138,7 @@ class OperationGroup(BaseModel):
138
138
  # for multiapi
139
139
  if (
140
140
  (self.code_model.public_model_types)
141
- and self.code_model.options["models_mode"] == "msrest"
141
+ and self.code_model.options["models-mode"] == "msrest"
142
142
  and not self.is_mixin
143
143
  ):
144
144
  file_import.add_submodule_import(
@@ -92,14 +92,14 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
92
92
  if not wire_name:
93
93
  # That's an ok scenario, it just means no next page possible
94
94
  return None
95
- if self.code_model.options["models_mode"] == "msrest":
95
+ if self.code_model.options["models-mode"] == "msrest":
96
96
  return self._get_attr_name(wire_name)
97
97
  return wire_name
98
98
 
99
99
  @property
100
100
  def item_name(self) -> str:
101
101
  wire_name = self.yaml_data["itemName"]
102
- if self.code_model.options["models_mode"] == "msrest":
102
+ if self.code_model.options["models-mode"] == "msrest":
103
103
  # we don't use the paging model for dpg
104
104
  return self._get_attr_name(wire_name)
105
105
  return wire_name
@@ -135,7 +135,7 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
135
135
  )
136
136
  if (
137
137
  self.next_request_builder
138
- and self.code_model.options["builders_visibility"] == "embedded"
138
+ and self.code_model.options["builders-visibility"] == "embedded"
139
139
  and not async_mode
140
140
  ):
141
141
  file_import.merge(self.next_request_builder.imports(**kwargs))
@@ -168,7 +168,7 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
168
168
  "case_insensitive_dict",
169
169
  ImportType.SDKCORE,
170
170
  )
171
- if self.code_model.options["models_mode"] == "dpg":
171
+ if self.code_model.options["models-mode"] == "dpg":
172
172
  relative_path = self.code_model.get_relative_import_path(
173
173
  serialize_namespace, module_name="_utils.model_base"
174
174
  )
@@ -237,7 +237,7 @@ class BodyParameter(_ParameterBase):
237
237
  return (
238
238
  self.type.is_form_data
239
239
  or bool(self.entries)
240
- or ("multipart/form-data" in self.content_types and self.code_model.options["from_typespec"])
240
+ or ("multipart/form-data" in self.content_types and self.code_model.options["from-typespec"])
241
241
  )
242
242
 
243
243
  @property
@@ -314,7 +314,7 @@ class Parameter(_ParameterBase):
314
314
 
315
315
  @property
316
316
  def hide_in_operation_signature(self) -> bool:
317
- if self.code_model.options["version_tolerant"] and self.client_name == "maxpagesize":
317
+ if self.code_model.options["version-tolerant"] and self.client_name == "maxpagesize":
318
318
  return True
319
319
  return self.is_continuation_token
320
320
 
@@ -342,7 +342,7 @@ class Parameter(_ParameterBase):
342
342
  ) -> ParameterMethodLocation:
343
343
  if not self.in_method_signature:
344
344
  raise ValueError(f"Parameter '{self.client_name}' is not in the method.")
345
- if self.code_model.options["models_mode"] == "dpg" and self.in_flattened_body:
345
+ if self.code_model.options["models-mode"] == "dpg" and self.in_flattened_body:
346
346
  return ParameterMethodLocation.KEYWORD_ONLY
347
347
  if self.grouper:
348
348
  return ParameterMethodLocation.POSITIONAL
@@ -356,7 +356,7 @@ class Parameter(_ParameterBase):
356
356
  ParameterLocation.HEADER,
357
357
  ParameterLocation.QUERY,
358
358
  )
359
- if self.code_model.options["only_path_and_body_params_positional"] and query_or_header:
359
+ if self.code_model.options["only-path-and-body-params-positional"] and query_or_header:
360
360
  return ParameterMethodLocation.KEYWORD_ONLY
361
361
  # for optional path parameter, we need to use keyword only
362
362
  if self.location == ParameterLocation.PATH and self.optional:
@@ -385,15 +385,15 @@ class ClientParameter(Parameter):
385
385
  return ParameterMethodLocation.KWARG
386
386
  if (
387
387
  self.is_host
388
- and (self.code_model.options["version_tolerant"] or self.code_model.options["low_level_client"])
389
- and not self.code_model.options["azure_arm"]
388
+ and (self.code_model.options["version-tolerant"] or self.code_model.options["low-level-client"])
389
+ and not self.code_model.options["azure-arm"]
390
390
  ):
391
391
  # this means i am the base url
392
392
  return ParameterMethodLocation.KEYWORD_ONLY
393
393
  if (
394
394
  self.client_default_value is not None
395
- and self.code_model.options["from_typespec"]
396
- and not self.code_model.options["azure_arm"]
395
+ and self.code_model.options["from-typespec"]
396
+ and not self.code_model.options["azure-arm"]
397
397
  ):
398
398
  return ParameterMethodLocation.KEYWORD_ONLY
399
399
  return ParameterMethodLocation.POSITIONAL
@@ -87,11 +87,17 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
87
87
  def is_enum_discriminator(self) -> bool:
88
88
  return self.is_discriminator and self.type.type == "enum"
89
89
 
90
+ @property
91
+ def is_combined_discriminator(self) -> bool:
92
+ return self.is_discriminator and self.type.type == "combined"
93
+
90
94
  @property
91
95
  def is_base_discriminator(self) -> bool:
92
96
  """If this discriminator is on the base model for polymorphic inheritance"""
93
97
  if self.is_enum_discriminator:
94
98
  return self.is_polymorphic and self.client_default_value is None
99
+ if self.is_combined_discriminator:
100
+ return True
95
101
  return self.is_discriminator and self.is_polymorphic and cast(ConstantType, self.type).value is None
96
102
 
97
103
  @property
@@ -146,7 +152,7 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
146
152
  file_import.merge(self.type.imports(**kwargs))
147
153
  if (self.optional and self.client_default_value is None) or self.readonly:
148
154
  file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
149
- if self.code_model.options["models_mode"] == "dpg":
155
+ if self.code_model.options["models-mode"] == "dpg":
150
156
  serialize_namespace = kwargs.get("serialize_namespace", self.code_model.namespace)
151
157
  file_import.add_submodule_import(
152
158
  self.code_model.get_relative_import_path(serialize_namespace, module_name="_utils.model_base"),
@@ -110,7 +110,7 @@ class RequestBuilderBase(BaseBuilder[ParameterListType, Sequence["RequestBuilder
110
110
  msrest_import_type=MsrestImportType.Serializer,
111
111
  typing_section=TypingSection.REGULAR,
112
112
  )
113
- if self.overloads and self.code_model.options["builders_visibility"] != "embedded":
113
+ if self.overloads and self.code_model.options["builders-visibility"] != "embedded":
114
114
  file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
115
115
  return file_import
116
116
 
@@ -127,7 +127,7 @@ class RequestBuilderBase(BaseBuilder[ParameterListType, Sequence["RequestBuilder
127
127
  client: "Client",
128
128
  ) -> str:
129
129
  additional_mark = ""
130
- if code_model.options["combine_operation_files"] and code_model.options["builders_visibility"] == "embedded":
130
+ if code_model.options["combine-operation-files"] and code_model.options["builders-visibility"] == "embedded":
131
131
  additional_mark = yaml_data["groupName"] or client.yaml_data["builderPadName"]
132
132
  names = [
133
133
  "build",
@@ -26,7 +26,7 @@ class RequestBuilderBodyParameter(BodyParameter):
26
26
  if (
27
27
  isinstance(self.type, (BinaryType, StringType))
28
28
  or any("xml" in ct for ct in self.content_types)
29
- or self.code_model.options["models_mode"] == "dpg"
29
+ or self.code_model.options["models-mode"] == "dpg"
30
30
  ):
31
31
  self.client_name = "content"
32
32
  else:
@@ -40,7 +40,7 @@ class RequestBuilderBodyParameter(BodyParameter):
40
40
  @property
41
41
  def in_method_signature(self) -> bool:
42
42
  return (
43
- super().in_method_signature and not self.is_partial_body and self.code_model.options["models_mode"] != "dpg"
43
+ super().in_method_signature and not self.is_partial_body and self.code_model.options["models-mode"] != "dpg"
44
44
  )
45
45
 
46
46
  @property
@@ -191,7 +191,7 @@ class PagingResponse(Response):
191
191
 
192
192
  def docstring_text(self, **kwargs: Any) -> str:
193
193
  base_description = "An iterator like instance of "
194
- if not self.code_model.options["version_tolerant"]:
194
+ if not self.code_model.options["version-tolerant"]:
195
195
  base_description += "either "
196
196
  return base_description + self.item_type.docstring_text(**kwargs)
197
197
 
@@ -266,7 +266,7 @@ class LROResponse(Response):
266
266
  def docstring_text(self, **kwargs) -> str:
267
267
  super_text = super().docstring_text(**kwargs)
268
268
  base_description = f"An instance of {self.get_poller(kwargs.get('async_mode', False))} that returns "
269
- if not self.code_model.options["version_tolerant"]:
269
+ if not self.code_model.options["version-tolerant"]:
270
270
  base_description += "either "
271
271
  return base_description + super_text
272
272
 
@@ -321,7 +321,7 @@ class LROPagingResponse(LROResponse, PagingResponse):
321
321
 
322
322
  def docstring_text(self, **kwargs) -> str:
323
323
  base_description = "An instance of LROPoller that returns an iterator like instance of "
324
- if not self.code_model.options["version_tolerant"]:
324
+ if not self.code_model.options["version-tolerant"]:
325
325
  base_description += "either "
326
326
  return base_description + Response.docstring_text(self)
327
327
 
@@ -33,8 +33,7 @@ from .patch_serializer import PatchSerializer
33
33
  from .sample_serializer import SampleSerializer
34
34
  from .test_serializer import TestSerializer, TestGeneralSerializer
35
35
  from .types_serializer import TypesSerializer
36
- from ...utils import to_snake_case
37
- from .._utils import VALID_PACKAGE_MODE
36
+ from ...utils import to_snake_case, VALID_PACKAGE_MODE
38
37
  from .utils import (
39
38
  extract_sample_name,
40
39
  get_namespace_from_package_name,
@@ -84,11 +83,11 @@ class JinjaSerializer(ReaderAndWriter):
84
83
 
85
84
  @property
86
85
  def has_aio_folder(self) -> bool:
87
- return not self.code_model.options["no_async"] and bool(self.code_model.has_operations)
86
+ return not self.code_model.options["no-async"] and bool(self.code_model.has_operations)
88
87
 
89
88
  @property
90
89
  def has_operations_folder(self) -> bool:
91
- return self.code_model.options["show_operations"] and bool(self.code_model.has_operations)
90
+ return self.code_model.options["show-operations"] and bool(self.code_model.has_operations)
92
91
 
93
92
  @property
94
93
  def serialize_loop(self) -> List[AsyncInfo]:
@@ -98,7 +97,7 @@ class JinjaSerializer(ReaderAndWriter):
98
97
 
99
98
  @property
100
99
  def keep_version_file(self) -> bool:
101
- if self.options.get("keep_version_file"):
100
+ if self.options.get("keep-version-file"):
102
101
  return True
103
102
  # If the version file is already there and the version is greater than the current version, keep it.
104
103
  try:
@@ -107,7 +106,7 @@ class JinjaSerializer(ReaderAndWriter):
107
106
  serialized_version = match.group(1) if match else ""
108
107
  except (FileNotFoundError, IndexError):
109
108
  serialized_version = ""
110
- return serialized_version > self.code_model.options["package_version"]
109
+ return serialized_version > self.code_model.options.get("package-version", "")
111
110
 
112
111
  def serialize(self) -> None:
113
112
  env = Environment(
@@ -124,25 +123,25 @@ class JinjaSerializer(ReaderAndWriter):
124
123
  exec_path = self.exec_path(client_namespace)
125
124
  if client_namespace == "":
126
125
  # Write the setup file
127
- if self.code_model.options["basic_setup_py"]:
126
+ if self.code_model.options["basic-setup-py"]:
128
127
  self.write_file(exec_path / Path("setup.py"), general_serializer.serialize_setup_file())
129
128
 
130
129
  # add packaging files in root namespace (e.g. setup.py, README.md, etc.)
131
- if self.code_model.options["package_mode"]:
130
+ if self.code_model.options.get("package-mode"):
132
131
  self._serialize_and_write_package_files(client_namespace)
133
132
 
134
133
  # write apiview-properties.json
135
- if self.code_model.options.get("emit_cross_language_definition_file"):
134
+ if self.code_model.options.get("emit-cross-language-definition-file"):
136
135
  self.write_file(
137
136
  exec_path / Path("apiview-properties.json"),
138
137
  general_serializer.serialize_cross_language_definition_file(),
139
138
  )
140
139
 
141
140
  # add generated samples and generated tests
142
- if self.code_model.options["show_operations"] and self.code_model.has_operations:
143
- if self.code_model.options["generate_sample"]:
141
+ if self.code_model.options["show-operations"] and self.code_model.has_operations:
142
+ if self.code_model.options["generate-sample"]:
144
143
  self._serialize_and_write_sample(env, namespace=client_namespace)
145
- if self.code_model.options["generate_test"]:
144
+ if self.code_model.options["generate-test"]:
146
145
  self._serialize_and_write_test(env, namespace=client_namespace)
147
146
 
148
147
  # add _metadata.json
@@ -169,7 +168,7 @@ class JinjaSerializer(ReaderAndWriter):
169
168
  # add models folder if there are models in this namespace
170
169
  if (
171
170
  self.code_model.has_non_json_models(client_namespace_type.models) or client_namespace_type.enums
172
- ) and self.code_model.options["models_mode"]:
171
+ ) and self.code_model.options["models-mode"]:
173
172
  self._serialize_and_write_models_folder(
174
173
  env=env,
175
174
  namespace=client_namespace,
@@ -177,7 +176,7 @@ class JinjaSerializer(ReaderAndWriter):
177
176
  enums=client_namespace_type.enums,
178
177
  )
179
178
 
180
- if not self.code_model.options["models_mode"]:
179
+ if not self.code_model.options["models-mode"]:
181
180
  # keep models file if users ended up just writing a models file
182
181
  model_path = exec_path / Path("models.py")
183
182
  if self.read_file(model_path):
@@ -201,7 +200,7 @@ class JinjaSerializer(ReaderAndWriter):
201
200
 
202
201
  def _serialize_and_write_package_files(self, client_namespace: str) -> None:
203
202
  root_of_sdk = self.exec_path(client_namespace)
204
- if self.code_model.options["package_mode"] in VALID_PACKAGE_MODE:
203
+ if self.code_model.options["package-mode"] in VALID_PACKAGE_MODE:
205
204
  env = Environment(
206
205
  loader=PackageLoader("pygen.codegen", "templates/packaging_templates"),
207
206
  undefined=StrictUndefined,
@@ -212,9 +211,9 @@ class JinjaSerializer(ReaderAndWriter):
212
211
  package_files = _PACKAGE_FILES
213
212
  if not self.code_model.license_description:
214
213
  package_files.remove("LICENSE.jinja2")
215
- elif Path(self.code_model.options["package_mode"]).exists():
214
+ elif Path(self.code_model.options["package-mode"]).exists():
216
215
  env = Environment(
217
- loader=FileSystemLoader(str(Path(self.code_model.options["package_mode"]))),
216
+ loader=FileSystemLoader(str(Path(self.code_model.options["package-mode"]))),
218
217
  keep_trailing_newline=True,
219
218
  undefined=StrictUndefined,
220
219
  )
@@ -222,7 +221,7 @@ class JinjaSerializer(ReaderAndWriter):
222
221
  else:
223
222
  return
224
223
  serializer = GeneralSerializer(self.code_model, env, async_mode=False)
225
- params = self.code_model.options["packaging_files_config"] or {}
224
+ params = self.code_model.options.get("packaging-files-config", {})
226
225
  for template_name in package_files:
227
226
  if not self.code_model.is_azure_flavor and template_name == "dev_requirements.txt.jinja2":
228
227
  continue
@@ -251,7 +250,7 @@ class JinjaSerializer(ReaderAndWriter):
251
250
  ) -> None:
252
251
  # Write the models folder
253
252
  models_path = self.exec_path(namespace) / "models"
254
- serializer = DpgModelSerializer if self.code_model.options["models_mode"] == "dpg" else MsrestModelSerializer
253
+ serializer = DpgModelSerializer if self.code_model.options["models-mode"] == "dpg" else MsrestModelSerializer
255
254
  if self.code_model.has_non_json_models(models):
256
255
  self.write_file(
257
256
  models_path / Path(f"{self.code_model.models_filename}.py"),
@@ -332,7 +331,7 @@ class JinjaSerializer(ReaderAndWriter):
332
331
 
333
332
  # write operations file
334
333
  OgLoop = namedtuple("OgLoop", ["operation_groups", "filename"])
335
- if self.code_model.options["combine_operation_files"]:
334
+ if self.code_model.options["combine-operation-files"]:
336
335
  loops = [OgLoop(operation_groups, "_operations")]
337
336
  else:
338
337
  loops = [OgLoop([og], og.filename) for og in operation_groups]
@@ -372,7 +371,7 @@ class JinjaSerializer(ReaderAndWriter):
372
371
  _write_version_file(original_version_file_name="_version.py")
373
372
  elif self.keep_version_file and _read_version_file("version.py"):
374
373
  _write_version_file(original_version_file_name="version.py")
375
- elif self.code_model.options["package_version"]:
374
+ elif self.code_model.options.get("package-version"):
376
375
  self.write_file(
377
376
  exec_path / Path("_version.py"),
378
377
  general_serializer.serialize_version_file(),
@@ -437,7 +436,7 @@ class JinjaSerializer(ReaderAndWriter):
437
436
  )
438
437
 
439
438
  # write _model_base.py
440
- if self.code_model.options["models_mode"] == "dpg":
439
+ if self.code_model.options["models-mode"] == "dpg":
441
440
  self.write_file(
442
441
  utils_folder_path / Path("model_base.py"),
443
442
  general_serializer.serialize_model_base_file(),
@@ -479,7 +478,7 @@ class JinjaSerializer(ReaderAndWriter):
479
478
  """Assume the process is running in the root folder of the package. If not, we need the path compensation."""
480
479
  return (
481
480
  Path("../" * (self.code_model.namespace.count(".") + 1))
482
- if self.code_model.options["no_namespace_folders"]
481
+ if self.code_model.options["no-namespace-folders"]
483
482
  else Path(".")
484
483
  )
485
484
 
@@ -488,7 +487,7 @@ class JinjaSerializer(ReaderAndWriter):
488
487
 
489
488
  # pylint: disable=line-too-long
490
489
  def exec_path(self, namespace: str) -> Path:
491
- if self.code_model.options["no_namespace_folders"] and not self.code_model.options["multiapi"]:
490
+ if self.code_model.options["no-namespace-folders"] and not self.code_model.options["multiapi"]:
492
491
  # when output folder contains parts different from the namespace, we fall back to current folder directly.
493
492
  # (e.g. https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/communication/azure-communication-callautomation/swagger/SWAGGER.md)
494
493
  return Path(".")
@@ -506,7 +505,7 @@ class JinjaSerializer(ReaderAndWriter):
506
505
  namespace_config = get_namespace_config(self.code_model.namespace, self.code_model.options["multiapi"])
507
506
  num_of_namespace = namespace_config.count(".") + 1
508
507
  num_of_package_namespace = (
509
- get_namespace_from_package_name(self.code_model.options["package_name"]).count(".") + 1
508
+ get_namespace_from_package_name(self.code_model.options.get("namespace", "")).count(".") + 1
510
509
  )
511
510
  if num_of_namespace > num_of_package_namespace:
512
511
  return Path("/".join(namespace_config.split(".")[num_of_package_namespace:]))
@@ -519,7 +518,7 @@ class JinjaSerializer(ReaderAndWriter):
519
518
  for operation in op_group.operations:
520
519
  if (
521
520
  self.code_model.options["multiapi"]
522
- and operation.api_versions[0] != self.code_model.options["default_api_version"]
521
+ and operation.api_versions[0] != self.code_model.options["default-api-version"]
523
522
  ):
524
523
  continue
525
524
  samples = operation.yaml_data.get("samples")
@@ -550,7 +549,7 @@ class JinjaSerializer(ReaderAndWriter):
550
549
  out_path = self.exec_path_for_test_sample(namespace) / Path("generated_tests")
551
550
  general_serializer = TestGeneralSerializer(code_model=self.code_model, env=env)
552
551
  self.write_file(out_path / "conftest.py", general_serializer.serialize_conftest())
553
- if not self.code_model.options["azure_arm"]:
552
+ if not self.code_model.options["azure-arm"]:
554
553
  for async_mode in (True, False):
555
554
  async_suffix = "_async" if async_mode else ""
556
555
  general_serializer.async_mode = async_mode
@@ -562,7 +561,7 @@ class JinjaSerializer(ReaderAndWriter):
562
561
  for client in self.code_model.clients:
563
562
  for og in client.operation_groups:
564
563
  if self.code_model.options["multiapi"] and any(
565
- o.api_versions[0] != self.code_model.options["default_api_version"] for o in og.operations
564
+ o.api_versions[0] != self.code_model.options["default-api-version"] for o in og.operations
566
565
  ):
567
566
  continue
568
567
  test_serializer = TestSerializer(self.code_model, env, client=client, operation_group=og)