@autorest/python 5.19.0 → 6.0.1

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 (52) hide show
  1. package/ChangeLog.md +61 -2
  2. package/README.md +9 -0
  3. package/autorest/__init__.py +54 -13
  4. package/autorest/black/__init__.py +14 -8
  5. package/autorest/codegen/__init__.py +126 -89
  6. package/autorest/codegen/models/base_builder.py +17 -6
  7. package/autorest/codegen/models/client.py +1 -1
  8. package/autorest/codegen/models/code_model.py +7 -12
  9. package/autorest/codegen/models/lro_operation.py +2 -6
  10. package/autorest/codegen/models/lro_paging_operation.py +3 -9
  11. package/autorest/codegen/models/model_type.py +1 -6
  12. package/autorest/codegen/models/operation.py +6 -37
  13. package/autorest/codegen/models/operation_group.py +4 -7
  14. package/autorest/codegen/models/paging_operation.py +17 -7
  15. package/autorest/codegen/models/parameter.py +3 -7
  16. package/autorest/codegen/models/parameter_list.py +20 -36
  17. package/autorest/codegen/models/request_builder.py +0 -22
  18. package/autorest/codegen/serializers/__init__.py +46 -98
  19. package/autorest/codegen/serializers/builder_serializer.py +53 -36
  20. package/autorest/codegen/serializers/client_serializer.py +20 -31
  21. package/autorest/codegen/serializers/general_serializer.py +2 -7
  22. package/autorest/codegen/serializers/import_serializer.py +11 -22
  23. package/autorest/codegen/serializers/metadata_serializer.py +0 -2
  24. package/autorest/codegen/serializers/{model_base_serializer.py → model_serializer.py} +47 -38
  25. package/autorest/codegen/serializers/operation_groups_serializer.py +0 -7
  26. package/autorest/codegen/serializers/operations_init_serializer.py +2 -23
  27. package/autorest/codegen/serializers/patch_serializer.py +1 -3
  28. package/autorest/codegen/serializers/request_builders_serializer.py +1 -4
  29. package/autorest/codegen/serializers/utils.py +1 -4
  30. package/autorest/codegen/templates/client.py.jinja2 +3 -3
  31. package/autorest/codegen/templates/config.py.jinja2 +2 -2
  32. package/autorest/codegen/templates/metadata.json.jinja2 +4 -4
  33. package/autorest/codegen/templates/model_init.py.jinja2 +5 -12
  34. package/autorest/codegen/templates/operation_group.py.jinja2 +1 -1
  35. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +0 -6
  36. package/autorest/codegen/templates/patch.py.jinja2 +1 -2
  37. package/autorest/codegen/templates/request_builders.py.jinja2 +0 -3
  38. package/autorest/codegen/templates/rest_init.py.jinja2 +3 -8
  39. package/autorest/codegen/templates/serialization.py.jinja2 +3 -3
  40. package/autorest/codegen/templates/setup.py.jinja2 +1 -1
  41. package/autorest/jsonrpc/server.py +7 -7
  42. package/autorest/m2r/__init__.py +7 -2
  43. package/autorest/m4reformatter/__init__.py +13 -5
  44. package/autorest/multiapi/__init__.py +56 -29
  45. package/autorest/multiapi/serializers/__init__.py +26 -31
  46. package/autorest/multiapi/serializers/import_serializer.py +4 -8
  47. package/autorest/multiapi/serializers/multiapi_serializer.py +33 -26
  48. package/autorest/postprocess/__init__.py +14 -11
  49. package/autorest/preprocess/__init__.py +36 -7
  50. package/package.json +2 -2
  51. package/autorest/codegen/serializers/model_generic_serializer.py +0 -32
  52. package/autorest/codegen/serializers/model_python3_serializer.py +0 -72
@@ -3,7 +3,7 @@
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 Tuple
6
+ from typing import Tuple, Any, Dict
7
7
  from pathlib import Path
8
8
  import os
9
9
  import shutil
@@ -11,7 +11,7 @@ from venv import EnvBuilder
11
11
  import black
12
12
  from .venvtools import ExtendedEnvBuilder, python_run
13
13
 
14
- from .. import Plugin
14
+ from .. import Plugin, PluginAutorest
15
15
 
16
16
  _BLACK_MODE = black.Mode()
17
17
  _BLACK_MODE.line_length = 120
@@ -29,10 +29,10 @@ def format_file(file: Path, file_content: str) -> str:
29
29
  return file_content
30
30
 
31
31
 
32
- class PostProcessPlugin(Plugin):
33
- def __init__(self, autorestapi):
34
- super().__init__(autorestapi)
35
- output_folder_uri = self._autorestapi.get_value("outputFolderUri")
32
+ class PostProcessPlugin(Plugin): # pylint: disable=abstract-method
33
+ def __init__(self, **kwargs: Any):
34
+ super().__init__(**kwargs)
35
+ output_folder_uri = self.options["outputFolderUri"]
36
36
  if output_folder_uri.startswith("file:"):
37
37
  output_folder_uri = output_folder_uri[5:]
38
38
  if os.name == "nt" and output_folder_uri.startswith("///"):
@@ -65,9 +65,7 @@ class PostProcessPlugin(Plugin):
65
65
  try:
66
66
  init_file = next(d for d in dir.iterdir() if d.name == "__init__.py")
67
67
  # we don't care about pkgutil inits, we skip over them
68
- file_content = self._autorestapi.read_file(
69
- init_file.relative_to(self.output_folder)
70
- )
68
+ file_content = self.read_file(init_file.relative_to(self.output_folder))
71
69
  if not "pkgutil" in file_content:
72
70
  return dir, namespace
73
71
  except StopIteration:
@@ -157,7 +155,7 @@ class PostProcessPlugin(Plugin):
157
155
  k: None for k in customized_objects_str.split(",")
158
156
  }.keys() # filter out duplicates
159
157
  file = (folder_path / "__init__.py").relative_to(self.output_folder)
160
- file_content = self._autorestapi.read_file(file)
158
+ file_content = self.read_file(file)
161
159
  added_objs = []
162
160
  for obj in customized_objects:
163
161
  if f" import {obj}\n" in file_content:
@@ -199,4 +197,9 @@ class PostProcessPlugin(Plugin):
199
197
  "__all__ = [", f"__all__ = [\n{added_objs_all}", 1
200
198
  )
201
199
  formatted_file = format_file(file, file_content)
202
- self._autorestapi.write_file(file, formatted_file)
200
+ self.write_file(file, formatted_file)
201
+
202
+
203
+ class PostProcessPluginAutorest(PostProcessPlugin, PluginAutorest):
204
+ def get_options(self) -> Dict[str, Any]:
205
+ return {"outputFolderUri": self._autorestapi.get_value("outputFolderUri")}
@@ -9,7 +9,17 @@ from typing import Callable, Dict, Any, List, Optional
9
9
  from .helpers import to_snake_case, pad_reserved_words, add_redefined_builtin_info
10
10
  from .python_mappings import PadType
11
11
 
12
- from .. import YamlUpdatePlugin
12
+ from .. import YamlUpdatePlugin, PluginAutorest
13
+
14
+
15
+ def _remove_paging_maxpagesize(yaml_data: Dict[str, Any]) -> None:
16
+ # we don't expose maxpagesize for version tolerant generation
17
+ # users should be passing this into `by_page`
18
+ yaml_data["parameters"] = [
19
+ p
20
+ for p in yaml_data.get("parameters", [])
21
+ if p["restApiName"].lower() not in ["maxpagesize", "$maxpagesize"]
22
+ ]
13
23
 
14
24
 
15
25
  def update_description(
@@ -82,9 +92,13 @@ def update_paging_response(yaml_data: Dict[str, Any]) -> None:
82
92
  )
83
93
 
84
94
 
85
- class PreProcessPlugin(YamlUpdatePlugin):
95
+ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
86
96
  """Add Python naming information."""
87
97
 
98
+ @property
99
+ def version_tolerant(self) -> bool:
100
+ return self.options.get("version-tolerant", True)
101
+
88
102
  def get_operation_updater(
89
103
  self, yaml_data: Dict[str, Any]
90
104
  ) -> Callable[[Dict[str, Any]], None]:
@@ -119,7 +133,7 @@ class PreProcessPlugin(YamlUpdatePlugin):
119
133
  response["discriminator"] = "operation"
120
134
 
121
135
  def _update_lro_operation_helper(self, yaml_data: Dict[str, Any]) -> None:
122
- azure_arm = self._autorestapi.get_boolean_value("azure-arm", False)
136
+ azure_arm = self.options.get("azure-arm", False)
123
137
  for response in yaml_data.get("responses", []):
124
138
  response["discriminator"] = "lro"
125
139
  response["pollerSync"] = (
@@ -144,13 +158,16 @@ class PreProcessPlugin(YamlUpdatePlugin):
144
158
  def update_lro_paging_operation(self, yaml_data: Dict[str, Any]) -> None:
145
159
  self.update_lro_operation(yaml_data)
146
160
  self.update_paging_operation(yaml_data)
161
+ yaml_data["discriminator"] = "lropaging"
147
162
  for response in yaml_data.get("responses", []):
148
163
  response["discriminator"] = "lropaging"
164
+ for overload in yaml_data.get("overloads", []):
165
+ self.update_lro_paging_operation(overload)
149
166
 
150
167
  def update_lro_operation(self, yaml_data: Dict[str, Any]) -> None:
151
168
  self.update_operation(yaml_data)
152
169
  self._update_lro_operation_helper(yaml_data)
153
- for overload in yaml_data["overloads"]:
170
+ for overload in yaml_data.get("overloads", []):
154
171
  self._update_lro_operation_helper(overload)
155
172
 
156
173
  def update_paging_operation(self, yaml_data: Dict[str, Any]) -> None:
@@ -164,15 +181,18 @@ class PreProcessPlugin(YamlUpdatePlugin):
164
181
  if yaml_data.get("nextOperation")
165
182
  else yaml_data["responses"][0]
166
183
  )
167
- # if we're in version tolerant, hide the paging model
168
- if self._autorestapi.get_boolean_value("version-tolerant"):
184
+ if self.version_tolerant:
185
+ # if we're in version tolerant, hide the paging model
169
186
  returned_response_object["type"]["isPublic"] = False
187
+ _remove_paging_maxpagesize(yaml_data)
170
188
  item_type = next(
171
189
  p["type"]["elementType"]
172
190
  for p in returned_response_object["type"]["properties"]
173
- if p["restApiName"] == yaml_data["itemName"]
191
+ if p["restApiName"] == (yaml_data.get("itemName") or "value")
174
192
  )
175
193
  if yaml_data.get("nextOperation"):
194
+ if self.version_tolerant:
195
+ _remove_paging_maxpagesize(yaml_data["nextOperation"])
176
196
  yaml_data["nextOperation"]["groupName"] = pad_reserved_words(
177
197
  yaml_data["nextOperation"]["groupName"], PadType.OPERATION_GROUP
178
198
  )
@@ -208,3 +228,12 @@ class PreProcessPlugin(YamlUpdatePlugin):
208
228
  update_client(yaml_data["client"])
209
229
  update_types(yaml_data["types"])
210
230
  self.update_operation_groups(yaml_data)
231
+
232
+
233
+ class PreProcessPluginAutorest(PluginAutorest, PreProcessPlugin):
234
+ def get_options(self) -> Dict[str, Any]:
235
+ options = {
236
+ "version-tolerant": self._autorestapi.get_boolean_value("version-tolerant"),
237
+ "azure-arm": self._autorestapi.get_boolean_value("azure-arm"),
238
+ }
239
+ return {k: v for k, v in options.items() if v is not None}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "5.19.0",
3
+ "version": "6.0.1",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "scripts": {
6
6
  "prepare": "node run-python3.js prepare.py",
@@ -27,7 +27,7 @@
27
27
  "@autorest/system-requirements": "~1.0.0"
28
28
  },
29
29
  "devDependencies": {
30
- "@microsoft.azure/autorest.testserver": "^3.3.28"
30
+ "@microsoft.azure/autorest.testserver": "^3.3.31"
31
31
  },
