@azure-tools/typespec-python 0.28.0 → 0.30.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 (92) hide show
  1. package/dist/scripts/eng/format.d.ts +2 -0
  2. package/dist/scripts/eng/format.d.ts.map +1 -0
  3. package/dist/scripts/eng/format.js +4 -0
  4. package/dist/scripts/eng/format.js.map +1 -0
  5. package/dist/scripts/eng/lint.d.ts +5 -0
  6. package/dist/scripts/eng/lint.d.ts.map +1 -0
  7. package/dist/scripts/eng/lint.js +66 -0
  8. package/dist/scripts/eng/lint.js.map +1 -0
  9. package/dist/scripts/{regenerate.d.ts.map → eng/regenerate.d.ts.map} +1 -1
  10. package/dist/scripts/{regenerate.js → eng/regenerate.js} +33 -30
  11. package/dist/scripts/eng/regenerate.js.map +1 -0
  12. package/dist/scripts/eng/run-tests.d.ts +2 -0
  13. package/dist/scripts/eng/run-tests.d.ts.map +1 -0
  14. package/dist/scripts/eng/run-tests.js +71 -0
  15. package/dist/scripts/eng/run-tests.js.map +1 -0
  16. package/dist/scripts/eng/utils.d.ts +3 -0
  17. package/dist/scripts/eng/utils.d.ts.map +1 -0
  18. package/dist/scripts/eng/utils.js +39 -0
  19. package/dist/scripts/eng/utils.js.map +1 -0
  20. package/dist/scripts/run-python3.d.ts +2 -0
  21. package/dist/scripts/run-python3.d.ts.map +1 -0
  22. package/dist/scripts/run-python3.js +23 -0
  23. package/dist/scripts/run-python3.js.map +1 -0
  24. package/dist/scripts/system-requirements.d.ts +17 -0
  25. package/dist/scripts/system-requirements.d.ts.map +1 -0
  26. package/{scripts/system-requirements.cjs → dist/scripts/system-requirements.js} +80 -97
  27. package/dist/scripts/system-requirements.js.map +1 -0
  28. package/dist/src/code-model.d.ts.map +1 -1
  29. package/dist/src/code-model.js +23 -17
  30. package/dist/src/code-model.js.map +1 -1
  31. package/dist/src/emitter.d.ts.map +1 -1
  32. package/dist/src/emitter.js +14 -3
  33. package/dist/src/emitter.js.map +1 -1
  34. package/dist/src/external-process.js +1 -1
  35. package/dist/src/external-process.js.map +1 -1
  36. package/dist/src/http.js +34 -23
  37. package/dist/src/http.js.map +1 -1
  38. package/dist/src/lib.d.ts +1 -0
  39. package/dist/src/lib.d.ts.map +1 -1
  40. package/dist/src/lib.js +1 -0
  41. package/dist/src/lib.js.map +1 -1
  42. package/dist/src/types.d.ts +7 -1
  43. package/dist/src/types.d.ts.map +1 -1
  44. package/dist/src/types.js +42 -7
  45. package/dist/src/types.js.map +1 -1
  46. package/dist/src/utils.d.ts +3 -3
  47. package/dist/src/utils.d.ts.map +1 -1
  48. package/dist/src/utils.js +11 -13
  49. package/dist/src/utils.js.map +1 -1
  50. package/generator/pygen/black.py +2 -3
  51. package/generator/pygen/codegen/models/__init__.py +2 -0
  52. package/generator/pygen/codegen/models/code_model.py +2 -4
  53. package/generator/pygen/codegen/models/combined_type.py +1 -1
  54. package/generator/pygen/codegen/models/credential_types.py +7 -14
  55. package/generator/pygen/codegen/models/enum_type.py +1 -1
  56. package/generator/pygen/codegen/models/lro_operation.py +0 -1
  57. package/generator/pygen/codegen/models/lro_paging_operation.py +1 -1
  58. package/generator/pygen/codegen/models/model_type.py +6 -9
  59. package/generator/pygen/codegen/models/operation.py +13 -16
  60. package/generator/pygen/codegen/models/paging_operation.py +0 -1
  61. package/generator/pygen/codegen/models/parameter_list.py +2 -5
  62. package/generator/pygen/codegen/models/primitive_types.py +35 -3
  63. package/generator/pygen/codegen/models/property.py +1 -9
  64. package/generator/pygen/codegen/serializers/__init__.py +1 -1
  65. package/generator/pygen/codegen/serializers/builder_serializer.py +12 -13
  66. package/generator/pygen/codegen/serializers/general_serializer.py +2 -2
  67. package/generator/pygen/codegen/serializers/model_serializer.py +2 -0
  68. package/generator/pygen/codegen/serializers/sample_serializer.py +20 -15
  69. package/generator/pygen/codegen/templates/model_base.py.jinja2 +30 -18
  70. package/generator/pygen/codegen/templates/vendor.py.jinja2 +0 -2
  71. package/generator/pygen/m2r.py +1 -1
  72. package/generator/pygen/postprocess/__init__.py +2 -2
  73. package/generator/pygen/postprocess/venvtools.py +1 -3
  74. package/generator/pygen/preprocess/__init__.py +1 -1
  75. package/generator/pygen/utils.py +1 -3
  76. package/generator/setup.py +1 -1
  77. package/package.json +18 -25
  78. package/scripts/__pycache__/venvtools.cpython-310.pyc +0 -0
  79. package/scripts/eng/format.ts +5 -0
  80. package/scripts/eng/lint.ts +75 -0
  81. package/scripts/eng/mypy.ini +38 -0
  82. package/scripts/eng/pylintrc +58 -0
  83. package/scripts/eng/pyrightconfig.json +6 -0
  84. package/scripts/{regenerate.ts → eng/regenerate.ts} +45 -33
  85. package/scripts/eng/run-tests.ts +80 -0
  86. package/scripts/eng/utils.ts +38 -0
  87. package/scripts/run-python3.ts +25 -0
  88. package/scripts/run_tsp.py +7 -5
  89. package/scripts/system-requirements.ts +253 -0
  90. package/dist/scripts/regenerate.js.map +0 -1
  91. package/scripts/run-python3.cjs +0 -22
  92. /package/dist/scripts/{regenerate.d.ts → eng/regenerate.d.ts} +0 -0
@@ -418,8 +418,19 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
418
418
  file_import.merge(self.get_request_builder_import(self.request_builder, async_mode))
419
419
  if self.overloads:
420
420
  file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
421
- if self.non_default_errors and self.code_model.options["models_mode"] == "dpg":
422
- file_import.add_submodule_import(f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL)
421
+ if self.code_model.options["models_mode"] == "dpg":
422
+ if self.parameters.has_body:
423
+ if self.has_form_data_body:
424
+ file_import.add_submodule_import(relative_path, "_model_base", ImportType.LOCAL)
425
+ else:
426
+ file_import.add_submodule_import(
427
+ f"{relative_path}_model_base",
428
+ "SdkJSONEncoder",
429
+ ImportType.LOCAL,
430
+ )
431
+ file_import.add_import("json", ImportType.STDLIB)
432
+ if (self.default_error_deserialization or any(r.type for r in self.responses)) or self.non_default_errors:
433
+ file_import.add_submodule_import(f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL)
423
434
  return file_import
424
435
 
425
436
  def get_response_from_status(self, status_code: Optional[Union[str, int]]) -> ResponseType:
@@ -492,20 +503,6 @@ class Operation(OperationBase[Response]):
492
503
  )
493
504
  if self.has_response_body and not self.has_optional_return_type and not self.code_model.options["models_mode"]:
494
505
  file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
495
- relative_path = "..." if async_mode else ".."
496
- if self.code_model.options["models_mode"] == "dpg":
497
- if self.parameters.has_body:
498
- if self.has_form_data_body:
499
- file_import.add_submodule_import(relative_path, "_model_base", ImportType.LOCAL)
500
- else:
501
- file_import.add_submodule_import(
502
- f"{relative_path}_model_base",
503
- "SdkJSONEncoder",
504
- ImportType.LOCAL,
505
- )
506
- file_import.add_import("json", ImportType.STDLIB)
507
- if self.default_error_deserialization or any(r.type for r in self.responses):
508
- file_import.add_submodule_import(f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL)
509
506
 
510
507
  return file_import
511
508
 
