@autorest/python 5.16.0 → 5.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/ChangeLog.md +43 -3
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +1 -1
  4. package/autorest/codegen/__init__.py +48 -209
  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} +56 -40
  9. package/autorest/codegen/models/client.py +157 -48
  10. package/autorest/codegen/models/code_model.py +108 -254
  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_schema.py → dictionary_type.py} +41 -31
  15. package/autorest/codegen/models/enum_type.py +195 -0
  16. package/autorest/codegen/models/imports.py +23 -0
  17. package/autorest/codegen/models/list_type.py +134 -0
  18. package/autorest/codegen/models/lro_operation.py +77 -156
  19. package/autorest/codegen/models/lro_paging_operation.py +28 -11
  20. package/autorest/codegen/models/model_type.py +239 -0
  21. package/autorest/codegen/models/operation.py +303 -269
  22. package/autorest/codegen/models/operation_group.py +48 -89
  23. package/autorest/codegen/models/paging_operation.py +80 -123
  24. package/autorest/codegen/models/parameter.py +289 -396
  25. package/autorest/codegen/models/parameter_list.py +348 -360
  26. package/autorest/codegen/models/primitive_types.py +544 -0
  27. package/autorest/codegen/models/property.py +109 -139
  28. package/autorest/codegen/models/request_builder.py +105 -88
  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 +46 -37
  33. package/autorest/codegen/serializers/builder_serializer.py +604 -1146
  34. package/autorest/codegen/serializers/client_serializer.py +83 -88
  35. package/autorest/codegen/serializers/general_serializer.py +5 -64
  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 +40 -32
  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 +4 -13
  43. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  44. package/autorest/codegen/serializers/request_builders_serializer.py +12 -29
  45. package/autorest/codegen/serializers/utils.py +0 -142
  46. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  47. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -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 +7 -7
  60. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  61. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  62. package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
  63. package/autorest/codegen/templates/request_builder.py.jinja2 +13 -11
  64. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  65. package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
  66. package/autorest/jsonrpc/server.py +15 -3
  67. package/autorest/m4reformatter/__init__.py +1108 -0
  68. package/autorest/multiapi/models/code_model.py +1 -1
  69. package/autorest/multiapi/serializers/__init__.py +4 -4
  70. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  71. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  72. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +3 -3
  73. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  74. package/autorest/postprocess/__init__.py +202 -0
  75. package/autorest/postprocess/get_all.py +19 -0
  76. package/autorest/postprocess/venvtools.py +73 -0
  77. package/autorest/preprocess/__init__.py +209 -0
  78. package/autorest/preprocess/helpers.py +54 -0
  79. package/autorest/{namer → preprocess}/python_mappings.py +21 -16
  80. package/package.json +2 -2
  81. package/autorest/codegen/models/credential_model.py +0 -55
  82. package/autorest/codegen/models/credential_schema.py +0 -95
  83. package/autorest/codegen/models/credential_schema_policy.py +0 -73
  84. package/autorest/codegen/models/enum_schema.py +0 -225
  85. package/autorest/codegen/models/list_schema.py +0 -135
  86. package/autorest/codegen/models/object_schema.py +0 -303
  87. package/autorest/codegen/models/primitive_schemas.py +0 -495
  88. package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
  89. package/autorest/codegen/models/schema_request.py +0 -55
  90. package/autorest/codegen/models/schema_response.py +0 -141
  91. package/autorest/namer/__init__.py +0 -23
  92. package/autorest/namer/name_converter.py +0 -509
@@ -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