@autorest/python 6.1.5 → 6.1.7

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 (29) hide show
  1. package/autorest/__init__.py +10 -3
  2. package/autorest/black/__init__.py +2 -8
  3. package/autorest/codegen/__init__.py +4 -2
  4. package/autorest/codegen/models/__init__.py +1 -1
  5. package/autorest/codegen/models/base_builder.py +4 -1
  6. package/autorest/codegen/models/client.py +5 -3
  7. package/autorest/codegen/models/combined_type.py +6 -4
  8. package/autorest/codegen/models/enum_type.py +6 -4
  9. package/autorest/codegen/models/model_type.py +30 -9
  10. package/autorest/codegen/models/operation.py +32 -0
  11. package/autorest/codegen/models/operation_group.py +11 -7
  12. package/autorest/codegen/models/parameter.py +44 -0
  13. package/autorest/codegen/models/property.py +8 -15
  14. package/autorest/codegen/models/request_builder_parameter.py +4 -2
  15. package/autorest/codegen/serializers/__init__.py +18 -2
  16. package/autorest/codegen/serializers/builder_serializer.py +64 -22
  17. package/autorest/codegen/serializers/client_serializer.py +3 -4
  18. package/autorest/codegen/serializers/general_serializer.py +8 -0
  19. package/autorest/codegen/serializers/model_serializer.py +159 -61
  20. package/autorest/codegen/templates/model_base.py.jinja2 +636 -0
  21. package/autorest/codegen/templates/model_container.py.jinja2 +6 -2
  22. package/autorest/codegen/templates/model_dpg.py.jinja2 +62 -0
  23. package/autorest/codegen/templates/model_init.py.jinja2 +0 -5
  24. package/autorest/codegen/templates/{model.py.jinja2 → model_msrest.py.jinja2} +1 -1
  25. package/autorest/codegen/templates/operation_group.py.jinja2 +1 -1
  26. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  27. package/autorest/codegen/templates/validation.py.jinja2 +38 -0
  28. package/package.json +9 -10
  29. package/ChangeLog.md +0 -1284
@@ -7,7 +7,7 @@ import logging
7
7
  from pathlib import Path
8
8
  import json
9
9
  from abc import ABC, abstractmethod
10
- from typing import Any, Dict, Union
10
+ from typing import Any, Dict, Union, List
11
11
 
12
12
  import yaml
13
13
 
@@ -22,6 +22,7 @@ _LOGGER = logging.getLogger(__name__)
22
22
  class ReaderAndWriter:
23
23
  def __init__(self, *, output_folder: Union[str, Path], **kwargs: Any) -> None:
24
24
  self.output_folder = Path(output_folder)
25
+ self._list_file: List[str] = []
25
26
  try:
26
27
  with open(
27
28
  Path(self.output_folder) / Path("..") / Path("python.json"), "r"
@@ -37,7 +38,7 @@ class ReaderAndWriter:
37
38
  self.options.update(python_json)
38
39
 
39
40
  def read_file(self, path: Union[str, Path]) -> str:
40
- """How does one read a file in cadl?"""
41
+ """Directly reading from disk"""
41
42
  # make path relative to output folder
42
43
  try:
43
44
  with open(self.output_folder / Path(path), "r") as fd:
@@ -46,13 +47,16 @@ class ReaderAndWriter:
46
47
  return ""
47
48
 
48
49
  def write_file(self, filename: Union[str, Path], file_content: str) -> None:
49
- """How does writing work in cadl?"""
50
+ """Directly writing to disk"""
50
51
  file_folder = Path(filename).parent
51
52
  if not Path.is_dir(self.output_folder / file_folder):
52
53
  Path.mkdir(self.output_folder / file_folder, parents=True)
53
54
  with open(self.output_folder / Path(filename), "w") as fd:
54
55
  fd.write(file_content)
55
56
 
57
+ def list_file(self) -> List[str]:
58
+ return [str(f) for f in self.output_folder.glob("**/*") if f.is_file()]
59
+
56
60
 
57
61
  class ReaderAndWriterAutorest(ReaderAndWriter):
58
62
  def __init__(
@@ -67,6 +71,9 @@ class ReaderAndWriterAutorest(ReaderAndWriter):
67
71
  def write_file(self, filename: Union[str, Path], file_content: str) -> None:
68
72
  return self._autorestapi.write_file(filename, file_content)
69
73
 
74
+ def list_file(self) -> List[str]:
75
+ return self._autorestapi.list_inputs()
76
+
70
77
 
71
78
  class Plugin(ReaderAndWriter, ABC):
72
79
  """A base class for autorest plugin.
@@ -30,16 +30,10 @@ class BlackScriptPlugin(Plugin): # pylint: disable=abstract-method
30
30
 
31
31
  def process(self) -> bool:
32
32
  # apply format_file on every file in the output folder
33
- list(
34
- map(
35
- self.format_file,
36
- [f for f in self.output_folder.glob("**/*") if f.is_file()],
37
- )
38
- )
33
+ list(map(self.format_file, [Path(f) for f in self.list_file()]))
39
34
  return True
40
35
 
41
- def format_file(self, full_path) -> None:
42
- file = full_path.relative_to(self.output_folder)
36
+ def format_file(self, file: Path) -> None:
43
37
  file_content = self.read_file(file)
44
38
  if not file.suffix == ".py":
45
39
  self.write_file(file, file_content)
@@ -44,9 +44,9 @@ def _validate_code_model_options(options: Dict[str, Any]) -> None:
44
44
  "or 'embedded'"
45
45
  )
46
46
 
47
- if options["models_mode"] not in ["msrest", "none"]:
47
+ if options["models_mode"] not in ["msrest", "dpg", "none"]:
48
48
  raise ValueError(
49
- "--models-mode can only be 'msrest' or 'none'. "
49
+ "--models-mode can only be 'msrest', 'dpg' or 'none'. "
50
50
  "Pass in 'msrest' if you want msrest models, or "
51
51
  "'none' if you don't want any."
52
52
  )
@@ -179,6 +179,8 @@ class CodeGenerator(Plugin):
179
179
  models_mode_default = (
180
180
  "none" if low_level_client or version_tolerant else "msrest"
181
181
  )
182
+ if self.options.get("cadl_file") is not None:
183
+ models_mode_default = "dpg"
182
184
 
183
185
  options: Dict[str, Any] = {
184
186
  "azure_arm": azure_arm,
@@ -158,7 +158,7 @@ def build_type(yaml_data: Dict[str, Any], code_model: CodeModel) -> BaseType:
158
158
  code_model.types_map[yaml_id] = response
159
159
  response.fill_instance_from_yaml(yaml_data, code_model)
160
160
  else:
161
- object_type = yaml_data.get("type", None)
161
+ object_type = yaml_data.get("type")
162
162
  if object_type is None:
163
163
  _LOGGER.warning(
164
164
  'Unrecognized definition type "%s" is found, falling back it as "string"! ',
@@ -31,7 +31,9 @@ if TYPE_CHECKING:
31
31
  _LOGGER = logging.getLogger(__name__)
32
32
 
33
33
 
34
- class BaseBuilder(Generic[ParameterListType], BaseModel):
34
+ class BaseBuilder(
35
+ Generic[ParameterListType], BaseModel
36
+ ): # pylint: disable=too-many-instance-attributes
35
37
  """Base class for Operations and Request Builders"""
36
38
 
37
39
  def __init__(
@@ -56,6 +58,7 @@ class BaseBuilder(Generic[ParameterListType], BaseModel):
56
58
  self.group_name: str = yaml_data["groupName"]
57
59
  self.is_overload: bool = yaml_data["isOverload"]
58
60
  self.api_versions: List[str] = yaml_data["apiVersions"]
61
+ self.added_on: Optional[str] = yaml_data.get("addedOn")
59
62
 
60
63
  if code_model.options["version_tolerant"] and yaml_data.get("abstract"):
61
64
  _LOGGER.warning(
@@ -108,7 +108,6 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
108
108
  f"{self.code_model.client.name}Configuration",
109
109
  ImportType.LOCAL,
110
110
  )
111
-
112
111
  file_import.add_msrest_import(
113
112
  self.code_model,
114
113
  ".." if async_mode else ".",
@@ -148,7 +147,10 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
148
147
  ImportType.LOCAL,
149
148
  )
150
149
 
151
- if self.code_model.model_types and self.code_model.options["models_mode"]:
150
+ if (
151
+ self.code_model.model_types
152
+ and self.code_model.options["models_mode"] == "msrest"
153
+ ):
152
154
  path_to_models = ".." if async_mode else "."
153
155
  if len(self.code_model.model_types) != len(
154
156
  self.code_model.public_model_types
@@ -167,7 +169,7 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
167
169
  file_import.add_submodule_import(
168
170
  path_to_models, "models", ImportType.LOCAL
169
171
  )
170
- else:
172
+ elif self.code_model.options["models_mode"] == "msrest":
171
173
  # in this case, we have client_models = {} in the service client, which needs a type annotation
172
174
  # this import will always be commented, so will always add it to the typing section
173
175
  file_import.add_submodule_import(
@@ -4,7 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from typing import Any, Dict, List, Optional, TYPE_CHECKING
7
-
7
+ import re
8
8
  from autorest.codegen.models.imports import FileImport, ImportType
9
9
  from .base_type import BaseType
10
10
 
@@ -67,9 +67,11 @@ class CombinedType(BaseType):
67
67
  Special case for enum, for instance: Union[str, "EnumName"]
68
68
  """
69
69
  kwargs["is_operation_file"] = True
70
- return (
71
- f'Union[{", ".join(type.type_annotation(**kwargs) for type in self.types)}]'
72
- )
70
+ inside_types = [type.type_annotation(**kwargs) for type in self.types]
71
+
72
+ # If the inside types has been a Union, peel first and then re-union
73
+ pattern = re.compile(r"Union\[.*\]")
74
+ return f'Union[{", ".join(map(lambda x: x[6: -1] if pattern.match(x) else x, inside_types))}]'
73
75
 
74
76
  def get_json_template_representation(
75
77
  self,
@@ -107,10 +107,12 @@ class EnumType(BaseType):
107
107
  :rtype: str
108
108
  """
109
109
  if self.code_model.options["models_mode"]:
110
- return (
111
- f"Union[{self.value_type.type_annotation(**kwargs)},"
112
- f' "_models.{self.name}"]'
113
- )
110
+ model_name = f"_models.{self.name}"
111
+ # we don't need quoted annotation in operation files, and need it in model folder files.
112
+ if not kwargs.get("is_operation_file", False):
113
+ model_name = f'"{model_name}"'
114
+
115
+ return f"Union[{self.value_type.type_annotation(**kwargs)}, {model_name}]"
114
116
  return self.value_type.type_annotation(**kwargs)
115
117
 
116
118
  def get_declaration(self, value: Any) -> str:
@@ -8,6 +8,7 @@ from typing import Any, Dict, List, Optional, TYPE_CHECKING, cast
8
8
 
9
9
  from autorest.codegen.models.utils import add_to_pylint_disable
10
10
  from .base_type import BaseType
11
+ from .constant_type import ConstantType
11
12
  from .property import Property
12
13
  from .imports import FileImport, ImportType, TypingSection
13
14
 
@@ -32,7 +33,9 @@ def _get_properties(type: "ModelType", properties: List[Property]) -> List[Prope
32
33
  return properties
33
34
 
34
35
 
35
- class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
36
+ class ModelType(
37
+ BaseType
38
+ ): # pylint: disable=too-many-instance-attributes, too-many-public-methods
36
39
  """Represents a class ready to be serialized in Python.
37
40
 
38
41
  :param str name: The name of the class.
@@ -71,14 +74,16 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
71
74
 
72
75
  @property
73
76
  def serialization_type(self) -> str:
74
- if self.code_model.options["models_mode"]:
75
- return (
76
- self.name
77
- if self.is_public
78
- else f"{self.code_model.models_filename}.{self.name}"
79
- )
77
+ if self.code_model.options["models_mode"] == "msrest":
78
+ return f"{'' if self.is_public else (self.code_model.models_filename + '.')}{self.name}"
79
+ if self.code_model.options["models_mode"] == "dpg":
80
+ return f"{'' if self.is_public else '_models.'}_models.{self.name}"
80
81
  return "object"
81
82
 
83
+ @property
84
+ def is_polymorphic(self) -> bool:
85
+ return any(p.is_polymorphic for p in self.properties)
86
+
82
87
  def type_annotation(self, **kwargs: Any) -> str:
83
88
  if self.code_model.options["models_mode"]:
84
89
  is_operation_file = kwargs.pop("is_operation_file", False)
@@ -229,10 +234,26 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
229
234
  except StopIteration:
230
235
  return None
231
236
 
237
+ @property
238
+ def discriminator_property(self) -> Optional[Property]:
239
+ try:
240
+ return next(
241
+ p
242
+ for p in self.properties
243
+ if p.is_discriminator
244
+ and isinstance(p.type, ConstantType)
245
+ and p.type.value == self.discriminator_value
246
+ )
247
+ except StopIteration:
248
+ return None
249
+
232
250
  @property
233
251
  def instance_check_template(self) -> str:
234
- if self.code_model.options["models_mode"]:
252
+ models_mode = self.code_model.options["models_mode"]
253
+ if models_mode == "msrest":
235
254
  return "isinstance({}, msrest.Model)"
255
+ if models_mode == "dpg":
256
+ return "isinstance({}, _model_base.Model)"
236
257
  return "isinstance({}, MutableMapping)"
237
258
 
238
259
  @property
@@ -257,7 +278,7 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
257
278
  file_import.add_submodule_import(
258
279
  relative_path, "models", ImportType.LOCAL, alias="_models"
259
280
  )
260
- if self.code_model.options["models_mode"]:
281
+ if self.code_model.options["models_mode"] == "msrest":
261
282
  return file_import
262
283
  file_import.add_submodule_import(
263
284
  "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
@@ -154,6 +154,14 @@ class OperationBase( # pylint: disable=too-many-public-methods
154
154
  retval = self._response_docstring_helper("docstring_text", **kwargs)
155
155
  if not self.code_model.options["version_tolerant"]:
156
156
  retval += " or the result of cls(response)"
157
+ if self.code_model.options["models_mode"] == "dpg" and any(
158
+ isinstance(r.type, ModelType) for r in self.responses
159
+ ):
160
+ r = next(r for r in self.responses if isinstance(r.type, ModelType))
161
+ type_name = getattr(r, "item_type", getattr(r, "type")).docstring_text(
162
+ **kwargs
163
+ )
164
+ retval += f". The {type_name} is compatible with MutableMapping"
157
165
  return retval
158
166
 
159
167
  def response_docstring_type(self, **kwargs) -> str:
@@ -209,6 +217,12 @@ class OperationBase( # pylint: disable=too-many-public-methods
209
217
  file_import.add_submodule_import(
210
218
  "typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL
211
219
  )
220
+ if self.added_on:
221
+ file_import.add_submodule_import(
222
+ f"{'.' if async_mode else ''}.._validation",
223
+ "api_version_validation",
224
+ ImportType.LOCAL,
225
+ )
212
226
  return file_import
213
227
 
214
228
  def imports_for_multiapi(self, async_mode: bool, **kwargs: Any) -> FileImport:
@@ -244,6 +258,11 @@ class OperationBase( # pylint: disable=too-many-public-methods
244
258
  for kwarg in kwargs_to_pop
245
259
  )
246
260
 
261
+ @property
262
+ def need_validation(self) -> bool:
263
+ """Whether we need parameter / operation validation. For API version."""
264
+ return bool(self.added_on) or any(p for p in self.parameters if p.added_on)
265
+
247
266
  def get_request_builder_import(
248
267
  self,
249
268
  request_builder: Union[RequestBuilder, OverloadedRequestBuilder],
@@ -450,6 +469,19 @@ class Operation(OperationBase[Response]):
450
469
  and not self.code_model.options["models_mode"]
451
470
  ):
452
471
  file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
472
+ if self.code_model.options["models_mode"] == "dpg":
473
+ relative_path = "..." if async_mode else ".."
474
+ if self.parameters.has_body:
475
+ file_import.add_submodule_import(
476
+ f"{relative_path}_model_base", "AzureJSONEncoder", ImportType.LOCAL
477
+ )
478
+ file_import.add_import("json", ImportType.STDLIB)
479
+ if self.default_error_deserialization or any(
480
+ [r.type for r in self.responses]
481
+ ):
482
+ file_import.add_submodule_import(
483
+ f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL
484
+ )
453
485
 
454
486
  return file_import
455
487
 
@@ -66,6 +66,11 @@ class OperationGroup(BaseModel):
66
66
  return " # type: ignore"
67
67
  return ""
68
68
 
69
+ @property
70
+ def need_validation(self) -> bool:
71
+ """Whether any of its operations need validation"""
72
+ return any(o for o in self.operations if o.need_validation)
73
+
69
74
  def imports(self, async_mode: bool) -> FileImport:
70
75
  file_import = FileImport()
71
76
 
@@ -75,13 +80,12 @@ class OperationGroup(BaseModel):
75
80
  operation.imports(async_mode, relative_path=relative_path)
76
81
  )
77
82
  # for multiapi
78
- if not self.code_model.options["version_tolerant"]:
79
- if (
80
- self.code_model.model_types or self.code_model.enums
81
- ) and self.code_model.options["models_mode"]:
82
- file_import.add_submodule_import(
83
- relative_path, "models", ImportType.LOCAL, alias="_models"
84
- )
83
+ if (
84
+ self.code_model.model_types or self.code_model.enums
85
+ ) and self.code_model.options["models_mode"] == "msrest":
86
+ file_import.add_submodule_import(
87
+ relative_path, "models", ImportType.LOCAL, alias="_models"
88
+ )
85
89
  if self.code_model.need_mixin_abc:
86
90
  file_import.add_submodule_import(".._vendor", "MixinABC", ImportType.LOCAL)
87
91
  if self.has_abstract_operations:
@@ -5,6 +5,7 @@
5
5
  # --------------------------------------------------------------------------
6
6
  import abc
7
7
  from enum import Enum, auto
8
+ import re
8
9
 
9
10
  from typing import (
10
11
  Dict,
@@ -21,6 +22,8 @@ from .imports import FileImport, ImportType
21
22
  from .base_model import BaseModel
22
23
  from .base_type import BaseType
23
24
  from .constant_type import ConstantType
25
+ from .model_type import ModelType
26
+ from .combined_type import CombinedType
24
27
  from .utils import add_to_description
25
28
 
26
29
  if TYPE_CHECKING:
@@ -82,6 +85,7 @@ class _ParameterBase(
82
85
  self.in_flattened_body: bool = self.yaml_data.get("inFlattenedBody", False)
83
86
  self.grouper: bool = self.yaml_data.get("grouper", False)
84
87
  self.check_client_input: bool = self.yaml_data.get("checkClientInput", False)
88
+ self.added_on: Optional[str] = self.yaml_data.get("addedOn")
85
89
 
86
90
  @property
87
91
  def constant(self) -> bool:
@@ -152,6 +156,12 @@ class _ParameterBase(
152
156
  )
153
157
  if self.optional and self.client_default_value is None:
154
158
  file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
159
+ if self.added_on:
160
+ file_import.add_submodule_import(
161
+ f"{'.' if async_mode else ''}.._validation",
162
+ "api_version_validation",
163
+ ImportType.LOCAL,
164
+ )
155
165
  return file_import
156
166
 
157
167
  @property
@@ -228,6 +238,40 @@ class BodyParameter(_BodyParameterBase):
228
238
  type=code_model.lookup_type(id(yaml_data["type"])),
229
239
  )
230
240
 
241
+ def type_annotation(self, **kwargs: Any) -> str:
242
+ annotation = super().type_annotation(**kwargs)
243
+ model_seq = BodyParameter.get_model_seq(self.type)
244
+ if self.code_model.options["models_mode"] == "dpg" and model_seq >= 0:
245
+ pattern = re.compile(r"Union\[.*\]")
246
+ union_content = (
247
+ annotation[6:-1] if pattern.match(annotation) else annotation
248
+ )
249
+ items = union_content.split(", ")
250
+ items.insert(model_seq + 1, "JSON")
251
+ annotation = f'Union[{", ".join(items)}]'
252
+ return annotation
253
+
254
+ def docstring_type(self, **kwargs: Any) -> str:
255
+ docstring = super().docstring_type(**kwargs)
256
+ model_seq = BodyParameter.get_model_seq(self.type)
257
+ if self.code_model.options["models_mode"] == "dpg" and model_seq >= 0:
258
+ items = docstring.split(" or ")
259
+ items.insert(model_seq + 1, "JSON")
260
+ docstring = " or ".join(items)
261
+ return docstring
262
+
263
+ @staticmethod
264
+ def get_model_seq(t: BaseType):
265
+ if isinstance(t, ModelType):
266
+ return 0
267
+ if isinstance(t, CombinedType):
268
+ sub_num = len(t.types)
269
+ for i in range(sub_num):
270
+ sub_seq = BodyParameter.get_model_seq(t.types[i])
271
+ if sub_seq >= 0:
272
+ return i + sub_seq
273
+ return -1
274
+
231
275
 
232
276
  EntryBodyParameterType = TypeVar(
233
277
  "EntryBodyParameterType", bound=Union[BodyParameter, "RequestBuilderBodyParameter"]
@@ -29,6 +29,7 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
29
29
  self.type = type
30
30
  self.optional: bool = self.yaml_data["optional"]
31
31
  self.readonly: bool = self.yaml_data.get("readonly", False)
32
+ self.is_polymorphic: bool = self.yaml_data.get("isPolymorphic", False)
32
33
  self.is_discriminator: bool = yaml_data.get("isDiscriminator", False)
33
34
  self.client_default_value = yaml_data.get("clientDefaultValue", None)
34
35
  if self.client_default_value is None:
@@ -45,7 +46,7 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
45
46
  def description(self, *, is_operation_file: bool) -> str:
46
47
  from .model_type import ModelType
47
48
 
48
- description = self.yaml_data["description"]
49
+ description = self.yaml_data.get("description", "")
49
50
  if not (self.optional or self.client_default_value):
50
51
  description = add_to_description(description, "Required.")
51
52
  # don't want model type documentation as part of property doc
@@ -124,20 +125,6 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
124
125
  retval.update(self.type.validation or {})
125
126
  return retval or None
126
127
 
127
- @property
128
- def attribute_map(self) -> str:
129
- if self.flattened_names:
130
- attribute_key = ".".join(
131
- n.replace(".", "\\\\.") for n in self.flattened_names
132
- )
133
- else:
134
- attribute_key = self.rest_api_name.replace(".", "\\\\.")
135
- if self.type.xml_serialization_ctxt:
136
- xml_metadata = f", 'xml': {{{self.type.xml_serialization_ctxt}}}"
137
- else:
138
- xml_metadata = ""
139
- return f'"{self.client_name}": {{"key": "{attribute_key}", "type": "{self.serialization_type}"{xml_metadata}}},'
140
-
141
128
  def imports(self) -> FileImport:
142
129
  from .model_type import ModelType
143
130
 
@@ -152,6 +139,12 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
152
139
  TypingSection.TYPING,
153
140
  alias="_models",
154
141
  )
142
+ if self.code_model.options["models_mode"] == "dpg":
143
+ file_import.add_submodule_import(
144
+ ".._model_base",
145
+ "rest_discriminator" if self.is_discriminator else "rest_field",
146
+ ImportType.LOCAL,
147
+ )
155
148
  return file_import
156
149
 
157
150
  @classmethod
@@ -24,8 +24,10 @@ class RequestBuilderBodyParameter(BodyParameter):
24
24
 
25
25
  def __init__(self, *args, **kwargs) -> None:
26
26
  super().__init__(*args, **kwargs)
27
- if isinstance(self.type, (BinaryType, StringType)) or any(
28
- "xml" in ct for ct in self.content_types
27
+ if (
28
+ isinstance(self.type, (BinaryType, StringType))
29
+ or any("xml" in ct for ct in self.content_types)
30
+ or self.code_model.options["models_mode"] == "dpg"
29
31
  ):
30
32
  self.client_name = "content"
31
33
  else:
@@ -16,7 +16,7 @@ from ..models import TokenCredentialType
16
16
  from .enum_serializer import EnumSerializer
17
17
  from .general_serializer import GeneralSerializer
18
18
  from .model_init_serializer import ModelInitSerializer
19
- from .model_serializer import ModelSerializer
19
+ from .model_serializer import DpgModelSerializer, MsrestModelSerializer
20
20
  from .operations_init_serializer import OperationsInitSerializer
21
21
  from .operation_groups_serializer import OperationGroupsSerializer
22
22
  from .metadata_serializer import MetadataSerializer
@@ -215,10 +215,15 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
215
215
  ) -> None:
216
216
  # Write the models folder
217
217
  models_path = namespace_path / Path("models")
218
+ serializer = (
219
+ DpgModelSerializer
220
+ if self.code_model.options["models_mode"] == "dpg"
221
+ else MsrestModelSerializer
222
+ )
218
223
  if self.code_model.model_types:
219
224
  self.write_file(
220
225
  models_path / Path(f"{self.code_model.models_filename}.py"),
221
- ModelSerializer(code_model=self.code_model, env=env).serialize(),
226
+ serializer(code_model=self.code_model, env=env).serialize(),
222
227
  )
223
228
  if self.code_model.enums:
224
229
  self.write_file(
@@ -427,6 +432,17 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
427
432
  namespace_path / Path("_serialization.py"),
428
433
  general_serializer.serialize_serialization_file(),
429
434
  )
435
+ if self.code_model.options["models_mode"] == "dpg":
436
+ self.write_file(
437
+ namespace_path / Path("_model_base.py"),
438
+ general_serializer.serialize_model_base_file(),
439
+ )
440
+
441
+ if any(og for og in self.code_model.operation_groups if og.need_validation):
442
+ self.write_file(
443
+ namespace_path / Path("_validation.py"),
444
+ general_serializer.serialize_validation_file(),
445
+ )
430
446
 
431
447
  # Write the config file
432
448
  if self.code_model.request_builders: