@autorest/python 5.15.0 → 5.18.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 (118) hide show
  1. package/ChangeLog.md +98 -4
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +2 -3
  4. package/autorest/black/__init__.py +12 -5
  5. package/autorest/codegen/__init__.py +122 -211
  6. package/autorest/codegen/models/__init__.py +122 -78
  7. package/autorest/codegen/models/base_builder.py +70 -72
  8. package/autorest/codegen/models/base_model.py +7 -5
  9. package/autorest/codegen/models/{base_schema.py → base_type.py} +68 -45
  10. package/autorest/codegen/models/client.py +193 -40
  11. package/autorest/codegen/models/code_model.py +145 -245
  12. package/autorest/codegen/models/combined_type.py +107 -0
  13. package/autorest/codegen/models/constant_type.py +122 -0
  14. package/autorest/codegen/models/credential_types.py +224 -0
  15. package/autorest/codegen/models/dictionary_type.py +131 -0
  16. package/autorest/codegen/models/enum_type.py +195 -0
  17. package/autorest/codegen/models/imports.py +93 -41
  18. package/autorest/codegen/models/list_type.py +149 -0
  19. package/autorest/codegen/models/lro_operation.py +90 -133
  20. package/autorest/codegen/models/lro_paging_operation.py +28 -12
  21. package/autorest/codegen/models/model_type.py +262 -0
  22. package/autorest/codegen/models/operation.py +412 -259
  23. package/autorest/codegen/models/operation_group.py +80 -91
  24. package/autorest/codegen/models/paging_operation.py +101 -117
  25. package/autorest/codegen/models/parameter.py +302 -341
  26. package/autorest/codegen/models/parameter_list.py +373 -357
  27. package/autorest/codegen/models/primitive_types.py +544 -0
  28. package/autorest/codegen/models/property.py +136 -134
  29. package/autorest/codegen/models/request_builder.py +138 -86
  30. package/autorest/codegen/models/request_builder_parameter.py +122 -86
  31. package/autorest/codegen/models/response.py +325 -0
  32. package/autorest/codegen/models/utils.py +13 -17
  33. package/autorest/codegen/serializers/__init__.py +212 -112
  34. package/autorest/codegen/serializers/builder_serializer.py +931 -1040
  35. package/autorest/codegen/serializers/client_serializer.py +140 -84
  36. package/autorest/codegen/serializers/general_serializer.py +26 -50
  37. package/autorest/codegen/serializers/import_serializer.py +96 -31
  38. package/autorest/codegen/serializers/metadata_serializer.py +39 -79
  39. package/autorest/codegen/serializers/model_base_serializer.py +62 -34
  40. package/autorest/codegen/serializers/model_generic_serializer.py +9 -10
  41. package/autorest/codegen/serializers/model_init_serializer.py +4 -2
  42. package/autorest/codegen/serializers/model_python3_serializer.py +29 -22
  43. package/autorest/codegen/serializers/operation_groups_serializer.py +21 -19
  44. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  45. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  46. package/autorest/codegen/serializers/patch_serializer.py +4 -1
  47. package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
  48. package/autorest/codegen/serializers/utils.py +0 -126
  49. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  50. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
  51. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  52. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  53. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  54. package/autorest/codegen/templates/init.py.jinja2 +3 -3
  55. package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
  56. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
  57. package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
  58. package/autorest/codegen/templates/model.py.jinja2 +23 -24
  59. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  60. package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
  61. package/autorest/codegen/templates/operation.py.jinja2 +10 -14
  62. package/autorest/codegen/templates/operation_group.py.jinja2 +9 -15
  63. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  64. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  65. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  66. package/autorest/codegen/templates/request_builder.py.jinja2 +19 -10
  67. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  68. package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
  69. package/autorest/jsonrpc/__init__.py +7 -12
  70. package/autorest/jsonrpc/localapi.py +4 -3
  71. package/autorest/jsonrpc/server.py +28 -9
  72. package/autorest/jsonrpc/stdstream.py +13 -6
  73. package/autorest/m2r/__init__.py +5 -8
  74. package/autorest/m4reformatter/__init__.py +1126 -0
  75. package/autorest/multiapi/__init__.py +24 -14
  76. package/autorest/multiapi/models/client.py +21 -11
  77. package/autorest/multiapi/models/code_model.py +23 -10
  78. package/autorest/multiapi/models/config.py +4 -1
  79. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  80. package/autorest/multiapi/models/global_parameter.py +2 -1
  81. package/autorest/multiapi/models/global_parameters.py +14 -8
  82. package/autorest/multiapi/models/imports.py +24 -17
  83. package/autorest/multiapi/models/mixin_operation.py +5 -5
  84. package/autorest/multiapi/models/operation_group.py +2 -1
  85. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  86. package/autorest/multiapi/serializers/__init__.py +20 -25
  87. package/autorest/multiapi/serializers/import_serializer.py +47 -17
  88. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  89. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  90. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  91. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  92. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  93. package/autorest/multiapi/utils.py +3 -3
  94. package/autorest/postprocess/__init__.py +202 -0
  95. package/autorest/postprocess/get_all.py +19 -0
  96. package/autorest/postprocess/venvtools.py +73 -0
  97. package/autorest/preprocess/__init__.py +210 -0
  98. package/autorest/preprocess/helpers.py +54 -0
  99. package/autorest/{namer → preprocess}/python_mappings.py +25 -32
  100. package/package.json +3 -3
  101. package/run-python3.js +2 -3
  102. package/venvtools.py +1 -1
  103. package/autorest/codegen/models/constant_schema.py +0 -101
  104. package/autorest/codegen/models/credential_model.py +0 -47
  105. package/autorest/codegen/models/credential_schema.py +0 -91
  106. package/autorest/codegen/models/credential_schema_policy.py +0 -77
  107. package/autorest/codegen/models/dictionary_schema.py +0 -103
  108. package/autorest/codegen/models/enum_schema.py +0 -215
  109. package/autorest/codegen/models/list_schema.py +0 -123
  110. package/autorest/codegen/models/object_schema.py +0 -253
  111. package/autorest/codegen/models/primitive_schemas.py +0 -466
  112. package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
  113. package/autorest/codegen/models/rest.py +0 -42
  114. package/autorest/codegen/models/schema_request.py +0 -45
  115. package/autorest/codegen/models/schema_response.py +0 -136
  116. package/autorest/codegen/serializers/rest_serializer.py +0 -57
  117. package/autorest/namer/__init__.py +0 -25
  118. package/autorest/namer/name_converter.py +0 -412
@@ -3,22 +3,38 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
+ from typing import Any
6
7
  from .imports import FileImport
7
- from .lro_operation import LROOperation
8
- from .paging_operation import PagingOperation
8
+ from .lro_operation import LROOperationBase
9
+ from .paging_operation import PagingOperationBase
10
+ from .response import LROPagingResponse, Response
9
11
 
10
- class LROPagingOperation(PagingOperation, LROOperation):
11
12
 
12
- def imports(self, async_mode: bool, is_python3_file: bool) -> FileImport:
13
- lro_imports = LROOperation.imports(self, async_mode, is_python3_file)
14
- paging_imports = PagingOperation.imports(self, async_mode, is_python3_file)
13
+ class LROPagingOperation(
14
+ LROOperationBase[LROPagingResponse], PagingOperationBase[LROPagingResponse]
15
+ ):
16
+ @property
17
+ def success_status_codes(self):
18
+ """The list of all successfull status code."""
19
+ return [200]
20
+
21
+ @property
22
+ def operation_type(self) -> str:
23
+ return "lropaging"
24
+
25
+ def cls_type_annotation(self, *, async_mode: bool) -> str:
26
+ return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode)}]" # pylint: disable=no-member
27
+
28
+ def imports(
29
+ self, async_mode: bool, is_python3_file: bool, **kwargs: Any
30
+ ) -> FileImport:
31
+ lro_imports = LROOperationBase.imports(
32
+ self, async_mode, is_python3_file, **kwargs
33
+ )
34
+ paging_imports = PagingOperationBase.imports(
35
+ self, async_mode, is_python3_file, **kwargs
36
+ )
15
37
 
16
38
  file_import = lro_imports
17
39
  file_import.merge(paging_imports)
18
40
  return file_import
