@autorest/python 5.16.0 → 5.19.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 (96) hide show
  1. package/ChangeLog.md +79 -4
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +1 -1
  4. package/autorest/codegen/__init__.py +55 -211
  5. package/autorest/codegen/models/__init__.py +116 -83
  6. package/autorest/codegen/models/base_builder.py +49 -88
  7. package/autorest/codegen/models/base_model.py +1 -1
  8. package/autorest/codegen/models/{base_schema.py → base_type.py} +61 -39
  9. package/autorest/codegen/models/client.py +165 -53
  10. package/autorest/codegen/models/code_model.py +122 -257
  11. package/autorest/codegen/models/combined_type.py +107 -0
  12. package/autorest/codegen/models/{constant_schema.py → constant_type.py} +49 -40
  13. package/autorest/codegen/models/credential_types.py +224 -0
  14. package/autorest/codegen/models/dictionary_type.py +131 -0
  15. package/autorest/codegen/models/enum_type.py +195 -0
  16. package/autorest/codegen/models/imports.py +80 -2
  17. package/autorest/codegen/models/list_type.py +149 -0
  18. package/autorest/codegen/models/lro_operation.py +79 -156
  19. package/autorest/codegen/models/lro_paging_operation.py +28 -11
  20. package/autorest/codegen/models/model_type.py +262 -0
  21. package/autorest/codegen/models/operation.py +331 -298
  22. package/autorest/codegen/models/operation_group.py +54 -91
  23. package/autorest/codegen/models/paging_operation.py +82 -123
  24. package/autorest/codegen/models/parameter.py +289 -396
  25. package/autorest/codegen/models/parameter_list.py +355 -360
  26. package/autorest/codegen/models/primitive_types.py +544 -0
  27. package/autorest/codegen/models/property.py +123 -139
  28. package/autorest/codegen/models/request_builder.py +130 -102
  29. package/autorest/codegen/models/request_builder_parameter.py +112 -100
  30. package/autorest/codegen/models/response.py +325 -0
  31. package/autorest/codegen/models/utils.py +12 -19
  32. package/autorest/codegen/serializers/__init__.py +55 -37
  33. package/autorest/codegen/serializers/builder_serializer.py +695 -1144
  34. package/autorest/codegen/serializers/client_serializer.py +92 -89
  35. package/autorest/codegen/serializers/general_serializer.py +15 -69
  36. package/autorest/codegen/serializers/import_serializer.py +7 -4
  37. package/autorest/codegen/serializers/metadata_serializer.py +15 -104
  38. package/autorest/codegen/serializers/model_base_serializer.py +49 -36
  39. package/autorest/codegen/serializers/model_generic_serializer.py +8 -6
  40. package/autorest/codegen/serializers/model_init_serializer.py +2 -4
  41. package/autorest/codegen/serializers/model_python3_serializer.py +22 -16
  42. package/autorest/codegen/serializers/operation_groups_serializer.py +7 -13
  43. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  44. package/autorest/codegen/serializers/request_builders_serializer.py +13 -30
  45. package/autorest/codegen/serializers/utils.py +0 -140
  46. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  47. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +10 -7
  48. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  49. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  50. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  51. package/autorest/codegen/templates/init.py.jinja2 +2 -2
  52. package/autorest/codegen/templates/lro_operation.py.jinja2 +4 -1
  53. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +4 -1
  54. package/autorest/codegen/templates/metadata.json.jinja2 +33 -33
  55. package/autorest/codegen/templates/model.py.jinja2 +23 -24
  56. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  57. package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
  58. package/autorest/codegen/templates/operation.py.jinja2 +6 -8
  59. package/autorest/codegen/templates/operation_group.py.jinja2 +21 -8
  60. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -2
  61. package/autorest/codegen/templates/operation_tools.jinja2 +11 -3
  62. package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
  63. package/autorest/codegen/templates/request_builder.py.jinja2 +10 -15
  64. package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
  65. package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
  66. package/autorest/codegen/templates/setup.py.jinja2 +13 -3
  67. package/autorest/codegen/templates/vendor.py.jinja2 +11 -1
  68. package/autorest/jsonrpc/server.py +15 -3
  69. package/autorest/m4reformatter/__init__.py +1126 -0
  70. package/autorest/multiapi/models/client.py +12 -2
  71. package/autorest/multiapi/models/code_model.py +1 -1
  72. package/autorest/multiapi/serializers/__init__.py +18 -4
  73. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  74. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  75. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  76. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  77. package/autorest/postprocess/__init__.py +202 -0
  78. package/autorest/postprocess/get_all.py +19 -0
  79. package/autorest/postprocess/venvtools.py +73 -0
  80. package/autorest/preprocess/__init__.py +210 -0
  81. package/autorest/preprocess/helpers.py +54 -0
  82. package/autorest/{namer → preprocess}/python_mappings.py +21 -16
  83. package/package.json +2 -2
  84. package/autorest/codegen/models/credential_model.py +0 -55
  85. package/autorest/codegen/models/credential_schema.py +0 -95
  86. package/autorest/codegen/models/credential_schema_policy.py +0 -73
  87. package/autorest/codegen/models/dictionary_schema.py +0 -106
  88. package/autorest/codegen/models/enum_schema.py +0 -225
  89. package/autorest/codegen/models/list_schema.py +0 -135
  90. package/autorest/codegen/models/object_schema.py +0 -303
  91. package/autorest/codegen/models/primitive_schemas.py +0 -495
  92. package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
  93. package/autorest/codegen/models/schema_request.py +0 -55
  94. package/autorest/codegen/models/schema_response.py +0 -141
  95. package/autorest/namer/__init__.py +0 -23
  96. package/autorest/namer/name_converter.py +0 -509