32
32
  "files": [
33
33
  "autorest/**/*.py",
@@ -1,32 +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 List
7
- from jinja2 import Environment
8
- from .model_base_serializer import ModelBaseSerializer
9
- from ..models import ModelType, CodeModel, Property
10
-
11
-
12
- class ModelGenericSerializer(ModelBaseSerializer):
13
- def __init__(self, code_model: CodeModel, env: Environment) -> None:
14
- super().__init__(code_model=code_model, env=env, is_python3_file=False)
15
-
16
- def init_line(self, model: ModelType) -> List[str]:
17
- return []
18
-
19
- def properties_to_pass_to_super(self, model: ModelType) -> str:
20
- return "**kwargs"
21
-
22
- def required_property_no_default_init(self, prop: Property) -> str:
23
- return f"self.{prop.client_name} = kwargs['{prop.client_name}']"
24
-
25
- def optional_property_init(self, prop: Property) -> str:
26
- return f"self.{prop.client_name} = kwargs.get('{prop.client_name}', {prop.client_default_value_declaration})"
27
-
28
- def initialize_standard_arg(self, prop: Property) -> str:
29
- return self.initialize_standard_property(prop)
30
-
31
- def super_call_template(self, model: ModelType) -> str:
32
- return "super(" + model.name + ", self).__init__({})"
@@ -1,72 +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 List
7
- from jinja2 import Environment
8
- from .model_base_serializer import ModelBaseSerializer
9
- from ..models import ModelType, CodeModel, Property
10
- from ..models.imports import FileImport
11
-
12
-
13
- class ModelPython3Serializer(ModelBaseSerializer):
14
- def __init__(self, code_model: CodeModel, env: Environment) -> None:
15
- super().__init__(code_model=code_model, env=env, is_python3_file=True)
16
-
17
- def init_line(self, model: ModelType) -> List[str]:
18
- init_properties_declaration = []
19
- init_line_parameters = [
20
- p
21
- for p in model.properties
22
- if not p.readonly and not p.is_discriminator and not p.constant
23
- ]
24
- init_line_parameters.sort(key=lambda x: x.optional)
25
- if init_line_parameters:
26
- init_properties_declaration.append("*,")
27
- for param in init_line_parameters:
28
- init_properties_declaration.append(self.initialize_standard_property(param))
29
-
30
- return init_properties_declaration
31
-
32
- def properties_to_pass_to_super(self, model: ModelType) -> str:
33
- properties_to_pass_to_super = []
34
- for parent in model.parents:
35
- for prop in model.properties:
36
- if (
37
- prop in parent.properties
38
- and not prop.is_discriminator
39
- and not prop.constant
40
- and not prop.readonly
41
- ):
42
- properties_to_pass_to_super.append(
43
- f"{prop.client_name}={prop.client_name}"
44
- )
45
- properties_to_pass_to_super.append("**kwargs")
46
- return ", ".join(properties_to_pass_to_super)
47
-
48
- def required_property_no_default_init(self, prop: Property) -> str:
49
- return f"{prop.client_name}: {prop.type_annotation()},{prop.pylint_disable}"
50
-
51
- def optional_property_init(self, prop: Property) -> str:
52
- return (
53
- f"{prop.client_name}: {prop.type_annotation()} = "
54
- f"{prop.client_default_value_declaration},{prop.pylint_disable}"
55
- )
56
-
57
- def initialize_standard_arg(self, prop: Property) -> str:
58
- return f"self.{prop.client_name} = {prop.client_name}"
59
-
60
- def super_call_template(self, model: ModelType) -> str:
61
- return "super().__init__({})"
62
-
63
- def imports(self) -> FileImport:
64
- file_import = super(ModelPython3Serializer, self).imports()
65
- for model in self.code_model.model_types:
66
- init_line_parameters = [
67
- p for p in model.properties if not p.readonly and not p.is_discriminator
68
- ]
69
- for param in init_line_parameters:
70
- file_import.merge(param.imports())
71
-
72
- return file_import