@@ -1,4 +1,3 @@
1
- # pylint: disable=multiple-statements
2
1
  # -------------------------------------------------------------------------
3
2
  # Copyright (c) Microsoft Corporation. All rights reserved.
4
3
  # Licensed under the MIT License. See License.txt in the project root for
@@ -261,8 +261,7 @@ class _ParameterListBase(
261
261
  )
262
262
 
263
263
 
264
- class _ParameterList(_ParameterListBase[Parameter, BodyParameter]): # pylint: disable=unsubscriptable-object
265
- """Base Parameter class for the two operation ParameterLists"""
264
+ class _ParameterList(_ParameterListBase[Parameter, BodyParameter]):
266
265
 
267
266
  @staticmethod
268
267
  def parameter_creator() -> Callable[[Dict[str, Any], "CodeModel"], Parameter]:
@@ -285,9 +284,7 @@ class ParameterList(_ParameterList):
285
284
  """ParameterList is the parameter list for Operation classes"""
286
285
 
287
286
 
288
- class _RequestBuilderParameterList(
289
- _ParameterListBase[RequestBuilderParameter, RequestBuilderBodyParameter] # pylint: disable=unsubscriptable-object
290
- ):
287
+ class _RequestBuilderParameterList(_ParameterListBase[RequestBuilderParameter, RequestBuilderBodyParameter]):
291
288
  """_RequestBuilderParameterList is base parameter list for RequestBuilder classes"""
292
289
 
293
290
  @staticmethod
@@ -22,8 +22,8 @@ class RawString(object):
22
22
  return "r'{}'".format(self.string.replace("'", "\\'"))
23
23
 
24
24
 
25
- class PrimitiveType(BaseType): # pylint: disable=abstract-method
26
- def description(self, *, is_operation_file: bool) -> str: # pylint: disable=unused-argument
25
+ class PrimitiveType(BaseType):
26
+ def description(self, *, is_operation_file: bool) -> str:
27
27
  return ""
28
28
 
29
29
  def type_annotation(self, **kwargs: Any) -> str:
@@ -188,7 +188,7 @@ class AnyObjectType(PrimitiveType):
188
188
  return "JSON"
189
189
 
190
190
 
191
- class NumberType(PrimitiveType): # pylint: disable=abstract-method
191
+ class NumberType(PrimitiveType):
192
192
  def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
193
193
  super().__init__(yaml_data=yaml_data, code_model=code_model)
194
194
  self.precision: Optional[int] = yaml_data.get("precision")
@@ -233,6 +233,12 @@ class NumberType(PrimitiveType): # pylint: disable=abstract-method
233
233
 
234
234
 
235
235
  class IntegerType(NumberType):
236
+
237
+ def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
238
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
239
+ if yaml_data.get("encode") == "string":
240
+ self.encode = "str"
241
+
236
242
  @property
237
243
  def serialization_type(self) -> str:
238
244
  return "int"
@@ -624,3 +630,29 @@ class SdkCoreType(PrimitiveType):
624
630
  @property
625
631
  def serialization_type(self) -> str:
626
632
  return self.name
633
+
634
+
635
+ class MultiPartFileType(PrimitiveType):
636
+ def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
637
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
638
+ self.name = "FileType"
639
+
640
+ def type_annotation(self, **kwargs: Any) -> str:
641
+ return self.name
642
+
643
+ def docstring_type(self, **kwargs: Any) -> str:
644
+ return f"~{self.code_model.namespace}._vendor.{self.name}"
645
+
646
+ def imports(self, **kwargs: Any) -> FileImport:
647
+ file_import = super().imports(**kwargs)
648
+ relative_path = "..." if kwargs.get("async_mode") else ".."
649
+ file_import.add_submodule_import(f"{relative_path}_vendor", self.name, ImportType.LOCAL)
650
+ return file_import
651
+
652
+ @property
653
+ def default_template_representation_declaration(self) -> str:
654
+ return '"filetype"' if self.code_model.for_test else "filetype"
655
+
656
+ @property
657
+ def instance_check_template(self) -> str:
658
+ return f"isinstance({{}}, {self.name})"
@@ -97,12 +97,9 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
97
97
  return self.is_discriminator and self.is_polymorphic and cast(ConstantType, self.type).value is None
98
98
 
99
99
  def type_annotation(self, *, is_operation_file: bool = False) -> str:
100
- types_type_annotation = self.type.type_annotation(is_operation_file=is_operation_file)
101
- if self.is_multipart_file_input:
102
- # we only support FileType or list of FileType
103
- types_type_annotation = types_type_annotation.replace("bytes", "FileType")
104
100
  if self.is_base_discriminator:
105
101
  return "str"
102
+ types_type_annotation = self.type.type_annotation(is_operation_file=is_operation_file)
106
103
  if self.optional and self.client_default_value is None:
107
104
  return f"Optional[{types_type_annotation}]"
108
105
  return types_type_annotation
@@ -115,9 +112,6 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
115
112
  *,
116
113
  client_default_value_declaration: Optional[str] = None,
117
114
  ) -> Any:
118
- if self.is_multipart_file_input:
119
- file_type_str = '"filetype"' if self.code_model.for_test else "filetype"
120
- return f"[{file_type_str}]" if self.type.type == "list" else file_type_str
121
115
  if self.client_default_value:
122
116
  client_default_value_declaration = self.get_declaration(self.client_default_value)
123
117
  # make sure there is no \n otherwise the json template will be invalid
@@ -156,8 +150,6 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
156
150
  "rest_discriminator" if self.is_discriminator else "rest_field",
157
151
  ImportType.LOCAL,
158
152
  )
159
- if self.is_multipart_file_input:
160
- file_import.add_submodule_import(".._vendor", "FileType", ImportType.LOCAL)
161
153
  return file_import
162
154
 
163
155
  @classmethod
@@ -66,7 +66,7 @@ def _sample_output_path(source_file_path: str) -> Path:
66
66
  return Path("")
67
67
 
68
68
 
69
- class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
69
+ class JinjaSerializer(ReaderAndWriter):
70
70
  def __init__(
71
71
  self,
72
72
  code_model: CodeModel,
@@ -1,4 +1,4 @@
1
- # pylint: disable=too-many-lines,multiple-statements
1
+ # pylint: disable=too-many-lines
2
2
  # -------------------------------------------------------------------------
3
3
  # Copyright (c) Microsoft Corporation. All rights reserved.
4
4
  # Licensed under the MIT License. See License.txt in the project root for
@@ -23,7 +23,6 @@ from ..models import (
23
23
  BinaryType,
24
24
  BodyParameter,
25
25
  ParameterMethodLocation,
26
- RequestBuilderBodyParameter,
27
26
  OverloadedRequestBuilder,
28
27
  Property,
29
28
  RequestBuilderType,
@@ -218,7 +217,7 @@ def is_json_model_type(parameters: ParameterListType) -> bool:
218
217
  )
219
218
 
220
219
 
221
- class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-method
220
+ class _BuilderBaseSerializer(Generic[BuilderType]):
222
221
  def __init__(self, code_model: CodeModel, async_mode: bool) -> None:
223
222
  self.code_model = code_model
224
223
  self.async_mode = async_mode
@@ -391,7 +390,7 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
391
390
  ############################## REQUEST BUILDERS ##############################
392
391
 
393
392
 
394
- class RequestBuilderSerializer(_BuilderBaseSerializer[RequestBuilderType]): # pylint: disable=abstract-method
393
+ class RequestBuilderSerializer(_BuilderBaseSerializer[RequestBuilderType]):
395
394
  def description_and_summary(self, builder: RequestBuilderType) -> List[str]:
396
395
  retval = super().description_and_summary(builder)
397
396
  retval += [
@@ -517,7 +516,7 @@ class RequestBuilderSerializer(_BuilderBaseSerializer[RequestBuilderType]): # p
517
516
  ############################## NORMAL OPERATIONS ##############################
518
517
 
519
518
 
520
- class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: disable=abstract-method
519
+ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
521
520
  def description_and_summary(self, builder: OperationType) -> List[str]:
522
521
  retval = super().description_and_summary(builder)
523
522
  if builder.deprecated:
@@ -535,9 +534,9 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
535
534
  return "response"
536
535
 
537
536
  def example_template(self, builder: OperationType) -> List[str]:
537
+ if self.code_model.options["models_mode"] in ("msrest", "dpg"):
538
+ return []
538
539
  retval = super().example_template(builder)
539
- if self.code_model.options["models_mode"] == "msrest":
540
- return retval
541
540
  for response in builder.responses:
542
541
  polymorphic_subtypes: List[ModelType] = []
543
542
  if not response.type:
@@ -842,14 +841,14 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
842
841
  elif request_builder.overloads:
843
842
  seen_body_params = set()
844
843
  for overload in request_builder.overloads:
845
- body_param = cast(RequestBuilderBodyParameter, overload.parameters.body_parameter)
844
+ body_param = overload.parameters.body_parameter
846
845
  if body_param.client_name in seen_body_params:
847
846
  continue
848
847
  seen_body_params.add(body_param.client_name)
849
848
 
850
849
  retval.append(f" {body_param.client_name}={body_param.name_in_high_level_operation},")
851
850
  elif request_builder.parameters.has_body:
852
- body_param = cast(RequestBuilderBodyParameter, request_builder.parameters.body_parameter)
851
+ body_param = request_builder.parameters.body_parameter
853
852
  retval.append(f" {body_param.client_name}={body_param.name_in_high_level_operation},")
854
853
  retval.append(" headers=_headers,")
855
854
  retval.append(" params=_params,")
@@ -871,7 +870,7 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
871
870
  )
872
871
  return retval
873
872
 
874
- def _call_request_builder_helper( # pylint: disable=too-many-statements
873
+ def _call_request_builder_helper(
875
874
  self,
876
875
  builder: OperationType,
877
876
  request_builder: RequestBuilderType,
@@ -1031,7 +1030,7 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
1031
1030
  retval.append("deserialized = None")
1032
1031
  if builder.any_response_has_headers:
1033
1032
  retval.append("response_headers = {}")
1034
- if builder.has_response_body or builder.any_response_has_headers:
1033
+ if builder.has_response_body or builder.any_response_has_headers: # pylint: disable=too-many-nested-blocks
1035
1034
  if len(builder.responses) > 1:
1036
1035
  status_codes, res_headers, res_deserialization = [], [], []
1037
1036
  for status_code in builder.success_status_codes:
@@ -1173,7 +1172,7 @@ class OperationSerializer(_OperationSerializer[Operation]): ...
1173
1172
  PagingOperationType = TypeVar("PagingOperationType", bound=Union[PagingOperation, LROPagingOperation])
1174
1173
 
1175
1174
 
1176
- class _PagingOperationSerializer(_OperationSerializer[PagingOperationType]): # pylint: disable=abstract-method
1175
+ class _PagingOperationSerializer(_OperationSerializer[PagingOperationType]):
1177
1176
  def __init__(self, code_model: CodeModel, async_mode: bool) -> None:
1178
1177
  # for pylint reasons need to redefine init
1179
1178
  # probably because inheritance is going too deep
@@ -1458,7 +1457,7 @@ class LROOperationSerializer(_LROOperationSerializer[LROOperation]): ...
1458
1457
  class LROPagingOperationSerializer(
1459
1458
  _LROOperationSerializer[LROPagingOperation],
1460
1459
  _PagingOperationSerializer[LROPagingOperation],
1461
- ): # pylint: disable=abstract-method
1460
+ ):
1462
1461
  @property
1463
1462
  def _call_method(self) -> str:
1464
1463
  return "await " if self.async_mode else ""
@@ -124,7 +124,6 @@ class GeneralSerializer(BaseSerializer):
124
124
  file_import.add_submodule_import("typing", "Union", ImportType.STDLIB)
125
125
  file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
126
126
  file_import.add_submodule_import("typing", "Mapping", ImportType.STDLIB)
127
- file_import.add_submodule_import("typing", "Sequence", ImportType.STDLIB)
128
127
  file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB)
129
128
  file_import.add_submodule_import("typing", "Any", ImportType.STDLIB)
130
129
  file_import.add_submodule_import("typing", "List", ImportType.STDLIB)
@@ -183,12 +182,13 @@ class GeneralSerializer(BaseSerializer):
183
182
  def serialize_cross_language_definition_file(self) -> str:
184
183
  cross_langauge_def_dict = {
185
184
  f"{self.code_model.namespace}.models.{model.name}": model.cross_language_definition_id
186
- for model in self.code_model.model_types
185
+ for model in self.code_model.public_model_types
187
186
  }
188
187
  cross_langauge_def_dict.update(
189
188
  {
190
189
  f"{self.code_model.namespace}.models.{enum.name}": enum.cross_language_definition_id
191
190
  for enum in self.code_model.enums
191
+ if not enum.internal
192
192
  }
193
193
  )
194
194
  cross_langauge_def_dict.update(
@@ -194,6 +194,8 @@ class DpgModelSerializer(_ModelSerializer):
194
194
  )
195
195
 
196
196
  for model in self.code_model.model_types:
197
+ if model.base == "json":
198
+ continue
197
199
  file_import.merge(model.imports(is_operation_file=False))
198
200
  for prop in model.properties:
199
201
  file_import.merge(prop.imports())
@@ -1,4 +1,3 @@
1
- # pylint: disable=too-many-lines
2
1
  # -------------------------------------------------------------------------
3
2
  # Copyright (c) Microsoft Corporation. All rights reserved.
4
3
  # Licensed under the MIT License. See License.txt in the project root for
@@ -22,7 +21,6 @@ from ..models import (
22
21
  FileImport,
23
22
  )
24
23
  from .utils import get_namespace_config, get_namespace_from_package_name
25
- from ...utils import to_snake_case
26
24
 
27
25
  _LOGGER = logging.getLogger(__name__)
28
26
 
@@ -42,7 +40,7 @@ class SampleSerializer(BaseSerializer):
42
40
  self.operation = operation
43
41
  self.sample = sample
44
42
  self.file_name = file_name
45
- self.sample_params = {to_snake_case(k): v for k, v in sample.get("parameters", {}).items()}
43
+ self.sample_params = sample.get("parameters", {})
46
44
 
47
45
  def _imports(self) -> FileImportSerializer:
48
46
  imports = FileImport(self.code_model)
@@ -66,8 +64,8 @@ class SampleSerializer(BaseSerializer):
66
64
  "AzureKeyCredential",
67
65
  ImportType.SDKCORE,
68
66
  )