@@ -1,225 +0,0 @@
1
- # -------------------------------------------------------------------------
2
- # Copyright (c) Microsoft Corporation. All rights reserved.
3
- # Licensed under the MIT License. See License.txt in the project root for
4
- # license information.
5
- # --------------------------------------------------------------------------
6
- from typing import Any, Dict, List, Optional, Set, Type, TYPE_CHECKING
7
- from .base_schema import BaseSchema
8
- from .primitive_schemas import PrimitiveSchema, get_primitive_schema, StringSchema
9
- from .imports import FileImport, ImportType, TypingSection
10
-
11
- if TYPE_CHECKING:
12
- from .code_model import CodeModel
13
-
14
-
15
- class EnumValue:
16
- """Model containing necessary information for a single value of an enum.
17
-
18
- :param str name: The name of this enum value
19
- :param str value: The value of this enum value
20
- :param str description: Optional. The description for this enum value
21
- """
22
-
23
- def __init__(
24
- self, name: str, value: str, description: Optional[str] = None
25
- ) -> None:
26
- self.name = name
27
- self.value = value
28
- self.description = description
29
-
30
- @classmethod
31
- def from_yaml(cls, yaml_data: Dict[str, Any]) -> "EnumValue":
32
- """Constructs an EnumValue from yaml data.
33
-
34
- :param yaml_data: the yaml data from which we will construct this object
35
- :type yaml_data: dict[str, Any]
36
-
37
- :return: A created EnumValue
38
- :rtype: ~autorest.models.EnumValue
39
- """
40
- return cls(
41
- name=yaml_data["language"]["python"]["name"],
42
- value=yaml_data["value"],
43
- description=yaml_data["language"]["python"].get("description"),
44
- )
45
-
46
-
47
- class EnumSchema(BaseSchema):
48
- """Schema for enums that will be serialized.
49
-
50
- :param yaml_data: the yaml data for this schema
51
- :type yaml_data: dict[str, Any]
52
- :param str description: The description of this enum
53
- :param str name: The name of the enum.
54
- :type element_type: ~autorest.models.PrimitiveSchema
55
- :param values: List of the values for this enum
56
- :type values: list[~autorest.models.EnumValue]
57
- """
58
-
59
- def __init__(
60
- self,
61
- yaml_data: Dict[str, Any],
62
- code_model: "CodeModel",
63
- description: str,
64
- name: str,
65
- values: List["EnumValue"],
66
- enum_type: PrimitiveSchema,
67
- ) -> None:
68
- super().__init__(yaml_data=yaml_data, code_model=code_model)
69
- self.description = description
70
- self.name = name
71
- self.values = values
72
- self.enum_type = enum_type
73
-
74
- def __lt__(self, other):
75
- return self.name.lower() < other.name.lower()
76
-
77
- @property
78
- def serialization_type(self) -> str:
79
- """Returns the serialization value for msrest.
80
-
81
- :return: The serialization value for msrest
82
- :rtype: str
83
- """
84
- return self.enum_type.serialization_type
85
-
86
- def type_annotation(self, *, is_operation_file: bool = False) -> str:
87
- """The python type used for type annotation
88
-
89
- :return: The type annotation for this schema
90
- :rtype: str
91
- """
92
- return f'Union[{self.enum_type.type_annotation(is_operation_file=is_operation_file)}, "_models.{self.name}"]'
93
-
94
- def get_declaration(self, value: Any) -> str:
95
- return self.enum_type.get_declaration(value)
96
-
97
- @property
98
- def docstring_text(self) -> str:
99
- return self.name
100
-
101
- @property
102
- def docstring_type(self) -> str:
103
- """The python type used for RST syntax input and type annotation."""
104
- return f"{self.enum_type.type_annotation()} or ~{self.code_model.namespace}.models.{self.name}"
105
-
106
- @staticmethod
107
- def _get_enum_values(yaml_data: List[Dict[str, Any]]) -> List["EnumValue"]:
108
- """Creates the list of values for this enum.
109
-
110
- :param yaml_data: yaml data about the enum's values
111
- :type yaml_data: dict[str, Any]
112
- :return: The list of values for this enum
113
- :rtype: list[~autorest.models.EnumValue]
114
- """
115
- values = []
116
- seen_enums: Set[str] = set()
117
-
118
- for enum in yaml_data:
119
- enum_name = enum["language"]["python"]["name"]
120
- if enum_name in seen_enums:
121
- continue
122
- values.append(EnumValue.from_yaml(enum))
123
- seen_enums.add(enum_name)
124
- return values
125
-
126
- def _template_kwargs(self, **kwargs: Any) -> Any:
127
- if len(self.values) == 1 and not kwargs.get("default_value_declaration"):
128
- kwargs["default_value_declaration"] = self.enum_type.get_declaration(
129
- self.values[0].value
130
- )
131
- description = kwargs.pop("description", "")
132
- kwargs["description"] = description
133
- return kwargs
134
-
135
- def get_json_template_representation(self, **kwargs: Any) -> Any:
136
- # for better display effect, use the only value instead of var type
137
- return self.enum_type.get_json_template_representation(
138
- **self._template_kwargs(**kwargs)
139
- )
140
-
141
- @classmethod
142
- def from_yaml(
143
- cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
144
- ) -> "EnumSchema":
145
- """Constructs an EnumSchema from yaml data.
146
-
147
- :param yaml_data: the yaml data from which we will construct this schema
148
- :type yaml_data: dict[str, Any]
149
-
150
- :return: A created EnumSchema
151
- :rtype: ~autorest.models.EnumSchema
152
- """
153
- name = yaml_data["language"]["python"]["name"]
154
-
155
- # choice type doesn't always exist. if there is no choiceType, we default to string
156
- if yaml_data.get("choiceType"):
157
- enum_type = get_primitive_schema(yaml_data["choiceType"], code_model)
158
- else:
159
- enum_type = StringSchema({"type": "str"}, code_model)
160
- values = EnumSchema._get_enum_values(yaml_data["choices"])
161
- return cls(
162
- yaml_data=yaml_data,
163
- code_model=code_model,
164
- description=yaml_data["language"]["python"]["description"],
165
- name=name,
166
- values=values,
167
- enum_type=enum_type,
168
- )
169
-
170
- def imports(self) -> FileImport:
171
- file_import = FileImport()
172
- file_import.add_submodule_import(
173
- "typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL
174
- )
175
- file_import.merge(self.enum_type.imports())
176
- return file_import
177
-
178
-
179
- class HiddenModelEnumSchema(EnumSchema):
180
- def imports(self) -> FileImport:
181
- file_import = FileImport()
182
- file_import.merge(self.enum_type.imports())
183
- return file_import
184
-
185
- def type_annotation(self, *, is_operation_file: bool = False) -> str:
186
- """The python type used for type annotation
187
-
188
- :return: The type annotation for this schema
189
- :rtype: str
190
- """
191
- return self.enum_type.type_annotation(is_operation_file=is_operation_file)
192
-
193
- @property
194
- def docstring_text(self) -> str:
195
- return (
196
- f"{self.enum_type.type_annotation()}. {self.extra_description_information}"
197
- )
198
-
199
- @property
200
- def extra_description_information(self):
201
- possible_values = [self.get_declaration(v.value) for v in self.values]
202
- if not possible_values:
203
- return ""
204
- if len(possible_values) == 1:
205
- return possible_values[0]
206
- if len(possible_values) == 2:
207
- possible_values_str = " or ".join(possible_values)
208
- else:
209
- possible_values_str = (
210
- ", ".join(possible_values[: len(possible_values) - 1])
211
- + f", and {possible_values[-1]}"
212
- )
213
-
214
- return "Known values are: {}.".format(possible_values_str)
215
-
216
- @property
217
- def docstring_type(self) -> str:
218
- """The python type used for RST syntax input and type annotation."""
219
- return self.enum_type.type_annotation()
220
-
221
-
222
- def get_enum_schema(code_model) -> Type[EnumSchema]:
223
- if code_model.options["models_mode"]:
224
- return EnumSchema
225
- return HiddenModelEnumSchema
@@ -1,135 +0,0 @@
1
- # -------------------------------------------------------------------------
2
- # Copyright (c) Microsoft Corporation. All rights reserved.
3
- # Licensed under the MIT License. See License.txt in the project root for
4
- # license information.
5
- # --------------------------------------------------------------------------
6
- from typing import Any, Dict, Optional, Union, TYPE_CHECKING
7
- from .base_schema import BaseSchema
8
- from .imports import FileImport, ImportType, TypingSection
9
-
10
- if TYPE_CHECKING:
11
- from .code_model import CodeModel
12
-
13
-
14
- class ListSchema(BaseSchema):
15
- def __init__(
16
- self,
17
- yaml_data: Dict[str, Any],
18
- code_model: "CodeModel",
19
- element_type: BaseSchema,
20
- *,
21
- max_items: Optional[int] = None,
22
- min_items: Optional[int] = None,
23
- unique_items: Optional[int] = None,
24
- ) -> None:
25
- super().__init__(yaml_data=yaml_data, code_model=code_model)
26
- self.element_type = element_type
27
- self.max_items = max_items
28
- self.min_items = min_items
29
- self.unique_items = unique_items
30
-
31
- @property
32
- def serialization_type(self) -> str:
33
- return f"[{self.element_type.serialization_type}]"
34
-
35
- def type_annotation(self, *, is_operation_file: bool = False) -> str:
36
- if self.element_type.type_annotation() == "ET.Element":
37
- # this means we're version tolerant XML, we just return the XML element
38
- return self.element_type.type_annotation(
39
- is_operation_file=is_operation_file
40
- )
41
- return f"List[{self.element_type.type_annotation(is_operation_file=is_operation_file)}]"
42
-
43
- @property
44
- def docstring_type(self) -> str:
45
- if self.element_type.docstring_type == "ET.Element":
46
- # this means we're version tolerant XML, we just return the XML element
47
- return self.element_type.docstring_type
48
- return f"list[{self.element_type.docstring_type}]"
49
-
50
- @property
51
- def docstring_text(self) -> str:
52
- if self.element_type.docstring_text == "XML Element":
53
- # this means we're version tolerant XML, we just return the XML element
54
- return self.element_type.docstring_text
55
- return f"list of {self.element_type.docstring_text}"
56
-
57
- @property
58
- def validation_map(self) -> Optional[Dict[str, Union[bool, int, str]]]:
59
- validation_map: Dict[str, Union[bool, int, str]] = {}
60
- if self.max_items:
61
- validation_map["max_items"] = self.max_items
62
- validation_map["min_items"] = self.min_items or 0
63
- if self.min_items:
64
- validation_map["min_items"] = self.min_items
65
- if self.unique_items:
66
- validation_map["unique"] = True
67
- return validation_map or None
68
-
69
- @property
70
- def has_xml_serialization_ctxt(self) -> bool:
71
- return (
72
- super().has_xml_serialization_ctxt
73
- or self.element_type.has_xml_serialization_ctxt
74
- )
75
-
76
- def get_json_template_representation(self, **kwargs: Any) -> Any:
77
- return [self.element_type.get_json_template_representation(**kwargs)]
78
-
79
- def xml_serialization_ctxt(self) -> Optional[str]:
80
- attrs_list = []
81
- base_xml_map = super().xml_serialization_ctxt()
82
- if base_xml_map:
83
- attrs_list.append(base_xml_map)
84
-
85
- # Attribute at the list level
86
- if self.xml_metadata.get("wrapped", False):
87
- attrs_list.append("'wrapped': True")
88
-
89
- # Attributes of the items
90
- item_xml_metadata = self.element_type.xml_metadata
91
- if item_xml_metadata.get("name"):
92
- attrs_list.append(f"'itemsName': '{item_xml_metadata['name']}'")
93
- if item_xml_metadata.get("prefix", False):
94
- attrs_list.append(f"'itemsPrefix': '{item_xml_metadata['prefix']}'")
95
- if item_xml_metadata.get("namespace", False):
96
- attrs_list.append(f"'itemsNs': '{item_xml_metadata['namespace']}'")
97
-
98
- return ", ".join(attrs_list)
99
-
100
- @classmethod
101
- def from_yaml(
102
- cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
103
- ) -> "ListSchema":
104
- # TODO: for items, if the type is a primitive is it listed in type instead of $ref?
105
- element_schema = yaml_data["elementType"]
106
-
107
- from . import build_schema # pylint: disable=import-outside-toplevel
108
-
109
- element_type = build_schema(yaml_data=element_schema, code_model=code_model)
110
-
111
- return cls(
112
- yaml_data=yaml_data,
113
- code_model=code_model,
114
- element_type=element_type,
115
- max_items=yaml_data.get("maxItems"),
116
- min_items=yaml_data.get("minItems"),
117
- unique_items=yaml_data.get("uniqueItems"),
118
- )
119
-
120
- def imports(self) -> FileImport:
121
- file_import = FileImport()
122
- if (
123
- not self.element_type.type_annotation(is_operation_file=True)
124
- == "ET.Element"
125
- ):
126
- file_import.add_submodule_import(
127
- "typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
128
- )
129
- file_import.merge(self.element_type.imports())
130
- return file_import
131
-
132
- def model_file_imports(self) -> FileImport:
133
- file_import = self.imports()
134
- file_import.merge(self.element_type.model_file_imports())
135
- return file_import
@@ -1,303 +0,0 @@
1
- # -------------------------------------------------------------------------
2
- # Copyright (c) Microsoft Corporation. All rights reserved.
3
- # Licensed under the MIT License. See License.txt in the project root for
4
- # license information.
5
- # --------------------------------------------------------------------------
6
- from typing import Any, Dict, List, Optional, Union, Type, TYPE_CHECKING
7
- from .base_schema import BaseSchema
8
- from .dictionary_schema import DictionarySchema
9
- from .property import Property
10
- from .imports import FileImport, ImportModel, ImportType, TypingSection
11
-
12
- if TYPE_CHECKING:
13
- from .code_model import CodeModel
14
-
15
-
16
- class ObjectSchema(BaseSchema): # pylint: disable=too-many-instance-attributes
17
- """Represents a class ready to be serialized in Python.
18
-
19
- :param str name: The name of the class.
20
- :param str description: The description of the class.
21
- :param properties: the optional properties of the class.
22
- :type properties: dict(str, str)
23
- """
24
-
25
- def __init__(
26
- self,
27
- yaml_data: Dict[str, Any],
28
- code_model: "CodeModel",
29
- name: str,
30
- description: str = "",
31
- **kwargs,
32
- ) -> None:
33
- super().__init__(yaml_data=yaml_data, code_model=code_model)
34
- self.name = name
35
- self.description = description
36
- self.max_properties: Optional[int] = kwargs.pop("max_properties", None)
37
- self.min_properties: Optional[int] = kwargs.pop("min_properties", None)
38
- self.properties: List[Property] = kwargs.pop("properties", [])
39
- self.is_exception: bool = kwargs.pop("is_exception", False)
40
- self.base_models: Union[List[int], List["ObjectSchema"]] = kwargs.pop(
41
- "base_models", []
42
- )
43
- self.subtype_map: Optional[Dict[str, str]] = kwargs.pop("subtype_map", None)
44
- self.discriminator_name: Optional[str] = kwargs.pop("discriminator_name", None)
45
- self.discriminator_value: Optional[str] = kwargs.pop(
46
- "discriminator_value", None
47
- )
48
- self._created_json_template_representation = False
49
-
50
- @property
51
- def serialization_type(self) -> str:
52
- return self.name
53
-
54
- def type_annotation(self, *, is_operation_file: bool = False) -> str:
55
- retval = f"_models.{self.name}"
56
- return retval if is_operation_file else f'"{retval}"'
57
-
58
- @property
59
- def docstring_type(self) -> str:
60
- return f"~{self.code_model.namespace}.models.{self.name}"
61
-
62
- @property
63
- def docstring_text(self) -> str:
64
- return self.name
65
-
66
- def get_declaration(self, value: Any) -> str:
67
- return f"{self.name}()"
68
-
69
- def __repr__(self) -> str:
70
- return f"<{self.__class__.__name__} {self.name}>"
71
-
72
- @property
73
- def has_xml_serialization_ctxt(self) -> bool:
74
- return False
75
-
76
- def xml_serialization_ctxt(self) -> Optional[str]:
77
- # object schema contains _xml_map, they don't need serialization context
78
- return ""
79
-
80
- def xml_map_content(self) -> Optional[str]:
81
- if not self.xml_metadata:
82
- raise ValueError("This object does not contain XML metadata")
83
- # This is NOT an error on the super call, we use the serialization context for "xml_map",
84
- # but we don't want to write a serialization context for an object.
85
- return super().xml_serialization_ctxt()
86
-
87
- def get_json_template_representation(self, **kwargs: Any) -> Any:
88
- if self._created_json_template_representation:
89
- return "..." # do this to avoid loop
90
- self._created_json_template_representation = True
91
- # don't add additional properties, because there's not really a concept of
92
- # additional properties in the template
93
- representation = {
94
- f'"{prop.original_swagger_name}"': prop.get_json_template_representation(
95
- **kwargs
96
- )
97
- for prop in [
98
- p
99
- for p in self.properties
100
- if not (p.is_discriminator or p.name == "additional_properties")
101
- ]
102
- }
103
- try:
104
- # add discriminator prop if there is one
105
- discriminator = next(p for p in self.properties if p.is_discriminator)
106
- representation[discriminator.original_swagger_name] = (
107
- self.discriminator_value or discriminator.original_swagger_name
108
- )
109
- except StopIteration:
110
- pass
111
-
112
- # once we've finished, we want to reset created_json_template_representation to false
113
- # so we can call it again
114
- self._created_json_template_representation = False
115
- return representation
116
-
117
- @classmethod
118
- def from_yaml(
119
- cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
120
- ) -> "ObjectSchema":
121
- """Returns a ClassType from the dict object constructed from a yaml file.
122
-
123
- WARNING: This guy might create an infinite loop.
124
-
125
- :param str name: The name of the class type.
126
- :param yaml_data: A representation of the schema of a class type from a yaml file.
127
- :type yaml_data: dict(str, str)
128
- :returns: A ClassType.
129
- :rtype: ~autorest.models.schema.ClassType
130
- """
131
- obj = cls(yaml_data, code_model, "", description="")
132
- obj.fill_instance_from_yaml(yaml_data, code_model)
133
- return obj
134
-
135
- def fill_instance_from_yaml(
136
- self, yaml_data: Dict[str, Any], code_model: "CodeModel"
137
- ) -> None:
138
- properties = []
139
- base_models = []
140
-
141
- name = yaml_data["language"]["python"]["name"]
142
-
143
- # checking to see if there is a parent class and / or additional properties
144
- if yaml_data.get("parents"):
145
- immediate_parents = yaml_data["parents"]["immediate"]
146
- # checking if object has a parent
147
- if immediate_parents:
148
- for immediate_parent in immediate_parents:
149
- if immediate_parent["type"] == "dictionary":
150
- additional_properties_schema = DictionarySchema.from_yaml(
151
- yaml_data=immediate_parent, code_model=code_model
152
- )
153
- properties.append(
154
- Property(
155
- yaml_data={},
156
- code_model=code_model,
157
- name="additional_properties",
158
- schema=additional_properties_schema,
159
- original_swagger_name="",
160
- description=(
161
- "Unmatched properties from the message are "
162
- "deserialized to this collection."
163
- ),
164
- )
165
- )
166
- elif (
167
- immediate_parent["language"]["default"]["name"] != name
168
- and immediate_parent["type"] == "object"
169
- ):
170
- base_models.append(id(immediate_parent))
171
-
172
- # checking to see if this is a polymorphic class
173
- subtype_map = None
174
- if yaml_data.get("discriminator"):
175
- subtype_map = {}
176
- # map of discriminator value to child's name
177
- for children_yaml in yaml_data["discriminator"]["immediate"].values():
178
- subtype_map[children_yaml["discriminatorValue"]] = children_yaml[
179
- "language"
180
- ]["python"]["name"]
181
- if yaml_data.get("properties"):
182
- properties += [
183
- Property.from_yaml(
184
- p, code_model, has_additional_properties=len(properties) > 0
185
- )
186
- for p in yaml_data["properties"]
187
- ]
188
- # this is to ensure that the attribute map type and property type are generated correctly
189
-
190
- description = yaml_data["language"]["python"]["description"]
191
- is_exception = False
192
- if code_model.exception_ids:
193
- if id(yaml_data) in code_model.exception_ids:
194
- is_exception = True
195
-
196
- self.yaml_data = yaml_data
197
- self.name = name
198
- self.description = description
199
- self.properties = properties
200
- self.base_models = base_models
201
- self.is_exception = is_exception
202
- self.subtype_map = subtype_map
203
- self.discriminator_name = (
204
- yaml_data["discriminator"]["property"]["language"]["python"]["name"]
205
- if yaml_data.get("discriminator")
206
- else None
207
- )
208
- self.discriminator_value = yaml_data.get("discriminatorValue", None)
209
-
210
- @property
211
- def has_readonly_or_constant_property(self) -> bool:
212
- return any(x.readonly or x.constant for x in self.properties)
213
-
214
- @property
215
- def property_with_discriminator(self) -> Any:
216
- try:
217
- return next(
218
- p
219
- for p in self.properties
220
- if getattr(p.schema, "discriminator_name", None)
221
- )
222
- except StopIteration:
223
- return None
224
-
225
- def imports(self) -> FileImport:
226
- file_import = FileImport()
227
- if self.is_exception:
228
- file_import.add_submodule_import(
229
- "azure.core.exceptions", "HttpResponseError", ImportType.AZURECORE
230
- )
231
- return file_import
232
-
233
- def model_file_imports(self) -> FileImport:
234
- file_import = self.imports()
235
- file_import.add_import(
236
- "__init__",
237
- ImportType.LOCAL,
238
- typing_section=TypingSection.TYPING,
239
- alias="_models",
240
- )
241
- return file_import
242
-
243
-
244
- class HiddenModelObjectSchema(ObjectSchema):
245
- @property
246
- def serialization_type(self) -> str:
247
- return "object"
248
-
249
- def type_annotation(
250
- self, *, is_operation_file: bool = False # pylint: disable=unused-argument
251
- ) -> str:
252
- if self.xml_metadata:
253
- return "ET.Element"
254
- return "JSON"
255
-
256
- @property
257
- def docstring_type(self) -> str:
258
- if self.xml_metadata:
259
- return "ET.Element"
260
- return "JSON"
261
-
262
- @property
263
- def docstring_text(self) -> str:
264
- if self.xml_metadata:
265
- return "XML Element"
266
- return "JSON object"
267
-
268
- def imports(self) -> FileImport:
269
- file_import = FileImport()
270
- file_import.add_submodule_import(
271
- "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
272
- )
273
- if self.xml_metadata:
274
- file_import.add_submodule_import(
275
- "xml.etree", "ElementTree", ImportType.STDLIB, alias="ET"
276
- )
277
- file_import.add_import("sys", ImportType.STDLIB)
278
- file_import.define_mypy_type(
279
- "JSON",
280
- "MutableMapping[str, Any] # pylint: disable=unsubscriptable-object",
281
- None,
282
- {
283
- (3, 9): ImportModel(
284
- TypingSection.CONDITIONAL,
285
- ImportType.STDLIB,
286
- "collections.abc",
287
- submodule_name="MutableMapping",
288
- ),
289
- None: ImportModel(
290
- TypingSection.CONDITIONAL,
291
- ImportType.STDLIB,
292
- "typing",
293
- submodule_name="MutableMapping",
294
- ),
295
- },
296
- )
297
- return file_import
298
-
299
-
300
- def get_object_schema(code_model) -> Type[ObjectSchema]:
301
- if code_model.options["models_mode"]:
302
- return ObjectSchema
303
- return HiddenModelObjectSchema