@autorest/python 5.14.0 → 5.15.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 (58) hide show
  1. package/ChangeLog.md +29 -0
  2. package/autorest/codegen/__init__.py +87 -47
  3. package/autorest/codegen/models/base_schema.py +2 -6
  4. package/autorest/codegen/models/client.py +6 -0
  5. package/autorest/codegen/models/code_model.py +40 -74
  6. package/autorest/codegen/models/constant_schema.py +7 -3
  7. package/autorest/codegen/models/credential_model.py +47 -0
  8. package/autorest/codegen/models/credential_schema.py +5 -4
  9. package/autorest/codegen/models/dictionary_schema.py +7 -7
  10. package/autorest/codegen/models/enum_schema.py +8 -39
  11. package/autorest/codegen/models/imports.py +3 -1
  12. package/autorest/codegen/models/list_schema.py +18 -8
  13. package/autorest/codegen/models/lro_operation.py +3 -3
  14. package/autorest/codegen/models/lro_paging_operation.py +3 -3
  15. package/autorest/codegen/models/object_schema.py +17 -13
  16. package/autorest/codegen/models/operation.py +27 -6
  17. package/autorest/codegen/models/operation_group.py +7 -2
  18. package/autorest/codegen/models/paging_operation.py +3 -3
  19. package/autorest/codegen/models/parameter.py +39 -15
  20. package/autorest/codegen/models/parameter_list.py +1 -1
  21. package/autorest/codegen/models/primitive_schemas.py +15 -25
  22. package/autorest/codegen/models/property.py +5 -5
  23. package/autorest/codegen/models/request_builder.py +4 -4
  24. package/autorest/codegen/models/request_builder_parameter.py +12 -5
  25. package/autorest/codegen/models/schema_response.py +23 -10
  26. package/autorest/codegen/models/utils.py +20 -0
  27. package/autorest/codegen/serializers/__init__.py +49 -25
  28. package/autorest/codegen/serializers/builder_serializer.py +79 -37
  29. package/autorest/codegen/serializers/client_serializer.py +16 -6
  30. package/autorest/codegen/serializers/general_serializer.py +24 -3
  31. package/autorest/codegen/serializers/import_serializer.py +1 -1
  32. package/autorest/codegen/serializers/metadata_serializer.py +1 -1
  33. package/autorest/codegen/serializers/model_base_serializer.py +8 -0
  34. package/autorest/codegen/serializers/model_python3_serializer.py +2 -2
  35. package/autorest/codegen/serializers/operation_groups_serializer.py +1 -0
  36. package/autorest/codegen/serializers/patch_serializer.py +12 -3
  37. package/autorest/codegen/serializers/utils.py +29 -4
  38. package/autorest/codegen/templates/config.py.jinja2 +4 -4
  39. package/autorest/codegen/templates/enum.py.jinja2 +1 -1
  40. package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
  41. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  42. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  43. package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
  44. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +1 -1
  45. package/autorest/codegen/templates/metadata.json.jinja2 +3 -3
  46. package/autorest/codegen/templates/model.py.jinja2 +1 -6
  47. package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
  48. package/autorest/codegen/templates/operation.py.jinja2 +2 -3
  49. package/autorest/codegen/templates/operation_group.py.jinja2 +12 -5
  50. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +0 -1
  51. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  52. package/autorest/codegen/templates/paging_operation.py.jinja2 +1 -1
  53. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  54. package/autorest/codegen/templates/request_builder.py.jinja2 +4 -6
  55. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  56. package/autorest/multiapi/models/imports.py +21 -11
  57. package/autorest/multiapi/serializers/import_serializer.py +3 -1
  58. package/package.json +2 -2
@@ -59,13 +59,11 @@ class EnumSchema(BaseSchema):
59
59
  name: str,
60
60
  values: List["EnumValue"],
61
61
  enum_type: PrimitiveSchema,
62
- enum_file_name: str
63
62
  ) -> None:
64
63
  super(EnumSchema, self).__init__(namespace=namespace, yaml_data=yaml_data)
65
64
  self.description = description
66
65
  self.name = name
67
66
  self.values = values
68
- self.enum_file_name = enum_file_name
69
67
  self.enum_type = enum_type
70
68
 
71
69
  def __lt__(self, other):
@@ -80,23 +78,13 @@ class EnumSchema(BaseSchema):
80
78
  """
81
79
  return self.enum_type.serialization_type
82
80
 
83
- @property
84
- def type_annotation(self) -> str:
81
+ def type_annotation(self, *, is_operation_file: bool = False) -> str:
85
82
  """The python type used for type annotation
86
83
 
87
84
  :return: The type annotation for this schema
88
85
  :rtype: str
89
86
  """
90
- return f'Union[{self.enum_type.type_annotation}, "{self.name}"]'
91
-
92
- @property
93
- def operation_type_annotation(self) -> str:
94
- """The python type used for type annotation
95
-
96
- :return: The type annotation for this schema
97
- :rtype: str
98
- """
99
- return f'Union[{self.enum_type.type_annotation}, "_models.{self.name}"]'
87
+ return f'Union[{self.enum_type.type_annotation(is_operation_file=is_operation_file)}, "_models.{self.name}"]'
100
88
 
101
89
  def get_declaration(self, value: Any) -> str:
102
90
  return self.enum_type.get_declaration(value)
@@ -109,7 +97,7 @@ class EnumSchema(BaseSchema):
109
97
  def docstring_type(self) -> str:
110
98
  """The python type used for RST syntax input and type annotation.
111
99
  """
112
- return f"{self.enum_type.type_annotation} or ~{self.namespace}.models.{self.name}"
100
+ return f"{self.enum_type.type_annotation()} or ~{self.namespace}.models.{self.name}"
113
101
 
114
102
  @staticmethod
115
103
  def _get_enum_values(yaml_data: List[Dict[str, Any]]) -> List["EnumValue"]:
@@ -164,8 +152,6 @@ class EnumSchema(BaseSchema):
164
152
  else:
165
153
  enum_type = StringSchema(namespace, {"type": "str"})
166
154
  values = EnumSchema._get_enum_values(yaml_data["choices"])
167
- code_model = kwargs.pop("code_model")
168
-
169
155
  return cls(
170
156
  namespace=namespace,
171
157
  yaml_data=yaml_data,
@@ -173,7 +159,6 @@ class EnumSchema(BaseSchema):
173
159
  name=name,
174
160
  values=values,
175
161
  enum_type=enum_type,
176
- enum_file_name=f"_{code_model.module_name}_enums"
177
162
  )
178
163
 
179
164
  def imports(self) -> FileImport:
@@ -182,12 +167,6 @@ class EnumSchema(BaseSchema):
182
167
  file_import.merge(self.enum_type.imports())
183
168
  return file_import
184
169
 
185
- def model_file_imports(self) -> FileImport:
186
- imports = self.imports()
187
- # we import every enum since we can get extremely long imports
188
- # if we import my name
189
- imports.add_submodule_import("." + self.enum_file_name, "*", ImportType.LOCAL)
190
- return imports
191
170
 
192
171
  class HiddenModelEnumSchema(EnumSchema):
193
172
 
@@ -196,27 +175,17 @@ class HiddenModelEnumSchema(EnumSchema):
196
175
  file_import.merge(self.enum_type.imports())
197
176
  return file_import
198
177
 
199
- @property
200
- def type_annotation(self) -> str:
201
- """The python type used for type annotation
202
-
203
- :return: The type annotation for this schema
204
- :rtype: str
205
- """
206
- return self.enum_type.type_annotation
207
-
208
- @property
209
- def operation_type_annotation(self) -> str:
178
+ def type_annotation(self, *, is_operation_file: bool = False) -> str:
210
179
  """The python type used for type annotation
211
180
 