69
- for param in self.operation.parameters.positional:
70
- if not param.client_default_value and not param.optional and param.client_name in self.sample_params:
67
+ for param in self.operation.parameters.positional + self.operation.parameters.keyword_only:
68
+ if not param.client_default_value and not param.optional and param.wire_name in self.sample_params:
71
69
  imports.merge(param.type.imports_for_sample())
72
70
  return FileImportSerializer(imports, True)
73
71
 
@@ -80,15 +78,19 @@ class SampleSerializer(BaseSerializer):
80
78
  elif isinstance(credential_type, KeyCredentialType):
81
79
  special_param.update({"credential": 'AzureKeyCredential(key=os.getenv("AZURE_KEY"))'})
82
80
 
83
- params_positional = [
84
- p for p in self.code_model.clients[0].parameters.positional if not (p.optional or p.client_default_value)
81
+ params = [
82
+ p
83
+ for p in (
84
+ self.code_model.clients[0].parameters.positional + self.code_model.clients[0].parameters.keyword_only
85
+ )
86
+ if not (p.optional or p.client_default_value)
85
87
  ]
86
88
  client_params = {
87
89
  p.client_name: special_param.get(
88
90
  p.client_name,
89
- f'"{self.sample_params.get(p.client_name) or p.client_name.upper()}"',
91
+ f'"{self.sample_params.get(p.wire_name) or p.client_name.upper()}"',
90
92
  )
91
- for p in params_positional
93
+ for p in params
92
94
  }
93
95
 
94
96
  return client_params
@@ -103,15 +105,18 @@ class SampleSerializer(BaseSerializer):
103
105
 
104
106
  # prepare operation parameters
105
107
  def _operation_params(self) -> Dict[str, Any]:
106
- params_positional = [p for p in self.operation.parameters.positional if not p.client_default_value]
108
+ params = [
109
+ p
110
+ for p in (self.operation.parameters.positional + self.operation.parameters.keyword_only)
111
+ if not p.client_default_value
112
+ ]
107
113
  failure_info = "fail to find required param named {}"
108
114
  operation_params = {}
109
- for param in params_positional:
110
- name = param.client_name
111
- param_value = self.sample_params.get(name)
115
+ for param in params:
112
116
  if not param.optional:
117
+ param_value = self.sample_params.get(param.wire_name)
113
118
  if not param_value:
114
- raise Exception(failure_info.format(name)) # pylint: disable=broad-exception-raised
119
+ raise Exception(failure_info.format(param.client_name)) # pylint: disable=broad-exception-raised
115
120
  operation_params[param.client_name] = self.handle_param(param, param_value)
116
121
  return operation_params
117
122
 
@@ -145,7 +150,7 @@ class SampleSerializer(BaseSerializer):
145
150
  name = self.sample.get("x-ms-original-file", "")
146
151
  if "specification" in name:
147
152
  return "specification" + name.split("specification")[-1]
148
- return ""
153
+ return name if self.code_model.options["from_typespec"] else ""
149
154
 
150
155
  def serialize(self) -> str:
151
156
  operation_result, return_var = self._operation_result()
@@ -454,6 +454,10 @@ def _serialize(o, format: typing.Optional[str] = None): # pylint: disable=too-m
454
454
  return float(o)
455
455
  if isinstance(o, enum.Enum):
456
456
  return o.value
457
+ if isinstance(o, int):
458
+ if format == "str":
459
+ return str(o)
460
+ return o
457
461
  try:
458
462
  # First try datetime.datetime
459
463
  return _serialize_datetime(o, format)
@@ -489,6 +493,9 @@ def _create_value(rf: typing.Optional["_RestField"], value: typing.Any) -> typin
489
493
 
490
494
  class Model(_MyMutableMapping):
491
495
  _is_model = True
496
+ # label whether current class's _attr_to_rest_field has been calculated
497
+ # could not see _attr_to_rest_field directly because subclass inherits it from parent class
498
+ _calculated: typing.Set[str] = set()
492
499
 
493
500
  def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None:
494
501
  class_name = self.__class__.__name__
@@ -521,24 +528,27 @@ class Model(_MyMutableMapping):
521
528
  return Model(self.__dict__)
522
529
 
523
530
  def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> Self: # pylint: disable=unused-argument
524
- # we know the last three classes in mro are going to be 'Model', 'dict', and 'object'
525
- mros = cls.__mro__[:-3][::-1] # ignore model, dict, and object parents, and reverse the mro order
526
- attr_to_rest_field: typing.Dict[str, _RestField] = { # map attribute name to rest_field property
527
- k: v for mro_class in mros for k, v in mro_class.__dict__.items() if k[0] != "_" and hasattr(v, "_type")
528
- }
529
- annotations = {
530
- k: v
531
- for mro_class in mros
532
- if hasattr(mro_class, "__annotations__") # pylint: disable=no-member
533
- for k, v in mro_class.__annotations__.items() # pylint: disable=no-member
534
- }
535
- for attr, rf in attr_to_rest_field.items():
536
- rf._module = cls.__module__
537
- if not rf._type:
538
- rf._type = rf._get_deserialize_callable_from_annotation(annotations.get(attr, None))
539
- if not rf._rest_name_input:
540
- rf._rest_name_input = attr
541
- cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items())
531
+ if f"{cls.__module__}.{cls.__qualname__}" not in cls._calculated:
532
+ # we know the last nine classes in mro are going to be 'Model', '_MyMutableMapping', 'MutableMapping',
533
+ # 'Mapping', 'Collection', 'Sized', 'Iterable', 'Container' and 'object'
534
+ mros = cls.__mro__[:-9][::-1] # ignore parents, and reverse the mro order
535
+ attr_to_rest_field: typing.Dict[str, _RestField] = { # map attribute name to rest_field property
536
+ k: v for mro_class in mros for k, v in mro_class.__dict__.items() if k[0] != "_" and hasattr(v, "_type")
537
+ }
538
+ annotations = {
539
+ k: v
540
+ for mro_class in mros
541
+ if hasattr(mro_class, "__annotations__") # pylint: disable=no-member
542
+ for k, v in mro_class.__annotations__.items() # pylint: disable=no-member
543
+ }
544
+ for attr, rf in attr_to_rest_field.items():
545
+ rf._module = cls.__module__
546
+ if not rf._type:
547
+ rf._type = rf._get_deserialize_callable_from_annotation(annotations.get(attr, None))
548
+ if not rf._rest_name_input:
549
+ rf._rest_name_input = attr
550
+ cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items())
551
+ cls._calculated.add(f"{cls.__module__}.{cls.__qualname__}")
542
552
 