19
-
20
- @property
21
- def success_status_code(self):
22
- """The list of all successfull status code.
23
- """
24
- return [200]
@@ -0,0 +1,262 @@
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, TYPE_CHECKING, cast
7
+
8
+ from autorest.codegen.models.utils import add_to_pylint_disable
9
+ from .base_type import BaseType
10
+ from .property import Property
11
+ from .imports import FileImport, ImportType, TypingSection
12
+
13
+ if TYPE_CHECKING:
14
+ from .code_model import CodeModel
15
+
16
+
17
+ def _get_properties(type: "ModelType", properties: List[Property]) -> List[Property]:
18
+ for parent in type.parents:
19
+ # here we're adding the properties from our parents
20
+
21
+ # need to make sure that the properties we choose from our parent also don't contain
22
+ # any of our own properties
23
+ property_names = set(
24
+ [p.client_name for p in properties]
25
+ + [p.client_name for p in type.properties]
26
+ )
27
+ chosen_parent_properties = [
28
+ p for p in parent.properties if p.client_name not in property_names
29
+ ]
30
+ properties = _get_properties(parent, chosen_parent_properties) + properties
31
+ return properties
32
+
33
+
34
+ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes
35
+ """Represents a class ready to be serialized in Python.
36
+
37
+ :param str name: The name of the class.
38
+ :param str description: The description of the class.
39
+ :param properties: the optional properties of the class.
40
+ :type properties: dict(str, str)
41
+ """
42
+
43
+ def __init__(
44
+ self,
45
+ yaml_data: Dict[str, Any],
46
+ code_model: "CodeModel",
47
+ *,
48
+ properties: Optional[List[Property]] = None,
49
+ parents: Optional[List["ModelType"]] = None,
50
+ discriminated_subtypes: Optional[Dict[str, "ModelType"]] = None,
51
+ ) -> None:
52
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
53
+ self.name: str = self.yaml_data["name"]
54
+ self.max_properties: Optional[int] = self.yaml_data.get("maxProperties")
55
+ self.min_properties: Optional[int] = self.yaml_data.get("minProperties")
56
+ self.properties = properties or []
57
+ self.parents = parents or []
58
+ self.discriminated_subtypes = discriminated_subtypes or {}
59
+ self.discriminator_value: Optional[str] = self.yaml_data.get(
60
+ "discriminatorValue"
61
+ )
62
+ self._created_json_template_representation = False
63
+ self.is_public: bool = self.yaml_data.get("isPublic", True)
64
+ self.snake_case_name: str = self.yaml_data["snakeCaseName"]
65
+
66
+ @property
67
+ def is_xml(self) -> bool:
68
+ return self.yaml_data.get("isXml", False)
69
+
70
+ @property
71
+ def serialization_type(self) -> str:
72
+ if self.code_model.options["models_mode"]:
73
+ return self.name
74
+ return "object"
75
+
76
+ def type_annotation(self, **kwargs: Any) -> str:
77
+ if self.code_model.options["models_mode"]:
78
+ is_operation_file = kwargs.pop("is_operation_file", False)
79
+ if self.is_public:
80
+ retval = f"_models.{self.name}"
81
+ return retval if is_operation_file else f'"{retval}"'
82
+ return self.name if is_operation_file else f'"{self.name}"'
83
+ return "ET.Element" if self.is_xml else "JSON"
84
+
85
+ def docstring_type(self, **kwargs: Any) -> str:
86
+ if self.code_model.options["models_mode"]:
87
+ return f"~{self.code_model.namespace}.models.{self.name}"
88
+ return "ET.Element" if self.is_xml else "JSON"
89
+
90
+ def description(self, *, is_operation_file: bool = False) -> str:
91
+ return "" if is_operation_file else self.yaml_data.get("description", self.name)
92
+
93
+ def docstring_text(self, **kwargs: Any) -> str:
94
+ if self.code_model.options["models_mode"]:
95
+ return self.name
96
+ return "XML Element" if self.is_xml else "JSON object"
97
+
98
+ def get_declaration(self, value: Any) -> str:
99
+ return f"{self.name}()"
100
+
101
+ def __repr__(self) -> str:
102
+ return f"<{self.__class__.__name__} {self.name}>"
103
+
104
+ @property
105
+ def xml_serialization_ctxt(self) -> Optional[str]:
106
+ # object schema contains _xml_map, they don't need serialization context
107
+ return ""
108
+
109
+ @property
110
+ def xml_map_content(self) -> Optional[str]:
111
+ # This is NOT an error on the super call, we use the serialization context for "xml_map",
112
+ # but we don't want to write a serialization context for an object.
113
+ return super().xml_serialization_ctxt
114
+
115
+ @property
116
+ def discriminated_subtypes_name_mapping(self) -> Dict[str, str]:
117
+ return {k: v.name for k, v in self.discriminated_subtypes.items()}
118
+
119
+ def get_json_template_representation(
120
+ self,
121
+ *,
122
+ optional: bool = True,
123
+ client_default_value_declaration: Optional[str] = None,
124
+ description: Optional[str] = None,
125
+ ) -> Any:
126
+ if self._created_json_template_representation:
127
+ return "..." # do this to avoid loop
128
+ self._created_json_template_representation = True
129
+ if self.discriminated_subtypes:
130
+ # we will instead print the discriminated subtypes
131
+ self._created_json_template_representation = False
132
+ return self.snake_case_name
133
+
134
+ # don't add additional properties, because there's not really a concept of
135
+ # additional properties in the template
136
+ representation = {
137
+ f'"{prop.rest_api_name}"': prop.get_json_template_representation(
138
+ optional=optional,
139
+ client_default_value_declaration=client_default_value_declaration,
140
+ description=description,
141
+ )
142
+ for prop in [
143
+ p
144
+ for p in self.properties
145
+ if not (p.is_discriminator or p.client_name == "additional_properties")
146
+ ]
147
+ }
148
+ if self.discriminator and self.discriminator_value:
149
+ representation[
150
+ f'"{self.discriminator.rest_api_name}"'
151
+ ] = f'"{self.discriminator_value}"'
152
+
153
+ # once we've finished, we want to reset created_json_template_representation to false
154
+ # so we can call it again
155
+ self._created_json_template_representation = False
156
+ return representation
157
+
158
+ def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
159
+ is_polymorphic_subtype = (
160
+ self.discriminator_value and not self.discriminated_subtypes
161
+ )
162
+ if (
163
+ self.name not in (m.name for m in polymorphic_subtypes)
164
+ and is_polymorphic_subtype
165
+ ):
166
+ polymorphic_subtypes.append(self)
167
+ for discriminated_subtype in self.discriminated_subtypes.values():
168
+ discriminated_subtype.get_polymorphic_subtypes(polymorphic_subtypes)
169
+ for property in self.properties:
170
+ property.get_polymorphic_subtypes(polymorphic_subtypes)
171
+
172
+ @classmethod
173
+ def from_yaml(
174
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
175
+ ) -> "ModelType":
176
+ raise ValueError(
177
+ "You shouldn't call from_yaml for ModelType to avoid recursion. "
178
+ "Please initial a blank ModelType, then call .fill_instance_from_yaml on the created type."
179
+ )
180
+
181
+ def fill_instance_from_yaml(
182
+ self, yaml_data: Dict[str, Any], code_model: "CodeModel"
183
+ ) -> None:
184
+ from . import build_type
185
+
186
+ self.parents = [
187
+ cast(ModelType, build_type(bm, code_model))
188
+ for bm in yaml_data.get("parents", [])
189
+ ]
190
+ properties = [
191
+ Property.from_yaml(p, code_model) for p in yaml_data["properties"]
192
+ ]
193
+ self.properties = _get_properties(self, properties)
194
+ # checking to see if this is a polymorphic class
195
+ self.discriminated_subtypes = {
196
+ k: cast(ModelType, build_type(v, code_model))
197
+ for k, v in self.yaml_data.get("discriminatedSubtypes", {}).items()
198
+ }
199
+
200
+ @property
201
+ def has_readonly_or_constant_property(self) -> bool:
202
+ return any(x.readonly or x.constant for x in self.properties)
203
+
204
+ @property
205
+ def discriminator(self) -> Optional[Property]:
206
+ try:
207
+ return next(p for p in self.properties if p.is_discriminator)
208
+ except StopIteration:
209
+ return None
210
+
211
+ @property
212
+ def instance_check_template(self) -> str:
213
+ if self.code_model.options["models_mode"]:
214
+ return "isinstance({}, msrest.Model)"
215
+ return "isinstance({}, MutableMapping)"
216
+
217
+ @property
218
+ def pylint_disable(self) -> str:
219
+ retval: str = ""
220
+ if len(self.properties) > 10:
221
+ retval = add_to_pylint_disable(retval, "too-many-instance-attributes")
222
+ return retval
223
+
224
+ @property
225
+ def init_pylint_disable(self) -> str:
226
+ retval: str = ""
227
+ if len(self.properties) > 23:
228
+ retval = add_to_pylint_disable(retval, "too-many-locals")
229
+ return retval
230
+
231
+ def imports(self, **kwargs: Any) -> FileImport:
232
+ file_import = FileImport()
233
+ relative_path = kwargs.pop("relative_path", None)
234
+ if self.code_model.options["models_mode"] and relative_path:
235
+ # add import for models in operations file
236
+ if self.is_public:
237
+ file_import.add_submodule_import(
238
+ relative_path, "models", ImportType.LOCAL, alias="_models"
239
+ )
240
+ else:
241
+ # a little hacky, but we only do this for version tolerant
242
+ # models files, which are all python3 only
243
+ models_filename = self.code_model.get_models_filename(
244
+ is_python3_file=True
245
+ )
246
+ file_import.add_submodule_import(
247
+ f"{relative_path}models.{models_filename}",
248
+ self.name,
249
+ ImportType.LOCAL,
250
+ )
251
+ if self.code_model.options["models_mode"]:
252
+ return file_import
253
+ file_import.add_submodule_import(
254
+ "typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL
255
+ )
256
+ file_import.add_import("sys", ImportType.STDLIB)
257
+ file_import.define_mutable_mapping_type()
258
+ if self.is_xml:
259
+ file_import.add_submodule_import(
260
+ "xml.etree", "ElementTree", ImportType.STDLIB, alias="ET"
261
+ )
262
+ return file_import