212
181
  :return: The type annotation for this schema
213
182
  :rtype: str
214
183
  """
215
- return self.enum_type.type_annotation
184
+ return self.enum_type.type_annotation(is_operation_file=is_operation_file)
216
185
 
217
186
  @property
218
187
  def docstring_text(self) -> str:
219
- return f"{self.enum_type.type_annotation}. {self.extra_description_information}"
188
+ return f"{self.enum_type.type_annotation()}. {self.extra_description_information}"
220
189
 
221
190
  @property
222
191
  def extra_description_information(self):
@@ -232,13 +201,13 @@ class HiddenModelEnumSchema(EnumSchema):
232
201
  possible_values[: len(possible_values) - 1]
233
202
  ) + f", and {possible_values[-1]}"
234
203
 
235
- return "Possible values are: {}.".format(possible_values_str)
204
+ return "Known values are: {}.".format(possible_values_str)
236
205
 
237
206
  @property
238
207
  def docstring_type(self) -> str:
239
208
  """The python type used for RST syntax input and type annotation.
240
209
  """
241
- return self.enum_type.type_annotation
210
+ return self.enum_type.type_annotation()
242
211
 
243
212
  def get_enum_schema(code_model) -> Type[EnumSchema]:
244
213
  if code_model.options["models_mode"]:
@@ -97,13 +97,15 @@ class FileImport:
97
97
  self,
98
98
  module_name: str,
99
99
  import_type: ImportType,
100
- typing_section: TypingSection = TypingSection.REGULAR
100
+ typing_section: TypingSection = TypingSection.REGULAR,
101
+ alias: Optional[str] = None,
101
102
  ) -> None:
102
103
  # Implementation detail: a regular import is just a "from" with no from
103
104
  self._append_import(ImportModel(
104
105
  typing_section=typing_section,
105
106
  import_type=import_type,
106
107
  module_name=module_name,
108
+ alias=alias,
107
109
  ))
108
110
 
109
111
  def define_mypy_type(self, type_name: str, type_value: str, async_type_value: Optional[str] = None):
@@ -29,20 +29,24 @@ class ListSchema(BaseSchema):
29
29
  def serialization_type(self) -> str:
30
30
  return f"[{self.element_type.serialization_type}]"
31
31
 
32
- @property
33
- def type_annotation(self) -> str:
34
- return f"List[{self.element_type.type_annotation}]"
35
-
36
- @property
37
- def operation_type_annotation(self) -> str:
38
- return f"List[{self.element_type.operation_type_annotation}]"
32
+ def type_annotation(self, *, is_operation_file: bool = False) -> str:
33
+ if self.element_type.type_annotation() == "ET.Element":
34
+ # this means we're version tolerant XML, we just return the XML element
35
+ return self.element_type.type_annotation(is_operation_file=is_operation_file)
36
+ return f"List[{self.element_type.type_annotation(is_operation_file=is_operation_file)}]"
39
37
 
40
38
  @property
41
39
  def docstring_type(self) -> str:
40
+ if self.element_type.docstring_type == "ET.Element":
41
+ # this means we're version tolerant XML, we just return the XML element
42
+ return self.element_type.docstring_type
42
43
  return f"list[{self.element_type.docstring_type}]"
43
44
 
44
45
  @property
45
46
  def docstring_text(self) -> str:
47
+ if self.element_type.docstring_text == "XML Element":
48
+ # this means we're version tolerant XML, we just return the XML element
49
+ return self.element_type.docstring_text
46
50
  return f"list of {self.element_type.docstring_text}"
47
51
 
48
52
  @property
@@ -108,6 +112,12 @@ class ListSchema(BaseSchema):
108
112
 
109
113
  def imports(self) -> FileImport:
110
114
  file_import = FileImport()
111
- file_import.add_submodule_import("typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL)
115
+ if not self.element_type.type_annotation(is_operation_file=True) == "ET.Element":
116
+ file_import.add_submodule_import("typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL)
112
117
  file_import.merge(self.element_type.imports())
113
118
  return file_import
119
+
120
+ def model_file_imports(self) -> FileImport:
121
+ file_import = self.imports()
122
+ file_import.merge(self.element_type.model_file_imports())
123
+ return file_import
@@ -143,8 +143,8 @@ class LROOperation(Operation):
143
143
  file_import.add_submodule_import(poller_import_path, poller, ImportType.AZURECORE, TypingSection.CONDITIONAL)
144
144
  return file_import
145
145
 
146
- def imports(self, async_mode: bool) -> FileImport:
147
- file_import = super().imports(async_mode)
146
+ def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
147
+ file_import = self._imports_base(async_mode, is_python3_file)
148
148
  file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
149
149
 
150
150
  poller_import_path = ".".join(self.get_poller_path(async_mode).split(".")[:-1])
@@ -172,7 +172,7 @@ class LROOperation(Operation):
172
172
  )
173
173
  base_polling_method = self.get_base_polling_method(async_mode)
174
174
  file_import.add_submodule_import(base_polling_method_import_path, base_polling_method, ImportType.AZURECORE)
175
-
175
+ file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
176
176
  if async_mode:
177
177
  file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
178
178
  if self.code_model.options["tracing"] and self.want_tracing:
@@ -9,9 +9,9 @@ from .paging_operation import PagingOperation
9
9
 
10
10
  class LROPagingOperation(PagingOperation, LROOperation):
11
11
 
12
- def imports(self, async_mode: bool) -> FileImport:
13
- lro_imports = LROOperation.imports(self, async_mode)
14
- paging_imports = PagingOperation.imports(self, async_mode)
12
+ def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
13
+ lro_imports = LROOperation.imports(self, async_mode, is_python3_file)
14
+ paging_imports = PagingOperation.imports(self, async_mode, is_python3_file)
15
15
 
16
16
  file_import = lro_imports
17
17
  file_import.merge(paging_imports)
@@ -39,13 +39,9 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
39
39
  def serialization_type(self) -> str:
40
40
  return self.name
41
41
 
42
- @property
43
- def type_annotation(self) -> str:
44
- return f'"{self.name}"'
45
-
46
- @property
47
- def operation_type_annotation(self) -> str:
48
- return f'"_models.{self.name}"'
42
+ def type_annotation(self, *, is_operation_file: bool = False) -> str:
43
+ retval = f"_models.{self.name}"
44
+ return retval if is_operation_file else f'"{retval}"'
49
45
 
50
46
  @property
51
47
  def docstring_type(self) -> str:
@@ -216,31 +212,39 @@ class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
216
212
  file_import.add_submodule_import("azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE)
217
213
  return file_import
218
214
 
215
+ def model_file_imports(self) -> FileImport:
216
+ file_import = self.imports()
217
+ file_import.add_import("__init__", ImportType.LOCAL, typing_section=TypingSection.TYPING, alias="_models")
218
+ return file_import
219
+
219
220
  class HiddenModelObjectSchema(ObjectSchema):
220
221
 
221
222
  @property
222
223
  def serialization_type(self) -> str:
223
224
  return "object"
224
225
 
225
- @property
226
- def type_annotation(self) -> str:
227
- return "JSONType"
228
-
229
- @property
230
- def operation_type_annotation(self) -> str:
226
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
227
+ if self.xml_metadata:
228
+ return "ET.Element"
231
229
  return "JSONType"
232
230
 
233
231
  @property
234
232
  def docstring_type(self) -> str:
233
+ if self.xml_metadata:
234
+ return "ET.Element"
235
235
  return "JSONType"
236
236
 
237
237
  @property
238
238
  def docstring_text(self) -> str:
239
+ if self.xml_metadata:
240
+ return "XML Element"
239
241
  return "JSON object"
240
242
 
241
243
  def imports(self) -> FileImport:
242
244
  file_import = FileImport()
243
245
  file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
246
+ if self.xml_metadata:
247
+ file_import.add_submodule_import("xml.etree", "ElementTree", ImportType.STDLIB, alias="ET")
244
248
  return file_import
245
249
 
246
250
  def get_object_schema(code_model) -> Type[ObjectSchema]:
@@ -10,7 +10,7 @@ from typing import cast, Dict, List, Any, Optional, Union, Set
10
10
  from .base_builder import BaseBuilder, create_parameters
11
11
  from .imports import FileImport, ImportType, TypingSection
12
12
  from .schema_response import SchemaResponse
13
- from .parameter import Parameter, get_parameter
13
+ from .parameter import Parameter, get_parameter, ParameterLocation
14
14
  from .parameter_list import ParameterList, get_parameter_list
15
15
  from .base_schema import BaseSchema
16
16
  from .object_schema import ObjectSchema
@@ -159,7 +159,7 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
159
159
  if response.has_body:
160
160
  file_import.merge(cast(BaseSchema, response.schema).imports())
161
161
 
162
- response_types = [r.operation_type_annotation for r in self.responses if r.has_body]
162
+ response_types = [r.type_annotation(is_operation_file=True) for r in self.responses if r.has_body]
163
163
  if len(set(response_types)) > 1:
164
164
  file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
165
165
 
@@ -171,7 +171,17 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
171
171
  def imports_for_multiapi(self, async_mode: bool) -> FileImport: # pylint: disable=unused-argument
172
172
  return self._imports_shared(async_mode)
173
173
 
174
- def imports(self, async_mode: bool) -> FileImport:
174
+ def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
175
+ file_import = self._imports_base(async_mode, is_python3_file)
176
+ if self.has_response_body and not self.has_optional_return_type and not self.code_model.options["models_mode"]:
177
+ file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
178
+ return file_import
179
+
180
+ @staticmethod
181
+ def has_kwargs_to_pop_with_default(kwargs_to_pop: List[Parameter], location: ParameterLocation) -> bool:
182
+ return any(kwarg.has_default_value and kwarg.location == location for kwarg in kwargs_to_pop)
183
+
184
+ def _imports_base(self, async_mode: bool, is_python3_file: bool) -> FileImport:
175
185
  file_import = self._imports_shared(async_mode)
176
186
 
177
187
  # Exceptions
@@ -186,6 +196,10 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
186
196
  file_import.add_submodule_import("typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL)
187
197
  file_import.add_submodule_import("azure.core.pipeline", "PipelineResponse", ImportType.AZURECORE)
188
198
  file_import.add_submodule_import("azure.core.rest", "HttpRequest", ImportType.AZURECORE)
199
+ kwargs_to_pop = self.parameters.kwargs_to_pop(is_python3_file)
200
+ if (self.has_kwargs_to_pop_with_default(kwargs_to_pop, ParameterLocation.Header) or
201
+ self.has_kwargs_to_pop_with_default(kwargs_to_pop, ParameterLocation.Query)):
202
+ file_import.add_submodule_import("azure.core.utils", "case_insensitive_dict", ImportType.AZURECORE)
189
203
  if async_mode:
190
204
  file_import.add_submodule_import("azure.core.pipeline.transport", "AsyncHttpResponse", ImportType.AZURECORE)
191
205
  else:
@@ -218,6 +232,7 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
218
232
  file_import.add_submodule_import(
219
233
  f"{relative_path}_vendor", "_convert_request", ImportType.LOCAL
220
234
  )
235
+
221
236
  if self.code_model.options["version_tolerant"] and (
222
237
  self.parameters.has_body or
223
238
  any(r for r in self.responses if r.has_body)
@@ -267,7 +282,7 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
267
282
 
268
283
  def convert_multiple_content_type_parameters(self) -> None:
269
284
  type_annot = ", ".join([
270
- param.schema.operation_type_annotation
285
+ param.schema.type_annotation(is_operation_file=True)
271
286
  for param in self.multiple_content_type_parameters
272
287
  ])
273
288
  docstring_type = " or ".join([
@@ -323,7 +338,13 @@ class Operation(BaseBuilder): # pylint: disable=too-many-public-methods, too-ma
323
338
  multiple_content_type_parameters=multiple_content_type_parameter_list,
324
339
  schema_requests=schema_requests,
325
340
  summary=yaml_data["language"]["python"].get("summary"),
326
- responses=[SchemaResponse.from_yaml(yaml) for yaml in yaml_data.get("responses", [])],
341
+ responses=[
342
+ SchemaResponse.from_yaml(yaml, code_model=code_model)
343
+ for yaml in yaml_data.get("responses", [])
344
+ ],
327
345
  # Exception with no schema means default exception, we don't store them
328
- exceptions=[SchemaResponse.from_yaml(yaml) for yaml in yaml_data.get("exceptions", []) if "schema" in yaml],
346
+ exceptions=[
347
+ SchemaResponse.from_yaml(yaml, code_model=code_model)
348
+ for yaml in yaml_data.get("exceptions", []) if "schema" in yaml
349
+ ],
329
350
  )
@@ -54,15 +54,16 @@ class OperationGroup(BaseModel):
54
54
  file_import = FileImport()
55
55
  for operation in self.operations:
56
56
  file_import.merge(operation.imports_for_multiapi(async_mode))
57
+ file_import.add_submodule_import(".." if async_mode else ".", "models", ImportType.LOCAL, alias="_models")
57
58
  return file_import
58
59
 
59
- def imports(self, async_mode: bool) -> FileImport:
60
+ def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
60
61
  file_import = FileImport()
61
62
  file_import.add_submodule_import("azure.core.exceptions", "ClientAuthenticationError", ImportType.AZURECORE)
62
63
  file_import.add_submodule_import("azure.core.exceptions", "ResourceNotFoundError", ImportType.AZURECORE)
63
64
  file_import.add_submodule_import("azure.core.exceptions", "ResourceExistsError", ImportType.AZURECORE)
64
65
  for operation in self.operations:
65
- file_import.merge(operation.imports(async_mode))
66
+ file_import.merge(operation.imports(async_mode, is_python3_file))
66
67
  local_path = "..." if async_mode else ".."
67
68
  if self.code_model.has_schemas and self.code_model.options["models_mode"]:
68
69
  file_import.add_submodule_import(local_path, "models", ImportType.LOCAL, alias="_models")
@@ -84,6 +85,10 @@ class OperationGroup(BaseModel):
84
85
  request_builder.name,
85
86
  import_type=ImportType.LOCAL
86
87
  )
88
+ if self.code_model.need_mixin_abc:
89
+ file_import.add_submodule_import(
90
+ ".._vendor", "MixinABC", ImportType.LOCAL
91
+ )
87
92
  type_value = "Optional[Callable[[PipelineResponse[HttpRequest, {}HttpResponse], T, Dict[str, Any]], Any]]"
88
93
  file_import.define_mypy_type(
89
94
  "ClsType",
@@ -66,7 +66,7 @@ class PagingOperation(Operation):
66
66
  return response
67
67
 
68
68
  def _find_python_name(self, rest_api_name: str, log_name: str) -> str:
69
- response = self._get_response()
69
+ response = self.responses[0]
70
70
  response_schema = cast(ObjectSchema, response.schema)
71
71
  if response_schema:
72
72
  for prop in response_schema.properties:
@@ -145,8 +145,8 @@ class PagingOperation(Operation):
145
145
 
146
146
  return file_import
147
147
 
148
- def imports(self, async_mode: bool) -> FileImport:
149
- file_import = super(PagingOperation, self).imports(async_mode)
148
+ def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
149
+ file_import = self._imports_base(async_mode, is_python3_file)
150
150
  # operation adds an import for distributed_trace_async, we don't want it
151
151
  file_import.imports = [i for i in file_import.imports if not i.submodule_name == "distributed_trace_async"]
152
152
 
@@ -6,7 +6,7 @@
6
6
  import logging
7
7
  from enum import Enum
8
8
 
9
- from typing import Dict, Optional, List, Any, Union, Tuple, cast
9
+ from typing import Dict, Optional, List, Any, Union, Tuple, cast, TYPE_CHECKING
10
10
 
11
11
  from .imports import FileImport, ImportType, TypingSection
12
12
  from .base_model import BaseModel
@@ -15,6 +15,10 @@ from .constant_schema import ConstantSchema
15
15
  from .object_schema import ObjectSchema
16
16
  from .property import Property
17
17
  from .primitive_schemas import IOSchema
18
+ from .utils import get_schema
19
+
20
+ if TYPE_CHECKING:
21
+ from .code_model import CodeModel
18
22
 
19
23
 
20
24
  _LOGGER = logging.getLogger(__name__)
@@ -46,6 +50,15 @@ class ParameterStyle(Enum):
46
50
  multipart = "multipart"
47
51
 
48
52
 
53
+
54
+ def get_target_property_name(code_model: "CodeModel", target_property_id: int) -> str:
55
+ for obj in code_model.schemas.values():
56
+ for prop in obj.properties:
57
+ if prop.id == target_property_id:
58
+ return prop.name
59
+ raise KeyError("Didn't find the target property")
60
+
61
+
49
62
  class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too-many-public-methods
50
63
  def __init__(
51
64
  self,
@@ -99,7 +112,7 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
99
112
  self.body_kwargs: List[Parameter] = []
100
113
  self.is_body_kwarg = False
101
114
  self.need_import = True
102
- self.is_kwarg = (self.rest_api_name == "Content-Type" or (self.constant and self.rest_api_name != "Accept"))
115
+ self.is_kwarg = (self.rest_api_name == "Content-Type" or (self.constant and self.inputtable_by_user))
103
116
 
104
117
  def __hash__(self) -> int:
105
118
  return hash(self.serialized_name)
@@ -115,7 +128,7 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
115
128
  if isinstance(self.schema, ConstantSchema) and not self.constant:
116
129
  if description:
117
130
  description += " "
118
- description += f"Possible values are {self.schema.get_declaration(self.schema.value)} or {None}."
131
+ description += f"Known values are {self.schema.get_declaration(self.schema.value)} or {None}."
119
132
  if self.has_default_value and not any(
120
133
  l for l in ["default value is", "default is"] if l in description.lower()
121
134
  ):
@@ -175,6 +188,10 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
175
188
  def is_body(self) -> bool:
176
189
  return self.location == ParameterLocation.Body
177
190
 
191
+ @property
192
+ def inputtable_by_user(self) -> bool:
193
+ return self.rest_api_name != "Accept"
194
+
178
195
  @property
179
196
  def pre_semicolon_content_types(self) -> List[str]:
180
197
  """Splits on semicolon of media types and returns the first half.
@@ -185,8 +202,8 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
185
202
  @property
186
203
  def in_method_signature(self) -> bool:
187
204
  return not(
188
- # don't put accept in signature
189
- self.rest_api_name == "Accept"
205
+ # if not inputtable, don't put in signature
206
+ not self.inputtable_by_user
190
207
  # If i'm not in the method code, no point in being in signature
191
208
  or not self.in_method_code
192
209
  # If I'm grouped, my grouper will be on signature, not me
@@ -225,7 +242,7 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
225
242
  ) and isinstance(self.schema, IOSchema)
226
243
 
227
244
  def _default_value(self) -> Tuple[Optional[Any], str, str]:
228
- type_annot = self.multiple_content_types_type_annot or self.schema.operation_type_annotation
245
+ type_annot = self.multiple_content_types_type_annot or self.schema.type_annotation(is_operation_file=True)
229
246
  if self._is_io_json:
230
247
  type_annot = f"Union[{type_annot}, JSONType]"
231
248
  any_types = ["Any", "JSONType"]
@@ -277,8 +294,7 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
277
294
  def default_value_declaration(self) -> Optional[Any]:
278
295
  return self._default_value()[1]
279
296
 
280
- @property
281
- def type_annotation(self) -> str:
297
+ def type_annotation(self, *, is_operation_file: bool = False) -> str: # pylint: disable=unused-argument
282
298
  return self._default_value()[2]