543
553
  return super().__new__(cls) # pylint: disable=no-value-for-parameter
544
554
 
@@ -669,6 +679,8 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=R0911, R0915,
669
679
  rf: typing.Optional["_RestField"] = None,
670
680
  ) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]:
671
681
  if not annotation or annotation in [int, float]:
682
+ if annotation is int and rf and rf._format == "str":
683
+ return int
672
684
  return None
673
685
 
674
686
  # is it a type alias?
@@ -70,8 +70,6 @@ FileType = Union[
70
70
  Tuple[Optional[str], FileContent, Optional[str]],
71
71
  ]
72
72
 
73
- FilesType = Union[Mapping[str, FileType], Sequence[Tuple[str, FileType]]]
74
-
75
73
  def serialize_multipart_data_entry(data_entry: Any) -> Any:
76
74
  if isinstance(data_entry, (list, tuple, dict, Model)):
77
75
  return json.dumps(data_entry, cls=SdkJSONEncoder, exclude_readonly=True)
@@ -27,7 +27,7 @@ class GeneratorRenderer(m2r2.RestRenderer):
27
27
  return f":code:`{html}`"
28
28
 
29
29
 
30
- class M2R(YamlUpdatePlugin): # pylint: disable=abstract-method
30
+ class M2R(YamlUpdatePlugin):
31
31
  """A plugin to convert any description and summary from MD to RST."""
32
32
 
33
33
  def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
@@ -3,7 +3,7 @@
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 Tuple, Any, Dict
6
+ from typing import Tuple, Any
7
7
  from pathlib import Path
8
8
  import os
9
9
  import shutil
@@ -28,7 +28,7 @@ def format_file(file: Path, file_content: str) -> str:
28
28
  return file_content
29
29
 
30
30
 
31
- class PostProcessPlugin(Plugin): # pylint: disable=abstract-method
31
+ class PostProcessPlugin(Plugin):
32
32
  def __init__(self, **kwargs: Any):
33
33
  super().__init__(**kwargs)
34
34
  output_folder_uri = self.options["outputFolderUri"]
@@ -52,9 +52,7 @@ def create(
52
52
  return builder.context
53
53
 
54
54
 
55
- def python_run( # pylint: disable=inconsistent-return-statements
56
- venv_context, module, command, directory=_ROOT_DIR
57
- ) -> Optional[str]:
55
+ def python_run(venv_context, module, command, directory=_ROOT_DIR) -> Optional[str]:
58
56
  try:
59
57
  cmd_line = [
60
58
  venv_context.env_exe,
@@ -163,7 +163,7 @@ def has_multi_part_content_type(yaml_data: Dict[str, Any]) -> bool:
163
163
  return any(ct for ct in yaml_data.get("contentTypes", []) if ct == "multipart/form-data")
164
164
 
165
165
 
166
- class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
166
+ class PreProcessPlugin(YamlUpdatePlugin):
167
167
  """Add Python naming information."""
168
168
 
169
169
  @property
@@ -82,9 +82,7 @@ def parse_args(
82
82
  return value
83
83
 
84
84
  unknown_args_ret = {
85
- ua.strip("--").split("=", maxsplit=1)[0]: _get_value( # pylint: disable=bad-str-strip-call
86
- ua.strip("--").split("=", maxsplit=1)[1] # pylint: disable=bad-str-strip-call
87
- )
85
+ ua.strip("--").split("=", maxsplit=1)[0]: _get_value(ua.strip("--").split("=", maxsplit=1)[1])
88
86
  for ua in unknown_args
89
87
  }
90
88
  return args, unknown_args_ret
@@ -15,7 +15,7 @@ from setuptools import setup, find_packages
15
15
 
16
16
  # Version extraction inspired from 'requests'
17
17
  with open(os.path.join("pygen", "_version.py"), "r") as fd:
18
- version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1)
18
+ version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) # type: ignore
19
19
 
20
20
  if not version:
21
21
  raise RuntimeError("Cannot find version information")