@autorest/python 6.2.11 → 6.2.15

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 (56) hide show
  1. package/autorest/__init__.py +7 -5
  2. package/autorest/_utils.py +7 -1
  3. package/autorest/black/__init__.py +6 -1
  4. package/autorest/codegen/__init__.py +1 -1
  5. package/autorest/codegen/models/__init__.py +8 -2
  6. package/autorest/codegen/models/base.py +4 -13
  7. package/autorest/codegen/models/client.py +9 -11
  8. package/autorest/codegen/models/code_model.py +3 -3
  9. package/autorest/codegen/models/combined_type.py +4 -3
  10. package/autorest/codegen/models/credential_types.py +7 -14
  11. package/autorest/codegen/models/dictionary_type.py +1 -1
  12. package/autorest/codegen/models/imports.py +3 -3
  13. package/autorest/codegen/models/lro_operation.py +5 -5
  14. package/autorest/codegen/models/model_type.py +89 -47
  15. package/autorest/codegen/models/operation.py +8 -8
  16. package/autorest/codegen/models/operation_group.py +3 -1
  17. package/autorest/codegen/models/paging_operation.py +2 -2
  18. package/autorest/codegen/models/parameter.py +27 -6
  19. package/autorest/codegen/models/parameter_list.py +1 -9
  20. package/autorest/codegen/models/primitive_types.py +1 -1
  21. package/autorest/codegen/models/property.py +15 -3
  22. package/autorest/codegen/models/response.py +2 -2
  23. package/autorest/codegen/serializers/__init__.py +2 -2
  24. package/autorest/codegen/serializers/builder_serializer.py +64 -28
  25. package/autorest/codegen/serializers/client_serializer.py +6 -4
  26. package/autorest/codegen/serializers/general_serializer.py +7 -2
  27. package/autorest/codegen/serializers/model_serializer.py +14 -4
  28. package/autorest/codegen/serializers/sample_serializer.py +2 -6
  29. package/autorest/codegen/templates/config.py.jinja2 +25 -6
  30. package/autorest/codegen/templates/enum.py.jinja2 +2 -2
  31. package/autorest/codegen/templates/metadata.json.jinja2 +18 -9
  32. package/autorest/codegen/templates/model_base.py.jinja2 +74 -63
  33. package/autorest/codegen/templates/model_container.py.jinja2 +2 -2
  34. package/autorest/codegen/templates/model_dpg.py.jinja2 +6 -4
  35. package/autorest/codegen/templates/model_msrest.py.jinja2 +2 -2
  36. package/autorest/codegen/templates/serialization.py.jinja2 +57 -29
  37. package/autorest/codegen/templates/vendor.py.jinja2 +3 -2
  38. package/autorest/jsonrpc/localapi.py +3 -3
  39. package/autorest/jsonrpc/server.py +3 -3
  40. package/autorest/m2r/__init__.py +1 -1
  41. package/autorest/m4reformatter/__init__.py +13 -2
  42. package/autorest/multiapi/models/__init__.py +2 -0
  43. package/autorest/multiapi/models/code_model.py +13 -0
  44. package/autorest/multiapi/models/global_parameter.py +1 -0
  45. package/autorest/multiapi/models/imports.py +3 -3
  46. package/autorest/multiapi/serializers/__init__.py +30 -3
  47. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +8 -12
  48. package/autorest/postprocess/get_all.py +3 -1
  49. package/autorest/postprocess/venvtools.py +5 -4
  50. package/autorest/preprocess/__init__.py +19 -7
  51. package/autorest/preprocess/python_mappings.py +1 -0
  52. package/index.js +0 -0
  53. package/package.json +2 -1
  54. package/requirements.txt +6 -6
  55. package/setup.py +0 -1
  56. package/venvtools.py +2 -3
@@ -25,7 +25,9 @@ class ReaderAndWriter:
25
25
  self._list_file: List[str] = []
26
26
  try:
27
27
  with open(
28
- Path(self.output_folder) / Path("..") / Path("python.json"), "r"
28
+ Path(self.output_folder) / Path("..") / Path("python.json"),
29
+ "r",
30
+ encoding="utf-8-sig",
29
31
  ) as fd:
30
32
  python_json = json.load(fd)
31
33
  except Exception: # pylint: disable=broad-except
@@ -41,7 +43,7 @@ class ReaderAndWriter:
41
43
  """Directly reading from disk"""
42
44
  # make path relative to output folder
43
45
  try:
44
- with open(self.output_folder / Path(path), "r") as fd:
46
+ with open(self.output_folder / Path(path), "r", encoding="utf-8-sig") as fd:
45
47
  return fd.read()
46
48
  except FileNotFoundError:
47
49
  return ""
@@ -51,7 +53,7 @@ class ReaderAndWriter:
51
53
  file_folder = Path(filename).parent
52
54
  if not Path.is_dir(self.output_folder / file_folder):
53
55
  Path.mkdir(self.output_folder / file_folder, parents=True)
54
- with open(self.output_folder / Path(filename), "w") as fd:
56
+ with open(self.output_folder / Path(filename), "w", encoding="utf-8") as fd:
55
57
  fd.write(file_content)
56
58
 
57
59
  def list_file(self) -> List[str]:
@@ -111,11 +113,11 @@ class YamlUpdatePlugin(Plugin):
111
113
 
112
114
  def get_yaml(self) -> Dict[str, Any]:
113
115
  # cadl file doesn't have to be relative to output folder
114
- with open(self.options["cadl_file"], "r") as fd:
116
+ with open(self.options["cadl_file"], "r", encoding="utf-8-sig") as fd:
115
117
  return yaml.safe_load(fd.read())
116
118
 
117
119
  def write_yaml(self, yaml_string: str) -> None:
118
- with open(self.options["cadl_file"], "w") as fd:
120
+ with open(self.options["cadl_file"], "w", encoding="utf-8-sig") as fd:
119
121
  fd.write(yaml_string)
120
122
 
121
123
  def process(self) -> bool:
@@ -77,7 +77,13 @@ def parse_args(
77
77
  return value
78
78
 
79
79
  unknown_args_ret = {
80
- ua.strip("--").split("=")[0]: _get_value(ua.strip("--").split("=")[1])
80
+ ua.strip("--").split("=", maxsplit=1)[ # pylint: disable=bad-str-strip-call
81
+ 0
82
+ ]: _get_value(
83
+ ua.strip("--").split("=", maxsplit=1)[ # pylint: disable=bad-str-strip-call
84
+ 1
85
+ ]
86
+ )
81
87
  for ua in unknown_args
82
88
  }
83
89
  return args, unknown_args_ret
@@ -31,7 +31,12 @@ class BlackScriptPlugin(Plugin): # pylint: disable=abstract-method
31
31
 
32
32
  def process(self) -> bool:
33
33
  # apply format_file on every file in the output folder
34
- list(map(self.format_file, [Path(f) for f in self.list_file()]))
34
+ list(
35
+ map(
36
+ self.format_file,
37
+ [Path(f) for f in self.list_file() if "__pycache__" not in f],
38
+ )
39
+ )
35
40
  return True
36
41
 
37
42
  def format_file(self, file: Path) -> None:
@@ -186,7 +186,7 @@ class CodeGenerator(Plugin):
186
186
 
187
187
  def get_yaml(self) -> Dict[str, Any]:
188
188
  # cadl file doesn't have to be relative to output folder
189
- with open(self.options["cadl_file"], "r") as fd:
189
+ with open(self.options["cadl_file"], "r", encoding="utf-8-sig") as fd:
190
190
  return yaml.safe_load(fd.read())
191
191
 
192
192
  def get_serializer(self, code_model: CodeModel):
@@ -9,7 +9,7 @@ from .base import BaseModel
9
9
  from .base_builder import BaseBuilder
10
10
  from .code_model import CodeModel
11
11
  from .client import Client
12
- from .model_type import ModelType
12
+ from .model_type import ModelType, JSONModelType, DPGModelType, MsrestModelType
13
13
  from .dictionary_type import DictionaryType
14
14
  from .list_type import ListType
15
15
  from .combined_type import CombinedType
@@ -156,7 +156,13 @@ def build_type(yaml_data: Dict[str, Any], code_model: CodeModel) -> BaseType:
156
156
  pass
157
157
  if yaml_data["type"] == "model":
158
158
  # need to special case model to avoid recursion
159
- response = ModelType(yaml_data, code_model)
159
+ if yaml_data["base"] == "json" or not code_model.options["models_mode"]:
160
+ model_type = JSONModelType
161
+ elif yaml_data["base"] == "dpg":
162
+ model_type = DPGModelType # type: ignore
163
+ else:
164
+ model_type = MsrestModelType # type: ignore
165
+ response = model_type(yaml_data, code_model)
160
166
  code_model.types_map[yaml_id] = response
161
167
  response.fill_instance_from_yaml(yaml_data, code_model)
162
168
  else:
@@ -52,9 +52,7 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
52
52
  ) -> "BaseType":
53
53
  return cls(yaml_data=yaml_data, code_model=code_model)
54
54
 
55
- def imports( # pylint: disable=no-self-use
56
- self, **kwargs # pylint: disable=unused-argument
57
- ) -> FileImport:
55
+ def imports(self, **kwargs) -> FileImport: # pylint: disable=unused-argument
58
56
  return FileImport()
59
57
 
60
58
  def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
@@ -91,7 +89,7 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
91
89
  if self.xml_metadata.get("namespace", False):
92
90
  attrs_list.append(f"'ns': '{self.xml_metadata['namespace']}'")
93
91
  if self.xml_metadata.get("text"):
94
- attrs_list.append(f"'text': True")
92
+ attrs_list.append("'text': True")
95
93
  return ", ".join(attrs_list)
96
94
 
97
95
  @property
@@ -106,7 +104,6 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
106
104
  If list: '[str]'
107
105
  If dict: '{str}'
108
106
  """
109
- ...
110
107
  raise NotImplementedError()
111
108
 
112
109
  @property
@@ -121,12 +118,10 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
121
118
  @abstractmethod
122
119
  def description(self, *, is_operation_file: bool) -> str:
123
120
  """The description"""
124
- ...
125
121
 
126
122
  @abstractmethod
127
123
  def docstring_text(self, **kwargs: Any) -> str:
128
124
  """The names used in rtype documentation"""
129
- ...
130
125
 
131
126
  @abstractmethod
132
127
  def docstring_type(self, **kwargs: Any) -> str:
@@ -134,7 +129,6 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
134
129
 
135
130
  Special case for enum, for instance: 'str or ~namespace.EnumName'
136
131
  """
137
- ...
138
132
 
139
133
  @abstractmethod
140
134
  def type_annotation(self, **kwargs: Any) -> str:
@@ -142,7 +136,6 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
142
136
 
143
137
  Special case for enum, for instance: Union[str, "EnumName"]
144
138
  """
145
- ...
146
139
 
147
140
  @property
148
141
  def validation(self) -> Optional[Dict[str, Any]]:
@@ -153,7 +146,7 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
153
146
  """
154
147
  return None
155
148
 