283
299
 
284
300
  @property
@@ -297,13 +313,14 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
297
313
  return self.default_value is not None or not self.required
298
314
 
299
315
  def method_signature(self, is_python3_file: bool) -> str:
316
+ type_annot = self.type_annotation(is_operation_file=True)
300
317
  if is_python3_file:
301
318
  if self.has_default_value:
302
- return f"{self.serialized_name}: {self.type_annotation} = {self.default_value_declaration},"
303
- return f"{self.serialized_name}: {self.type_annotation},"
319
+ return f"{self.serialized_name}: {type_annot} = {self.default_value_declaration},"
320
+ return f"{self.serialized_name}: {type_annot},"
304
321
  if self.has_default_value:
305
- return f"{self.serialized_name}={self.default_value_declaration}, # type: {self.type_annotation}"
306
- return f"{self.serialized_name}, # type: {self.type_annotation}"
322
+ return f"{self.serialized_name}={self.default_value_declaration}, # type: {type_annot}"
323
+ return f"{self.serialized_name}, # type: {type_annot}"
307
324
 
308
325
  @property
309
326
  def full_serialized_name(self) -> str:
@@ -345,22 +362,29 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
345
362
  content_types: Optional[List[str]] = None
346
363
  ) -> "Parameter":
347
364
  http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
365
+ serialized_name = yaml_data["language"]["python"]["name"]
366
+ schema = get_schema(
367
+ code_model, yaml_data.get("schema"), serialized_name
368
+ )
369
+ target_property = yaml_data.get("targetProperty")
370
+ target_property_name = get_target_property_name(code_model, id(target_property)) if target_property else None
371
+
348
372
  return cls(
349
373
  code_model=code_model,
350
374
  yaml_data=yaml_data,
351
- schema=yaml_data.get("schema", None), # FIXME replace by operation model
375
+ schema=schema, # FIXME replace by operation model
352
376
  # See also https://github.com/Azure/autorest.modelerfour/issues/80
353
377
  rest_api_name=yaml_data["language"]["default"].get(
354
378
  "serializedName", yaml_data["language"]["default"]["name"]
355
379
  ),
356
- serialized_name=yaml_data["language"]["python"]["name"],
380
+ serialized_name=serialized_name,
357
381
  description=yaml_data["language"]["python"]["description"],
358
382
  implementation=yaml_data["implementation"],
359
383
  required=yaml_data.get("required", False),
360
384
  location=ParameterLocation(http_protocol["in"]),
361
385
  skip_url_encoding=yaml_data.get("extensions", {}).get("x-ms-skip-url-encoding", False),
362
386
  constraints=[], # FIXME constraints
363
- target_property_name=id(yaml_data["targetProperty"]) if yaml_data.get("targetProperty") else None,
387
+ target_property_name=target_property_name,
364
388
  style=ParameterStyle(http_protocol["style"]) if "style" in http_protocol else None,
365
389
  explode=http_protocol.get("explode", False),
366
390
  grouped_by=yaml_data.get("groupedBy", None),
@@ -405,7 +405,7 @@ class GlobalParameterList(ParameterList):
405
405
  credential_parameter = Parameter(
406
406
  self.code_model,
407
407
  yaml_data={},
408
- schema=self.code_model.credential_schema_policy.credential,
408
+ schema=self.code_model.credential_model.credential_schema_policy.credential,
409
409
  serialized_name="credential",
410
410
  rest_api_name="credential",
411
411
  implementation="Client",