156
- def get_declaration(self, value: Any) -> str: # pylint: disable=no-self-use
149
+ def get_declaration(self, value: Any) -> str:
157
150
  """Return the current value from YAML as a Python string that represents the constant.
158
151
 
159
152
  Example, if schema is "bytearray" and value is "foo",
@@ -175,9 +168,8 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
175
168
  description: Optional[str] = None,
176
169
  ) -> Any:
177
170
  """Template of what this schema would look like as JSON input"""
178
- ...
179
171
 
180
- def get_polymorphic_subtypes( # pylint: disable=no-self-use
172
+ def get_polymorphic_subtypes(
181
173
  self, polymorphic_subtypes: List["ModelType"] # pylint: disable=unused-argument
182
174
  ) -> None:
183
175
  return None
@@ -186,7 +178,6 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
186
178
  @abstractmethod
187
179
  def instance_check_template(self) -> str:
188
180
  """Template of what an instance check of a variable for this type would look like"""
189
- ...
190
181
 
191
182
  @property
192
183
  def serialization_constraints(self) -> List[str]:
@@ -155,8 +155,10 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
155
155
  for rb in self.request_builders
156
156
  if id(rb.yaml_data) == request_builder_id
157
157
  )
158
- except StopIteration:
159
- raise KeyError(f"No request builder with id {request_builder_id} found.")
158
+ except StopIteration as exc:
159
+ raise KeyError(
160
+ f"No request builder with id {request_builder_id} found."
161
+ ) from exc
160
162
 
161
163
  def _imports_shared(self, async_mode: bool) -> FileImport:
162
164
  file_import = FileImport()
@@ -207,20 +209,16 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
207
209
  def has_lro_operations(self) -> bool:
208
210
  """Are there any LRO operations in this SDK?"""
209
211
  return any(
210
- [
211
- operation.operation_type in ("lro", "lropaging")
212
- for operation_group in self.operation_groups
213
- for operation in operation_group.operations
214
- ]
212
+ operation.operation_type in ("lro", "lropaging")
213
+ for operation_group in self.operation_groups
214
+ for operation in operation_group.operations
215
215
  )
216
216
 
217
217
  @property
218
218
  def has_operations(self) -> bool:
219
219
  return any(
220
- [
221
- bool(operation_group.operations)
222
- for operation_group in self.operation_groups
223
- ]
220
+ bool(operation_group.operations)
221
+ for operation_group in self.operation_groups
224
222
  )
225
223
 
226
224
  def format_lro_operations(self) -> None:
@@ -172,8 +172,8 @@ class CodeModel: # pylint: disable=too-many-public-methods
172
172
  """
173
173
  try:
174
174
  return next(type for id, type in self.types_map.items() if id == schema_id)
175
- except StopIteration:
176
- raise KeyError(f"Couldn't find schema with id {schema_id}")
175
+ except StopIteration as exc:
176
+ raise KeyError(f"Couldn't find schema with id {schema_id}") from exc
177
177
 
178
178
  @property
179
179
  def model_types(self) -> List[ModelType]:
@@ -190,7 +190,7 @@ class CodeModel: # pylint: disable=too-many-public-methods
190
190
 
191
191
  @property
192
192
  def public_model_types(self) -> List[ModelType]:
193
- return [m for m in self.model_types if m.is_public]
193
+ return [m for m in self.model_types if m.is_public and not m.base == "json"]
194
194
 
195
195
  @property
196
196
  def enums(self) -> List[EnumType]:
@@ -79,9 +79,10 @@ class CombinedType(BaseType):
79
79
  client_default_value_declaration: Optional[str] = None,
80
80
  description: Optional[str] = None,
81
81
  ) -> Any:
82
- """Template of what this schema would look like as JSON input"""
83
- raise ValueError(
84
- "You shouldn't get a JSON template representation of multiple types"
82
+ return self.types[0].get_json_template_representation(
83
+ optional=optional,
84
+ client_default_value_declaration=client_default_value_declaration,
85
+ description=description,
85
86
  )
86
87
 
87
88
  def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
@@ -38,7 +38,6 @@ class _CredentialPolicyBaseType:
38
38
  """
39
39
  How to call this credential policy. Used to initialize the credential policy in the config file.
40
40
  """
41
- ...
42
41
 
43
42
 
44
43
  class BearerTokenCredentialPolicyType(_CredentialPolicyBaseType):
@@ -158,17 +157,17 @@ class TokenCredentialType(
158
157
  ):
159
158
  """Type of a token credential. Used by BearerAuth and ARMChallenge policies"""
160
159
 
161
- def type_annotation(self, **kwargs: Any) -> str: # pylint: disable=no-self-use
160
+ def type_annotation(self, **kwargs: Any) -> str:
162
161
  if kwargs.get("async_mode"):
163
162
  return '"AsyncTokenCredential"'
164
163
  return '"TokenCredential"'
165
164
 
166
- def docstring_type(self, **kwargs: Any) -> str: # pylint: disable=no-self-use
165
+ def docstring_type(self, **kwargs: Any) -> str:
167
166
  if kwargs.get("async_mode"):
168
167
  return "~azure.core.credentials_async.AsyncTokenCredential"
169
168
  return "~azure.core.credentials.TokenCredential"
170
169
 
171
- def imports(self, **kwargs: Any) -> FileImport: # pylint: disable=no-self-use
170
+ def imports(self, **kwargs: Any) -> FileImport:
172
171
  file_import = FileImport()
173
172
  if kwargs.get("async_mode"):
174
173
  file_import.add_submodule_import(
@@ -188,7 +187,7 @@ class TokenCredentialType(
188
187
 
189
188
  @property
190
189
  def instance_check_template(self) -> str:
191
- return "hasattr({}, get_token)"
190
+ return "hasattr({}, 'get_token')"
192
191
 
193
192
 
194
193
  class AzureKeyCredentialType(
@@ -197,23 +196,17 @@ class AzureKeyCredentialType(
197
196
  ):
198
197
  """Type for an AzureKeyCredential"""
199
198
 
200
- def docstring_type( # pylint: disable=no-self-use
201
- self, **kwargs: Any # pylint: disable=unused-argument
202
- ) -> str:
199
+ def docstring_type(self, **kwargs: Any) -> str: # pylint: disable=unused-argument
203
200
  return "~azure.core.credentials.AzureKeyCredential"
204
201
 
205
- def type_annotation( # pylint: disable=no-self-use
206
- self, **kwargs: Any # pylint: disable=unused-argument
207
- ) -> str:
202
+ def type_annotation(self, **kwargs: Any) -> str: # pylint: disable=unused-argument
208
203
  return "AzureKeyCredential"
209
204
 
210
205
  @property
211
206
  def instance_check_template(self) -> str:
212
207
  return "isinstance({}, AzureKeyCredential)"
213
208
 
214
- def imports( # pylint: disable=no-self-use
215
- self, **kwargs: Any # pylint: disable=unused-argument
216
- ) -> FileImport:
209
+ def imports(self, **kwargs: Any) -> FileImport: # pylint: disable=unused-argument
217
210
  file_import = FileImport()
218
211
  file_import.add_submodule_import(
219
212
  "azure.core.credentials",
@@ -73,7 +73,7 @@ class DictionaryType(BaseType):
73
73
  description: Optional[str] = None,
74
74
  ) -> Any:
75
75
  return {
76
- f'"str"': self.element_type.get_json_template_representation(
76
+ '"str"': self.element_type.get_json_template_representation(
77
77
  optional=optional,
78
78
  client_default_value_declaration=client_default_value_declaration,
79
79
  description=description,
@@ -228,7 +228,7 @@ class FileImport:
228
228
  ],
229
229
  ],
230
230
  ],
231
- ] = dict()
231
+ ] = {}
232
232
  for i in self.imports:
233
233
  name_import: Optional[
234
234
  Union[
@@ -248,8 +248,8 @@ class FileImport:
248
248
  name_import = (i.submodule_name, i.alias)
249
249
  else:
250
250
  name_import = i.submodule_name
251
- retval.setdefault(i.typing_section, dict()).setdefault(
252
- i.import_type, dict()
251
+ retval.setdefault(i.typing_section, {}).setdefault(
252
+ i.import_type, {}
253
253
  ).setdefault(i.module_name, set()).add(name_import)
254
254
  return retval
255
255
 
@@ -73,11 +73,11 @@ class LROOperationBase(OperationBase[LROResponseType]):
73
73
  response = next(
74
74
  r for r in responses_with_bodies if 200 in r.status_codes
75
75
  )
76
- except StopIteration:
76
+ except StopIteration as exc:
77
77
  raise ValueError(
78
- f"Your swagger is invalid because you have multiple response schemas for LRO"
78
+ "Your swagger is invalid because you have multiple response schemas for LRO"
79
79
  + f" method {self.name} and none of them have a 200 status code."
80
- )
80
+ ) from exc
81
81
 
82
82
  elif num_response_schemas:
83
83
  response = responses_with_bodies[0]
@@ -134,8 +134,8 @@ class LROOperationBase(OperationBase[LROResponseType]):
134
134
  return file_import
135
135
  if async_mode:
136
136
  file_import.add_submodule_import(
137
- f"azure.core.tracing.decorator_async",
138
- f"distributed_trace_async",
137
+ "azure.core.tracing.decorator_async",
138
+ "distributed_trace_async",
139
139
  ImportType.AZURECORE,
140
140
  )
141
141
  file_import.add_submodule_import(
@@ -5,13 +5,20 @@
5
5
  # --------------------------------------------------------------------------
6
6
  from collections import OrderedDict
7
7
  from typing import Any, Dict, List, Optional, TYPE_CHECKING, cast
8
-
8
+ import sys
9
9
  from autorest.codegen.models.utils import add_to_pylint_disable
10
10
  from .base import BaseType
11
11
  from .constant_type import ConstantType
12
12
  from .property import Property
13
13
  from .imports import FileImport, ImportType, TypingSection
14
14
 
15
+
16
+ if sys.version_info >= (3, 8):
17
+ from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports
18
+ else:
19
+ from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports
20
+
21
+
15
22
  if TYPE_CHECKING:
16
23
  from .code_model import CodeModel
17
24
 
@@ -33,7 +40,7 @@ def _get_properties(type: "ModelType", properties: List[Property]) -> List[Prope
33
40
  return properties
34
41
 
35
42
 
36
- class ModelType(
43
+ class ModelType( # pylint: disable=abstract-method
37
44
  BaseType
38
45
  ): # pylint: disable=too-many-instance-attributes, too-many-public-methods
39
46
  """Represents a class ready to be serialized in Python.
@@ -44,6 +51,8 @@ class ModelType(
44
51
  :type properties: dict(str, str)
45
52
  """
46
53
 
54
+ base: Literal["msrest", "dpg", "json"]
55
+
47
56
  def __init__(
48
57
  self,
49
58
  yaml_data: Dict[str, Any],
@@ -72,15 +81,6 @@ class ModelType(
72
81
  def is_xml(self) -> bool:
73
82
  return self.yaml_data.get("isXml", False)
74
83
 
75
- @property
76
- def serialization_type(self) -> str:
77
- if self.code_model.options["models_mode"] == "msrest":
78
- private_model_path = f"_models.{self.code_model.models_filename}."
79
- return f"{'' if self.is_public else private_model_path}{self.name}"
80
- if self.code_model.options["models_mode"] == "dpg":
81
- return f"{'' if self.is_public else '_models.'}_models.{self.name}"
82
- return "object"
83
-
84
84
  @property
85
85
  def msrest_deserialization_key(self) -> str:
86
86
  return self.name
@@ -89,28 +89,9 @@ class ModelType(
89
89
  def is_polymorphic(self) -> bool:
90
90
  return any(p.is_polymorphic for p in self.properties)
91
91
 
92
- def type_annotation(self, **kwargs: Any) -> str:
93
- if self.code_model.options["models_mode"]:
94
- is_operation_file = kwargs.pop("is_operation_file", False)
95
- retval = f"_models.{self.name}"
96
- if not self.is_public:
97
- retval = f"{self.code_model.models_filename}.{retval}"
98
- return retval if is_operation_file else f'"{retval}"'
99
- return "ET.Element" if self.is_xml else "JSON"
100
-
101
- def docstring_type(self, **kwargs: Any) -> str:
102
- if self.code_model.options["models_mode"]:
103
- return f"~{self.code_model.namespace}.models.{self.name}"
104
- return "ET.Element" if self.is_xml else "JSON"
105
-
106
92
  def description(self, *, is_operation_file: bool = False) -> str:
107
93
  return "" if is_operation_file else self.yaml_data.get("description", self.name)
108
94
 
109
- def docstring_text(self, **kwargs: Any) -> str:
110
- if self.code_model.options["models_mode"]:
111
- return self.name
112
- return "XML Element" if self.is_xml else "JSON object"
113
-
114
95
  def get_declaration(self, value: Any) -> str:
115
96
  return f"{self.name}()"
116
97
 
@@ -252,15 +233,6 @@ class ModelType(
252
233
  except StopIteration:
253
234
  return None
254
235
 
255
- @property
256
- def instance_check_template(self) -> str:
257
- models_mode = self.code_model.options["models_mode"]
258
- if models_mode == "msrest":
259
- return "isinstance({}, msrest.Model)"
260
- if models_mode == "dpg":
261
- return "isinstance({}, _model_base.Model)"
262
- return "isinstance({}, MutableMapping)"
263
-
264
236
  @property
265
237
  def pylint_disable(self) -> str:
266
238
  retval: str = ""
@@ -275,16 +247,29 @@ class ModelType(
275
247
  retval = add_to_pylint_disable(retval, "too-many-locals")
276
248
  return retval
277
249
 
250
+
251
+ class JSONModelType(ModelType):
252
+ base = "json"
253
+
254
+ def type_annotation(self, **kwargs: Any) -> str:
255
+ return "ET.Element" if self.is_xml else "JSON"
256
+
257
+ @property
258
+ def serialization_type(self) -> str:
259
+ return "object"
260
+
261
+ def docstring_type(self, **kwargs: Any) -> str:
262
+ return "ET.Element" if self.is_xml else "JSON"
263
+
264
+ def docstring_text(self, **kwargs: Any) -> str:
265
+ return "XML Element" if self.is_xml else "JSON object"
266
+
267
+ @property
268
+ def instance_check_template(self) -> str:
269
+ return "isinstance({}, MutableMapping)"
270
+
278
271
  def imports(self, **kwargs: Any) -> FileImport:
279
272
  file_import = FileImport()
280
- relative_path = kwargs.pop("relative_path", None)
281
- if self.code_model.options["models_mode"] and relative_path:
282
- # add import for models in operations file
283
- file_import.add_submodule_import(
284
- relative_path, "models", ImportType.LOCAL, alias="_models"
285
- )
286
- if self.code_model.options["models_mode"] == "msrest":
287
- return file_import
288
273
  file_import.add_submodule_import(
289
274
  "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
290
275
  )
@@ -294,3 +279,60 @@ class ModelType(
294
279
  "xml.etree", "ElementTree", ImportType.STDLIB, alias="ET"
295
280
  )
296
281
  return file_import
282
+
283
+
284
+ class GeneratedModelType(ModelType): # pylint: disable=abstract-method
285
+ def type_annotation(self, **kwargs: Any) -> str:
286
+ is_operation_file = kwargs.pop("is_operation_file", False)
287
+ retval = f"_models.{self.name}"
288
+ if not self.is_public:
289
+ retval = f"{self.code_model.models_filename}.{retval}"
290
+ return retval if is_operation_file else f'"{retval}"'
291
+
292
+ def docstring_type(self, **kwargs: Any) -> str:
293
+ return f"~{self.code_model.namespace}.models.{self.name}"
294
+
295
+ def docstring_text(self, **kwargs: Any) -> str:
296
+ return self.name
297
+
298
+ def imports(self, **kwargs: Any) -> FileImport:
299
+ file_import = super().imports(**kwargs)
300
+ relative_path = kwargs.pop("relative_path", None)
301
+ if relative_path:
302
+ # add import for models in operations file
303
+ file_import.add_submodule_import(
304
+ relative_path, "models", ImportType.LOCAL, alias="_models"
305
+ )
306
+ return file_import
307
+
308
+
309
+ class MsrestModelType(GeneratedModelType):
310
+ base = "msrest"
311
+
312
+ @property
313
+ def serialization_type(self) -> str:
314
+ private_model_path = f"_models.{self.code_model.models_filename}."
315
+ return f"{'' if self.is_public else private_model_path}{self.name}"
316
+
317
+ @property
318
+ def instance_check_template(self) -> str:
319
+ return "isinstance({}, msrest.Model)"
320
+
321
+ def imports(self, **kwargs: Any) -> FileImport:
322
+ file_import = super().imports(**kwargs)
323
+ file_import.add_submodule_import(
324
+ "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
325
+ )
326
+ return file_import
327
+
328
+
329
+ class DPGModelType(GeneratedModelType):
330
+ base = "dpg"
331
+
332
+ @property
333
+ def serialization_type(self) -> str:
334
+ return f"{'' if self.is_public else '_models.'}_models.{self.name}"
335
+
336
+ @property
337
+ def instance_check_template(self) -> str:
338
+ return "isinstance({}, _model_base.Model)"
@@ -394,8 +394,8 @@ class OperationBase( # pylint: disable=too-many-public-methods
394
394
  )
395
395
  if self.code_model.options["tracing"] and self.want_tracing and not async_mode:
396
396
  file_import.add_submodule_import(
397
- f"azure.core.tracing.decorator",
398
- f"distributed_trace",
397
+ "azure.core.tracing.decorator",
398
+ "distributed_trace",
399
399
  ImportType.AZURECORE,
400
400
  )
401
401
  file_import.merge(
@@ -410,10 +410,10 @@ class OperationBase( # pylint: disable=too-many-public-methods
410
410
  ) -> ResponseType:
411
411
  try:
412
412
  return next(r for r in self.responses if status_code in r.status_codes)
413
- except StopIteration:
413
+ except StopIteration as exc:
414
414
  raise ValueError(
415
415
  f"Incorrect status code {status_code}, operation {self.name}"
416
- )
416
+ ) from exc
417
417
 
418
418
  @property
419
419
  def success_status_codes(self) -> List[Union[str, int]]:
@@ -431,7 +431,7 @@ class OperationBase( # pylint: disable=too-many-public-methods
431
431
  basename == "operations"
432
432
  or self.code_model.options["combine_operation_files"]
433
433
  ):
434
- return f"_operations"
434
+ return "_operations"
435
435
  return f"_{basename}_operations"
436
436
 
437
437
  @property
@@ -481,8 +481,8 @@ class Operation(OperationBase[Response]):
481
481
  return file_import
482
482
  if async_mode:
483
483
  file_import.add_submodule_import(
484
- f"azure.core.tracing.decorator_async",
485
- f"distributed_trace_async",
484
+ "azure.core.tracing.decorator_async",
485
+ "distributed_trace_async",
486
486
  ImportType.AZURECORE,
487
487
  )
488
488
  if (
@@ -499,7 +499,7 @@ class Operation(OperationBase[Response]):
499
499
  )
500
500
  file_import.add_import("json", ImportType.STDLIB)
501
501
  if self.default_error_deserialization or any(
502
- [r.type for r in self.responses]
502
+ r.type for r in self.responses
503
503
  ):
504
504
  file_import.add_submodule_import(
505
505
  f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL
@@ -76,7 +76,9 @@ class OperationGroup(BaseModel):
76
76
  def imports(self, async_mode: bool) -> FileImport:
77
77
  file_import = FileImport()
78
78
 
79
- relative_path = "..." if async_mode else ".."
79
+ relative_path = ("..." if async_mode else "..") + (
80
+ "." if self.client.is_subclient else ""
81
+ )
80
82
  for operation in self.operations:
81
83
  file_import.merge(
82
84
  operation.imports(async_mode, relative_path=relative_path)
@@ -74,10 +74,10 @@ class PagingOperationBase(OperationBase[PagingResponseType]):
74
74
  for p in cast(ModelType, response.type).properties
75
75
  if p.rest_api_name == rest_api_name
76
76
  )
77
- except StopIteration:
77
+ except StopIteration as exc:
78
78
  raise ValueError(
79
79
  f"Can't find a matching property in response for {rest_api_name}"
80
- )
80
+ ) from exc
81
81
 
82
82
  def get_pager(self, async_mode: bool) -> str:
83
83
  return self.responses[0].get_pager(async_mode)