@autorest/python 6.0.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.
package/ChangeLog.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Release History
2
2
 
3
+ ### 2022-06-29 - 6.0.1
4
+
5
+ | Library | Min Version |
6
+ | ----------------------------------------------------------------------- | ----------- |
7
+ | `@autorest/core` | `3.8.1` |
8
+ | `@autorest/modelerfour` | `4.23.5` |
9
+ | `azure-core` dep of generated code | `1.24.0` |
10
+ | `isodate` dep of generated code | `0.6.1` |
11
+ | `msrest` dep of generated code (If generating legacy code) | `0.7.1` |
12
+ | `azure-mgmt-core` dep of generated code (If generating mgmt plane code) | `1.3.0` |
13
+
14
+ **Bug Fixes**
15
+
16
+ - Ignore linting error for clients with no credentials #1333
17
+
3
18
  ### 2022-06-24 - 6.0.0
4
19
 
5
20
  | Library | Min Version |
@@ -4,8 +4,9 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  import logging
7
+ from pathlib import Path
7
8
  from abc import ABC, abstractmethod
8
- from typing import Any, Dict
9
+ from typing import Any, Dict, Union
9
10
 
10
11
  import yaml
11
12
 
@@ -17,14 +18,40 @@ __version__ = VERSION
17
18
  _LOGGER = logging.getLogger(__name__)
18
19
 
19
20
 
20
- class Plugin(ABC):
21
+ class ReaderAndWriter:
22
+ def __init__(self, **kwargs: Any) -> None:
23
+ pass
24
+
25
+ def read_file(self, path: Union[str, Path]) -> str:
26
+ """How does one read a file in cadl?"""
27
+ raise NotImplementedError("Haven't plugged in Cadl yet")
28
+
29
+ def write_file(self, filename: Union[str, Path], file_content: str) -> None:
30
+ """How does writing work in cadl?"""
31
+ raise NotImplementedError("Haven't plugged in Cadl yet")
32
+
33
+
34
+ class ReaderAndWriterAutorest(ReaderAndWriter):
35
+ def __init__(self, *, autorestapi: AutorestAPI) -> None:
36
+ super().__init__()
37
+ self._autorestapi = autorestapi
38
+
39
+ def read_file(self, path: Union[str, Path]) -> str:
40
+ return self._autorestapi.read_file(path)
41
+
42
+ def write_file(self, filename: Union[str, Path], file_content: str) -> None:
43
+ return self._autorestapi.write_file(filename, file_content)
44
+
45
+
46
+ class Plugin(ReaderAndWriter, ABC):
21
47
  """A base class for autorest plugin.
22
48
 
23
49
  :param autorestapi: An autorest API instance
24
50
  """
25
51
 
26
- def __init__(self, autorestapi: AutorestAPI) -> None:
27
- self._autorestapi = autorestapi
52
+ def __init__(self, **kwargs: Any) -> None:
53
+ super().__init__(**kwargs)
54
+ self.options: Dict[str, Any] = {}
28
55
 
29
56
  @abstractmethod
30
57
  def process(self) -> bool:
@@ -37,24 +64,30 @@ class Plugin(ABC):
37
64
  raise NotImplementedError()
38
65
 
39
66
 
67
+ class PluginAutorest(Plugin, ReaderAndWriterAutorest):
68
+ """For our Autorest plugins, we want to take autorest api as input as options, then pass it to the Plugin"""
69
+
70
+ def __init__(self, autorestapi: AutorestAPI) -> None:
71
+ super().__init__(autorestapi=autorestapi)
72
+ self.options = self.get_options()
73
+
74
+ @abstractmethod
75
+ def get_options(self) -> Dict[str, Any]:
76
+ """Get the options bag using the AutorestAPI that we send to the parent plugin"""
77
+
78
+
40
79
  class YamlUpdatePlugin(Plugin):
41
80
  """A plugin that update the YAML as input."""
42
81
 
43
82
  def process(self) -> bool:
44
83
  # List the input file, should be only one
45
- inputs = self._autorestapi.list_inputs()
46
- _LOGGER.debug("Possible Inputs: %s", inputs)
47
- if "code-model-v4-no-tags.yaml" not in inputs:
48
- raise ValueError("code-model-v4-no-tags.yaml must be a possible input")
49
-
50
- file_content = self._autorestapi.read_file("code-model-v4-no-tags.yaml")
51
- yaml_data = yaml.safe_load(file_content)
84
+ yaml_data = yaml.safe_load(self.read_file("code-model-v4-no-tags.yaml"))
52
85
 
53
86
  self.update_yaml(yaml_data)
54
87
 
55
88
  yaml_string = yaml.safe_dump(yaml_data)
56
89
 
57
- self._autorestapi.write_file("code-model-v4-no-tags.yaml", yaml_string)
90
+ self.write_file("code-model-v4-no-tags.yaml", yaml_string)
58
91
  return True
59
92
 
60
93
  @abstractmethod
@@ -67,4 +100,12 @@ class YamlUpdatePlugin(Plugin):
67
100
  raise NotImplementedError()
68
101
 
69
102
 
70
- __all__ = ["Plugin", "YamlUpdatePlugin"]
103
+ class YamlUpdatePluginAutorest( # pylint: disable=abstract-method
104
+ YamlUpdatePlugin, PluginAutorest
105
+ ):
106
+ def get_options(self) -> Dict[str, Any]:
107
+ inputs = self._autorestapi.list_inputs()
108
+ _LOGGER.debug("Possible Inputs: %s", inputs)
109
+ if "code-model-v4-no-tags.yaml" not in inputs:
110
+ raise ValueError("code-model-v4-no-tags.yaml must be a possible input")
111
+ return {}
@@ -6,9 +6,10 @@
6
6
  import logging
7
7
  from pathlib import Path
8
8
  import os
9
+ from typing import Any, Dict
9
10
  import black
10
11
 
11
- from .. import Plugin
12
+ from .. import Plugin, PluginAutorest
12
13
 
13
14
  _LOGGER = logging.getLogger(__name__)
14
15
 
@@ -16,10 +17,10 @@ _BLACK_MODE = black.Mode()
16
17
  _BLACK_MODE.line_length = 120
17
18
 
18
19
 
19
- class BlackScriptPlugin(Plugin):
20
- def __init__(self, autorestapi):
21
- super().__init__(autorestapi)
22
- output_folder_uri = self._autorestapi.get_value("outputFolderUri")
20
+ class BlackScriptPlugin(Plugin): # pylint: disable=abstract-method
21
+ def __init__(self, **kwargs):
22
+ super().__init__(**kwargs)
23
+ output_folder_uri = self.options["outputFolderUri"]
23
24
  if output_folder_uri.startswith("file:"):
24
25
  output_folder_uri = output_folder_uri[5:]
25
26
  if os.name == "nt" and output_folder_uri.startswith("///"):
@@ -38,9 +39,9 @@ class BlackScriptPlugin(Plugin):
38
39
 
39
40
  def format_file(self, full_path) -> None:
40
41
  file = full_path.relative_to(self.output_folder)
41
- file_content = self._autorestapi.read_file(file)
42
+ file_content = self.read_file(file)
42
43
  if not file.suffix == ".py":
43
- self._autorestapi.write_file(file, file_content)
44
+ self.write_file(file, file_content)
44
45
  return
45
46
  try:
46
47
  file_content = black.format_file_contents(
@@ -48,4 +49,9 @@ class BlackScriptPlugin(Plugin):
48
49
  )
49
50
  except black.NothingChanged:
50
51
  pass
51
- self._autorestapi.write_file(file, file_content)
52
+ self.write_file(file, file_content)
53
+
54
+
55
+ class BlackScriptPluginAutorest(BlackScriptPlugin, PluginAutorest):
56
+ def get_options(self) -> Dict[str, Any]:
57
+ return {"outputFolderUri": self._autorestapi.get_value("outputFolderUri")}
@@ -10,13 +10,13 @@ from pathlib import Path
10
10
  import yaml
11
11
 
12
12
 
13
- from .. import Plugin
13
+ from .. import Plugin, PluginAutorest
14
14
  from .models.client import Client, Config
15
15
  from .models.code_model import CodeModel
16
16
  from .models import build_type
17
17
  from .models.request_builder import get_request_builder
18
18
  from .models.operation_group import OperationGroup
19
- from .serializers import JinjaSerializer
19
+ from .serializers import JinjaSerializer, JinjaSerializerAutorest
20
20
 
21
21
 
22
22
  def _build_convenience_layer(yaml_data: Dict[str, Any], code_model: CodeModel) -> None:
@@ -162,8 +162,8 @@ class CodeGenerator(Plugin):
162
162
 
163
163
  def _build_code_model_options(self) -> Dict[str, Any]:
164
164
  """Build en options dict from the user input while running autorest."""
165
- azure_arm = self._autorestapi.get_boolean_value("azure-arm", False)
166
- license_header = self._autorestapi.get_value("header-text")
165
+ azure_arm = self.options.get("azure-arm", False)
166
+ license_header = self.options["header-text"]
167
167
  if license_header:
168
168
  license_header = license_header.replace("\n", "\n# ")
169
169
  license_header = (
@@ -172,83 +172,46 @@ class CodeGenerator(Plugin):
172
172
  )
173
173
  license_header += "\n# --------------------------------------------------------------------------"
174
174
 
175
- low_level_client = cast(
176
- bool, self._autorestapi.get_boolean_value("low-level-client", False)
177
- )
178
- version_tolerant = cast(
179
- bool, self._autorestapi.get_boolean_value("version-tolerant")
180
- )
181
- show_operations = self._autorestapi.get_boolean_value(
182
- "show-operations", not low_level_client
183
- )
175
+ low_level_client = cast(bool, self.options.get("low-level-client", False))
176
+ version_tolerant = cast(bool, self.options.get("version-tolerant", True))
177
+ show_operations = self.options.get("show-operations", not low_level_client)
184
178
  models_mode_default = (
185
179
  "none" if low_level_client or version_tolerant else "msrest"
186
180
  )
187
- if self._autorestapi.get_boolean_value("python3-only") is False:
188
- _LOGGER.warning(
189
- "You have passed in --python3-only=False. We have force overriden "
190
- "this to True."
191
- )
192
- if self._autorestapi.get_boolean_value("add-python3-operation-files"):
193
- _LOGGER.warning(
194
- "You have passed in --add-python3-operation-files. "
195
- "This flag no longer has an effect bc all SDKs are now Python3 only."
196
- )
197
- if self._autorestapi.get_boolean_value("reformat-next-link"):
198
- _LOGGER.warning(
199
- "You have passed in --reformat-next-link. We have force overriden "
200
- "this to False because we no longer reformat initial query parameters into next "
201
- "calls unless explicitly defined in the service definition."
202
- )
203
181
 
204
182
  options: Dict[str, Any] = {
205
183
  "azure_arm": azure_arm,
206
- "head_as_boolean": self._autorestapi.get_boolean_value(
207
- "head-as-boolean", False
208
- ),
184
+ "head_as_boolean": self.options.get("head-as-boolean", True),
209
185
  "license_header": license_header,
210
- "keep_version_file": self._autorestapi.get_boolean_value(
211
- "keep-version-file", False
212
- ),
213
- "no_async": self._autorestapi.get_boolean_value("no-async", False),
214
- "no_namespace_folders": self._autorestapi.get_boolean_value(
215
- "no-namespace-folders", False
216
- ),
217
- "basic_setup_py": self._autorestapi.get_boolean_value(
218
- "basic-setup-py", False
219
- ),
220
- "package_name": self._autorestapi.get_value("package-name"),
221
- "package_version": self._autorestapi.get_value("package-version"),
222
- "client_side_validation": self._autorestapi.get_boolean_value(
223
- "client-side-validation", False
224
- ),
225
- "tracing": self._autorestapi.get_boolean_value("trace", show_operations),
226
- "multiapi": self._autorestapi.get_boolean_value("multiapi", False),
227
- "polymorphic_examples": self._autorestapi.get_value("polymorphic-examples")
228
- or 5,
229
- "models_mode": (
230
- self._autorestapi.get_value("models-mode") or models_mode_default
231
- ).lower(),
232
- "builders_visibility": self._autorestapi.get_value("builders-visibility"),
186
+ "keep_version_file": self.options.get("keep-version-file", False),
187
+ "no_async": self.options.get("no-async", False),
188
+ "no_namespace_folders": self.options.get("no-namespace-folders", False),
189
+ "basic_setup_py": self.options.get("basic-setup-py", False),
190
+ "package_name": self.options.get("package-name"),
191
+ "package_version": self.options.get("package-version"),
192
+ "client_side_validation": self.options.get("client-side-validation", False),
193
+ "tracing": self.options.get("tracing", show_operations),
194
+ "multiapi": self.options.get("multiapi", False),
195
+ "polymorphic_examples": self.options.get("polymorphic-examples", 5),
196
+ "models_mode": self.options.get("models-mode", models_mode_default).lower(),
197
+ "builders_visibility": self.options.get("builders-visibility"),
233
198
  "show_operations": show_operations,
234
- "show_send_request": self._autorestapi.get_boolean_value(
199
+ "show_send_request": self.options.get(
235
200
  "show-send-request", low_level_client or version_tolerant
236
201
  ),
237
- "only_path_and_body_params_positional": self._autorestapi.get_boolean_value(
202
+ "only_path_and_body_params_positional": self.options.get(
238
203
  "only-path-and-body-params-positional",
239
204
  low_level_client or version_tolerant,
240
205
  ),
241
206
  "version_tolerant": version_tolerant,
242
207
  "low_level_client": low_level_client,
243
- "combine_operation_files": self._autorestapi.get_boolean_value(
208
+ "combine_operation_files": self.options.get(
244
209
  "combine-operation-files", version_tolerant
245
210
  ),
246
- "package_mode": self._autorestapi.get_value("package-mode"),
247
- "package_pprint_name": self._autorestapi.get_value("package-pprint-name"),
248
- "package_configuration": self._autorestapi.get_value(
249
- "package-configuration"
250
- ),
251
- "default_optional_constants_to_none": self._autorestapi.get_boolean_value(
211
+ "package_mode": self.options.get("package-mode"),
212
+ "package_pprint_name": self.options.get("package-pprint-name"),
213
+ "package_configuration": self.options.get("package-configuration"),
214
+ "default_optional_constants_to_none": self.options.get(
252
215
  "default-optional-constants-to-none",
253
216
  low_level_client or version_tolerant,
254
217
  ),
@@ -272,8 +235,102 @@ class CodeGenerator(Plugin):
272
235
  options["head_as_boolean"] = True
273
236
  return options
274
237
 
238
+ def get_yaml(self) -> Dict[str, Any]:
239
+ # cadl should call this one
240
+ raise NotImplementedError()
241
+
242
+ @staticmethod
243
+ def get_serializer(code_model: CodeModel):
244
+ return JinjaSerializer(code_model)
245
+
275
246
  def process(self) -> bool:
276
247
  # List the input file, should be only one
248
+
249
+ options = self._build_code_model_options()
250
+ yaml_data = self.get_yaml()
251
+
252
+ if options["azure_arm"]:
253
+ self.remove_cloud_errors(yaml_data)
254
+
255
+ code_model = self._create_code_model(yaml_data=yaml_data, options=options)
256
+
257
+ serializer = self.get_serializer(code_model)
258
+ serializer.serialize()
259
+
260
+ return True
261
+
262
+
263
+ class CodeGeneratorAutorest(CodeGenerator, PluginAutorest):
264
+ def get_options(self) -> Dict[str, Any]:
265
+ if self._autorestapi.get_boolean_value("python3-only") is False:
266
+ _LOGGER.warning(
267
+ "You have passed in --python3-only=False. We have force overriden "
268
+ "this to True."
269
+ )
270
+ if self._autorestapi.get_boolean_value("add-python3-operation-files"):
271
+ _LOGGER.warning(
272
+ "You have passed in --add-python3-operation-files. "
273
+ "This flag no longer has an effect bc all SDKs are now Python3 only."
274
+ )
275
+ if self._autorestapi.get_boolean_value("reformat-next-link"):
276
+ _LOGGER.warning(
277
+ "You have passed in --reformat-next-link. We have force overriden "
278
+ "this to False because we no longer reformat initial query parameters into next "
279
+ "calls unless explicitly defined in the service definition."
280
+ )
281
+ options = {
282
+ "azure-arm": self._autorestapi.get_boolean_value("azure-arm"),
283
+ "header-text": self._autorestapi.get_value("header-text"),
284
+ "low-level-client": self._autorestapi.get_boolean_value(
285
+ "low-level-client", False
286
+ ),
287
+ "version-tolerant": self._autorestapi.get_boolean_value(
288
+ "version-tolerant", True
289
+ ),
290
+ "show-operations": self._autorestapi.get_boolean_value("show-operations"),
291
+ "python3-only": self._autorestapi.get_boolean_value("python3-only"),
292
+ "head-as-boolean": self._autorestapi.get_boolean_value(
293
+ "head-as-boolean", False
294
+ ),
295
+ "keep-version-file": self._autorestapi.get_boolean_value(
296
+ "keep-version-file"
297
+ ),
298
+ "no-async": self._autorestapi.get_boolean_value("no-async"),
299
+ "no-namespace-folders": self._autorestapi.get_boolean_value(
300
+ "no-namespace-folders"
301
+ ),
302
+ "basic-setup-py": self._autorestapi.get_boolean_value("basic-setup-py"),
303
+ "package-name": self._autorestapi.get_value("package-name"),
304
+ "package-version": self._autorestapi.get_value("package-version"),
305
+ "client-side-validation": self._autorestapi.get_boolean_value(
306
+ "client-side-validation"
307
+ ),
308
+ "tracing": self._autorestapi.get_boolean_value("trace"),
309
+ "multiapi": self._autorestapi.get_boolean_value("multiapi", False),
310
+ "polymorphic-examples": self._autorestapi.get_value("polymorphic-examples"),
311
+ "models-mode": self._autorestapi.get_value("models-mode"),
312
+ "builders-visibility": self._autorestapi.get_value("builders-visibility"),
313
+ "show-send-request": self._autorestapi.get_boolean_value(
314
+ "show-send-request"
315
+ ),
316
+ "only-path-and-body-params-positional": self._autorestapi.get_boolean_value(
317
+ "only-path-and-body-params-positional"
318
+ ),
319
+ "combine-operation-files": self._autorestapi.get_boolean_value(
320
+ "combine-operation-files"
321
+ ),
322
+ "package-mode": self._autorestapi.get_value("package-mode"),
323
+ "package-pprint-name": self._autorestapi.get_value("package-pprint-name"),
324
+ "package-configuration": self._autorestapi.get_value(
325
+ "package-configuration"
326
+ ),
327
+ "default-optional-constants-to-none": self._autorestapi.get_boolean_value(
328
+ "default-optional-constants-to-none"
329
+ ),
330
+ }
331
+ return {k: v for k, v in options.items() if v is not None}
332
+
333
+ def get_yaml(self) -> Dict[str, Any]:
277
334
  inputs = self._autorestapi.list_inputs()
278
335
  _LOGGER.debug("Possible Inputs: %s", inputs)
279
336
  if "code-model-v4-no-tags.yaml" not in inputs:
@@ -291,19 +348,10 @@ class CodeGenerator(Plugin):
291
348
  file_content = self._autorestapi.read_file("code-model-v4-no-tags.yaml")
292
349
 
293
350
  # Parse the received YAML
294
- yaml_data = yaml.safe_load(file_content)
351
+ return yaml.safe_load(file_content)
295
352
 
296
- options = self._build_code_model_options()
297
-
298
- if options["azure_arm"]:
299
- self.remove_cloud_errors(yaml_data)
300
-
301
- code_model = self._create_code_model(yaml_data=yaml_data, options=options)
302
-
303
- serializer = JinjaSerializer(self._autorestapi, code_model)
304
- serializer.serialize()
305
-
306
- return True
353
+ def get_serializer(self, code_model: CodeModel): # type: ignore
354
+ return JinjaSerializerAutorest(self._autorestapi, code_model)
307
355
 
308
356
 
309
357
  def main(yaml_model_file: str) -> None:
@@ -311,7 +359,7 @@ def main(yaml_model_file: str) -> None:
311
359
  LocalAutorestAPI,
312
360
  )
313
361
 
314
- code_generator = CodeGenerator(
362
+ code_generator = CodeGeneratorAutorest(
315
363
  autorestapi=LocalAutorestAPI(reachable_files=[yaml_model_file])
316
364
  )
317
365
  if not code_generator.process():
@@ -9,6 +9,7 @@ from jinja2 import PackageLoader, Environment, FileSystemLoader, StrictUndefined
9
9
  from autorest.codegen.models.operation_group import OperationGroup
10
10
  from autorest.codegen.models.request_builder import OverloadedRequestBuilder
11
11
 
12
+ from ... import ReaderAndWriter, ReaderAndWriterAutorest
12
13
  from ...jsonrpc import AutorestAPI
13
14
  from ..models import CodeModel, OperationGroup, RequestBuilder
14
15
  from ..models import TokenCredentialType
@@ -38,9 +39,9 @@ _PACKAGE_FILES = [
38
39
  _REGENERATE_FILES = {"setup.py", "MANIFEST.in"}
39
40
 
40
41
 
41
- class JinjaSerializer:
42
- def __init__(self, autorestapi: AutorestAPI, code_model: CodeModel) -> None:
43
- self._autorestapi = autorestapi
42
+ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
43
+ def __init__(self, code_model: CodeModel, **kwargs: Any) -> None:
44
+ super().__init__(**kwargs)
44
45
  self.code_model = code_model
45
46
 
46
47
  @property
@@ -129,10 +130,10 @@ class JinjaSerializer:
129
130
  )
130
131
  if not self.code_model.options["models_mode"]:
131
132
  # keep models file if users ended up just writing a models file
132
- if self._autorestapi.read_file(namespace_path / Path("models.py")):
133
- self._autorestapi.write_file(
133
+ if self.read_file(namespace_path / Path("models.py")):
134
+ self.write_file(
134
135
  namespace_path / Path("models.py"),
135
- self._autorestapi.read_file(namespace_path / Path("models.py")),
136
+ self.read_file(namespace_path / Path("models.py")),
136
137
  )
137
138
 
138
139
  if self.code_model.options["package_mode"]:
@@ -143,13 +144,10 @@ class JinjaSerializer:
143
144
  for template_name in package_files:
144
145
  file = template_name.replace(".jinja2", "")
145
146
  output_name = out_path / file
146
- if (
147
- not self._autorestapi.read_file(output_name)
148
- or file in _REGENERATE_FILES
149
- ):
147
+ if not self.read_file(output_name) or file in _REGENERATE_FILES:
150
148
  template = env.get_template(template_name)
151
149
  render_result = template.render(**kwargs)
152
- self._autorestapi.write_file(output_name, render_result)
150
+ self.write_file(output_name, render_result)
153
151
 
154
152
  def _prepare_params() -> Dict[Any, Any]:
155
153
  package_parts = package_name.split("-")[:-1]
@@ -207,12 +205,10 @@ class JinjaSerializer:
207
205
  _serialize_and_write_package_files_proc(**params)
208
206
 
209
207
  def _keep_patch_file(self, path_file: Path, env: Environment):
210
- if self._autorestapi.read_file(path_file):
211
- self._autorestapi.write_file(
212
- path_file, self._autorestapi.read_file(path_file)
213
- )
208
+ if self.read_file(path_file):
209
+ self.write_file(path_file, self.read_file(path_file))
214
210
  else:
215
- self._autorestapi.write_file(
211
+ self.write_file(
216
212
  path_file,
217
213
  PatchSerializer(env=env, code_model=self.code_model).serialize(),
218
214
  )
@@ -223,16 +219,16 @@ class JinjaSerializer:
223
219
  # Write the models folder
224
220
  models_path = namespace_path / Path("models")
225
221
  if self.code_model.model_types:
226
- self._autorestapi.write_file(
222
+ self.write_file(
227
223
  models_path / Path(f"{self.code_model.models_filename}.py"),
228
224
  ModelSerializer(code_model=self.code_model, env=env).serialize(),
229
225
  )
230
226
  if self.code_model.enums:
231
- self._autorestapi.write_file(
227
+ self.write_file(
232
228
  models_path / Path(f"{self.code_model.enums_filename}.py"),
233
229
  EnumSerializer(code_model=self.code_model, env=env).serialize(),
234
230
  )
235
- self._autorestapi.write_file(
231
+ self.write_file(
236
232
  models_path / Path("__init__.py"),
237
233
  ModelInitSerializer(code_model=self.code_model, env=env).serialize(),
238
234
  )
@@ -253,7 +249,7 @@ class JinjaSerializer:
253
249
  env, rest_path, request_builders
254
250
  )
255
251
  if not "" in group_names:
256
- self._autorestapi.write_file(
252
+ self.write_file(
257
253
  rest_path / Path("__init__.py"),
258
254
  self.code_model.options["license_header"],
259
255
  )
@@ -267,7 +263,7 @@ class JinjaSerializer:
267
263
  group_name = request_builders[0].group_name
268
264
  output_path = rest_path / Path(group_name) if group_name else rest_path
269
265
  # write generic request builders file
270
- self._autorestapi.write_file(
266
+ self.write_file(
271
267
  output_path / Path("_request_builders.py"),
272
268
  RequestBuildersSerializer(
273
269
  code_model=self.code_model,
@@ -277,7 +273,7 @@ class JinjaSerializer:
277
273
  )
278
274
 
279
275
  # write rest init file
280
- self._autorestapi.write_file(
276
+ self.write_file(
281
277
  output_path / Path("__init__.py"),
282
278
  RequestBuildersSerializer(
283
279
  code_model=self.code_model,
@@ -300,7 +296,7 @@ class JinjaSerializer:
300
296
  async_mode=False,
301
297
  operation_group=operation_group,
302
298
  )
303
- self._autorestapi.write_file(
299
+ self.write_file(
304
300
  namespace_path
305
301
  / Path(self.code_model.operations_folder_name)
306
302
  / Path(f"{filename}.py"),
@@ -315,7 +311,7 @@ class JinjaSerializer:
315
311
  async_mode=True,
316
312
  operation_group=operation_group,
317
313
  )
318
- self._autorestapi.write_file(
314
+ self.write_file(
319
315
  (
320
316
  namespace_path
321
317
  / Path("aio")
@@ -332,7 +328,7 @@ class JinjaSerializer:
332
328
  operations_init_serializer = OperationsInitSerializer(
333
329
  code_model=self.code_model, env=env, async_mode=False
334
330
  )
335
- self._autorestapi.write_file(
331
+ self.write_file(
336
332
  namespace_path
337
333
  / Path(self.code_model.operations_folder_name)
338
334
  / Path("__init__.py"),
@@ -344,7 +340,7 @@ class JinjaSerializer:
344
340
  operations_async_init_serializer = OperationsInitSerializer(
345
341
  code_model=self.code_model, env=env, async_mode=True
346
342
  )
347
- self._autorestapi.write_file(
343
+ self.write_file(
348
344
  namespace_path
349
345
  / Path("aio")
350
346
  / Path(self.code_model.operations_folder_name)
@@ -369,12 +365,10 @@ class JinjaSerializer:
369
365
  self, namespace_path: Path, general_serializer: GeneralSerializer
370
366
  ):
371
367
  def _read_version_file(original_version_file_name: str) -> str:
372
- return self._autorestapi.read_file(
373
- namespace_path / original_version_file_name
374
- )
368
+ return self.read_file(namespace_path / original_version_file_name)
375
369
 
376
370
  def _write_version_file(original_version_file_name: str) -> None:
377
- self._autorestapi.write_file(
371
+ self.write_file(
378
372
  namespace_path / Path("_version.py"),
379
373
  _read_version_file(original_version_file_name),
380
374
  )
@@ -385,7 +379,7 @@ class JinjaSerializer:
385
379
  elif keep_version_file and _read_version_file("version.py"):
386
380
  _write_version_file(original_version_file_name="version.py")
387
381
  elif self.code_model.options["package_version"]:
388
- self._autorestapi.write_file(
382
+ self.write_file(
389
383
  namespace_path / Path("_version.py"),
390
384
  general_serializer.serialize_version_file(),
391
385
  )
@@ -397,14 +391,14 @@ class JinjaSerializer:
397
391
  code_model=self.code_model, env=env, async_mode=False
398
392
  )
399
393
 
400
- self._autorestapi.write_file(
394
+ self.write_file(
401
395
  namespace_path / Path("__init__.py"),
402
396
  general_serializer.serialize_init_file(),
403
397
  )
404
398
  p = namespace_path.parent
405
399
  while p != Path("."):
406
400
  # write pkgutil init file
407
- self._autorestapi.write_file(
401
+ self.write_file(
408
402
  p / Path("__init__.py"),
409
403
  general_serializer.serialize_pkgutil_init_file(),
410
404
  )
@@ -412,13 +406,13 @@ class JinjaSerializer:
412
406
 
413
407
  # Write the service client
414
408
  if self.code_model.request_builders:
415
- self._autorestapi.write_file(
409
+ self.write_file(
416
410
  namespace_path / Path(f"{self.code_model.client.filename}.py"),
417
411
  general_serializer.serialize_service_client_file(),
418
412
  )
419
413
 
420
414
  if self.code_model.need_vendored_code(async_mode=False):
421
- self._autorestapi.write_file(
415
+ self.write_file(
422
416
  namespace_path / Path("_vendor.py"),
423
417
  general_serializer.serialize_vendor_file(),
424
418
  )
@@ -426,31 +420,27 @@ class JinjaSerializer:
426
420
  self._serialize_and_write_version_file(namespace_path, general_serializer)
427
421
 
428
422
  # write the empty py.typed file
429
- self._autorestapi.write_file(
430
- namespace_path / Path("py.typed"), "# Marker file for PEP 561."
431
- )
423
+ self.write_file(namespace_path / Path("py.typed"), "# Marker file for PEP 561.")
432
424
 
433
425
  if (
434
426
  not self.code_model.options["client_side_validation"]
435
427
  and not self.code_model.options["multiapi"]
436
428
  ):
437
- self._autorestapi.write_file(
429
+ self.write_file(
438
430
  namespace_path / Path("_serialization.py"),
439
431
  general_serializer.serialize_serialization_file(),
440
432
  )
441
433
 
442
434
  # Write the config file
443
435
  if self.code_model.request_builders:
444
- self._autorestapi.write_file(
436
+ self.write_file(
445
437
  namespace_path / Path("_configuration.py"),
446
438
  general_serializer.serialize_config_file(),
447
439
  )
448
440
 
449
441
  # Write the setup file
450
442
  if self.code_model.options["basic_setup_py"]:
451
- self._autorestapi.write_file(
452
- Path("setup.py"), general_serializer.serialize_setup_file()
453
- )
443
+ self.write_file(Path("setup.py"), general_serializer.serialize_setup_file())
454
444
 
455
445
  def _serialize_and_write_aio_top_level_folder(
456
446
  self, env: Environment, namespace_path: Path
@@ -462,24 +452,24 @@ class JinjaSerializer:
462
452
  aio_path = namespace_path / Path("aio")
463
453
 
464
454
  # Write the __init__ file
465
- self._autorestapi.write_file(
455
+ self.write_file(
466
456
  aio_path / Path("__init__.py"), aio_general_serializer.serialize_init_file()
467
457
  )
468
458
 
469
459
  # Write the service client
470
460
  if self.code_model.request_builders:
471
- self._autorestapi.write_file(
461
+ self.write_file(
472
462
  aio_path / Path(f"{self.code_model.client.filename}.py"),
473
463
  aio_general_serializer.serialize_service_client_file(),
474
464
  )
475
465
 
476
466
  # Write the config file
477
- self._autorestapi.write_file(
467
+ self.write_file(
478
468
  aio_path / Path("_configuration.py"),
479
469
  aio_general_serializer.serialize_config_file(),
480
470
  )
481
471
  if self.code_model.need_vendored_code(async_mode=True):
482
- self._autorestapi.write_file(
472
+ self.write_file(
483
473
  aio_path / Path("_vendor.py"),
484
474
  aio_general_serializer.serialize_vendor_file(),
485
475
  )
@@ -488,6 +478,11 @@ class JinjaSerializer:
488
478
  self, env: Environment, namespace_path: Path
489
479
  ) -> None:
490
480
  metadata_serializer = MetadataSerializer(self.code_model, env)
491
- self._autorestapi.write_file(
481
+ self.write_file(
492
482
  namespace_path / Path("_metadata.json"), metadata_serializer.serialize()
493
483
  )
484
+
485
+
486
+ class JinjaSerializerAutorest(JinjaSerializer, ReaderAndWriterAutorest):
487
+ def __init__(self, autorestapi: AutorestAPI, code_model: CodeModel) -> None:
488
+ super().__init__(autorestapi=autorestapi, code_model=code_model)
@@ -16,6 +16,11 @@ class ClientSerializer:
16
16
  self.parameter_serializer = ParameterSerializer()
17
17
 
18
18
  def _init_signature(self, async_mode: bool) -> str:
19
+ pylint_disable = ""
20
+ if not self.code_model.client.parameters.credential:
21
+ pylint_disable = (
22
+ " # pylint: disable=missing-client-constructor-parameter-credential"
23
+ )
19
24
  return self.parameter_serializer.serialize_method(
20
25
  function_def="def",
21
26
  method_name="__init__",
@@ -23,6 +28,7 @@ class ClientSerializer:
23
28
  method_param_signatures=self.code_model.client.parameters.method_signature(
24
29
  async_mode
25
30
  ),
31
+ pylint_disable=pylint_disable,
26
32
  )
27
33
 
28
34
  def init_signature_and_response_type_annotation(self, async_mode: bool) -> str:
@@ -43,24 +43,24 @@ def Process(plugin_name: str, session_id: str) -> bool:
43
43
  session_id,
44
44
  )
45
45
  if plugin_name == "m2r":
46
- from ..m2r import M2R as PluginToLoad
46
+ from ..m2r import M2RAutorest as PluginToLoad
47
47
  elif plugin_name == "preprocess":
48
- from ..preprocess import PreProcessPlugin as PluginToLoad # type: ignore
48
+ from ..preprocess import PreProcessPluginAutorest as PluginToLoad # type: ignore
49
49
  elif plugin_name == "m4reformatter":
50
50
  from ..m4reformatter import M4Reformatter as PluginToLoad # type: ignore
51
51
  elif plugin_name == "codegen":
52
- from ..codegen import CodeGenerator as PluginToLoad # type: ignore
52
+ from ..codegen import CodeGeneratorAutorest as PluginToLoad # type: ignore
53
53
  elif plugin_name == "postprocess":
54
- from ..postprocess import PostProcessPlugin as PluginToLoad # type: ignore
54
+ from ..postprocess import PostProcessPluginAutorest as PluginToLoad # type: ignore
55
55
  elif plugin_name == "black":
56
- from ..black import BlackScriptPlugin as PluginToLoad # type: ignore
56
+ from ..black import BlackScriptPluginAutorest as PluginToLoad # type: ignore
57
57
  elif plugin_name == "multiapiscript":
58
- from ..multiapi import MultiApiScriptPlugin as PluginToLoad # type: ignore
58
+ from ..multiapi import MultiApiScriptPluginAutorest as PluginToLoad # type: ignore
59
59
  else:
60
60
  _LOGGER.fatal("Unknown plugin name %s", plugin_name)
61
61
  raise RuntimeError(f"Unknown plugin name {plugin_name}")
62
62
 
63
- plugin = PluginToLoad(stdstream_connection)
63
+ plugin = PluginToLoad(autorestapi=stdstream_connection)
64
64
 
65
65
  try:
66
66
  _LOGGER.debug("Starting plugin %s", PluginToLoad.__name__)
@@ -10,7 +10,7 @@ from typing import Any, Dict, Set
10
10
 
11
11
  import m2r
12
12
 
13
- from .. import YamlUpdatePlugin
13
+ from .. import YamlUpdatePluginAutorest, YamlUpdatePlugin
14
14
 
15
15
 
16
16
  _LOGGER = logging.getLogger(__name__)
@@ -26,7 +26,7 @@ class AutorestRender(m2r.RestRenderer):
26
26
  return f":code:`{html}`"
27
27
 
28
28
 
29
- class M2R(YamlUpdatePlugin):
29
+ class M2R(YamlUpdatePlugin): # pylint: disable=abstract-method
30
30
  """A plugin to convert any description and summary from MD to RST."""
31
31
 
32
32
  def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
@@ -58,3 +58,8 @@ class M2R(YamlUpdatePlugin):
58
58
  return m2r.convert(string_to_convert, renderer=AutorestRender()).strip()
59
59
  except Exception: # pylint: disable=broad-except
60
60
  return string_to_convert
61
+
62
+
63
+ class M2RAutorest(YamlUpdatePluginAutorest, M2R):
64
+ def get_options(self) -> Dict[str, Any]:
65
+ return {}
@@ -11,7 +11,7 @@ import copy
11
11
  import logging
12
12
  from typing import Callable, Dict, Any, Iterable, List, Optional, Set
13
13
 
14
- from .. import YamlUpdatePlugin
14
+ from .. import YamlUpdatePluginAutorest
15
15
 
16
16
  JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
17
17
  ORIGINAL_ID_TO_UPDATED_TYPE: Dict[int, Dict[str, Any]] = {}
@@ -431,7 +431,9 @@ def update_client_url(yaml_data: Dict[str, Any]) -> str:
431
431
  ]["uri"]
432
432
 
433
433
 
434
- class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-methods
434
+ class M4Reformatter(
435
+ YamlUpdatePluginAutorest
436
+ ): # pylint: disable=too-many-public-methods
435
437
  """Add Python naming information."""
436
438
 
437
439
  @property
@@ -11,41 +11,62 @@ import shutil
11
11
  from collections import defaultdict
12
12
  from pathlib import Path
13
13
  from typing import Dict, List, Optional, cast, Any
14
- from .serializers import MultiAPISerializer
14
+
15
+ from .serializers import MultiAPISerializer, MultiAPISerializerAutorest
15
16
  from .models import CodeModel
16
17
  from .utils import _get_default_api_version_from_list
17
- from ..jsonrpc import AutorestAPI
18
18
 
19
- from .. import Plugin
19
+ from .. import Plugin, PluginAutorest, ReaderAndWriter, ReaderAndWriterAutorest
20
20
 
21
21
  _LOGGER = logging.getLogger(__name__)
22
22
 
23
23
 
24
- class MultiApiScriptPlugin(Plugin):
24
+ class MultiApiScriptPlugin(Plugin): # pylint: disable=abstract-method
25
25
  def process(self) -> bool:
26
- input_package_name: str = self._autorestapi.get_value("package-name")
27
- output_folder: str = self._autorestapi.get_value("output-folder")
28
- user_specified_default_api: str = self._autorestapi.get_value("default-api")
29
- no_async = self._autorestapi.get_boolean_value("no-async")
30
- generator = MultiAPI(
31
- input_package_name,
32
- output_folder,
33
- self._autorestapi,
34
- no_async,
35
- user_specified_default_api,
26
+ return self.generator.process()
27
+
28
+ @property
29
+ def generator(self) -> "MultiAPI":
30
+ return MultiAPI(
31
+ input_package_name=self.options.get("package-name"),
32
+ output_folder=self.options["output-folder"],
33
+ user_specified_default_api=self.options.get("default-api"),
34
+ no_async=self.options.get("no-async", False),
36
35
  )
37
- return generator.process()
38
36
 
39
37
 
40
- class MultiAPI:
38
+ class MultiApiScriptPluginAutorest(MultiApiScriptPlugin, PluginAutorest):
39
+ @property
40
+ def generator(self) -> "MultiAPI":
41
+ return MultiAPIAutorest(
42
+ autorestapi=self._autorestapi,
43
+ input_package_name=self.options.get("package-name"),
44
+ output_folder=self.options["output-folder"],
45
+ user_specified_default_api=self.options.get("default-api"),
46
+ no_async=self.options.get("no-async", False),
47
+ )
48
+
49
+ def get_options(self) -> Dict[str, Any]:
50
+ options = {
51
+ "package-name": self._autorestapi.get_value("package-name"),
52
+ "output-folder": self._autorestapi.get_value("output-folder"),
53
+ "default-api": self._autorestapi.get_value("default-api"),
54
+ "no-async": self._autorestapi.get_value("no-async"),
55
+ }
56
+ return {k: v for k, v in options.items() if v is not None}
57
+
58
+
59
+ class MultiAPI(ReaderAndWriter): # pylint: disable=abstract-method
41
60
  def __init__(
42
61
  self,
43
- input_package_name: str,
62
+ *,
63
+ input_package_name: Optional[str] = None,
44
64
  output_folder: str,
45
- autorestapi: AutorestAPI,
46
65
  no_async: Optional[bool] = False,
47
66
  user_specified_default_api: Optional[str] = None,
67
+ **kwargs: Any,
48
68
  ) -> None:
69
+ super().__init__(**kwargs)
49
70
  if input_package_name is None:
50
71
  raise ValueError(
51
72
  "package-name is required, either provide it as args or check your readme configuration"
@@ -57,7 +78,6 @@ class MultiAPI:
57
78
  _LOGGER.debug("Received output-folder %s", output_folder)
58
79
  self.output_package_name: str = ""
59
80
  self.no_async = no_async
60
- self._autorestapi = autorestapi
61
81
  self.user_specified_default_api = user_specified_default_api
62
82
 
63
83
  @property
@@ -77,9 +97,7 @@ class MultiAPI:
77
97
  if self.default_api_version.replace("-", "_") == path_to_version.stem:
78
98
  path_to_default_version = path_to_version
79
99
  break
80
- return json.loads(
81
- self._autorestapi.read_file(path_to_default_version / "_metadata.json")
82
- )
100
+ return json.loads(self.read_file(path_to_default_version / "_metadata.json"))
83
101
 
84
102
  @property
85
103
  def module_name(self) -> str:
@@ -120,9 +138,7 @@ class MultiAPI:
120
138
  @property
121
139
  def version_path_to_metadata(self) -> Dict[Path, Dict[str, Any]]:
122
140
  return {
123
- version_path: json.loads(
124
- self._autorestapi.read_file(version_path / "_metadata.json")
125
- )
141
+ version_path: json.loads(self.read_file(version_path / "_metadata.json"))
126
142
  for version_path in self.paths_to_versions
127
143
  }
128
144
 
@@ -130,9 +146,7 @@ class MultiAPI:
130
146
  def mod_to_api_version(self) -> Dict[str, str]:
131
147
  mod_to_api_version: Dict[str, str] = defaultdict(str)
132
148
  for version_path in self.paths_to_versions:
133
- metadata_json = json.loads(
134
- self._autorestapi.read_file(version_path / "_metadata.json")
135
- )
149
+ metadata_json = json.loads(self.read_file(version_path / "_metadata.json"))
136
150
  version = metadata_json["chosen_version"]
137
151
  total_api_version_list = metadata_json["total_api_version_list"]
138
152
  if not version:
@@ -145,6 +159,10 @@ class MultiAPI:
145
159
  mod_to_api_version[version_path.name] = version
146
160
  return mod_to_api_version
147
161
 
162
+ @property
163
+ def serializer(self) -> MultiAPISerializer:
164
+ return MultiAPISerializer()
165
+
148
166
  def process(self) -> bool:
149
167
  _LOGGER.info("Generating multiapi client")
150
168
 
@@ -163,8 +181,17 @@ class MultiAPI:
163
181
  shutil.rmtree(str(self.output_folder / "operations"), ignore_errors=True)
164
182
  shutil.rmtree(str(self.output_folder / "models"), ignore_errors=True)
165
183
 
166
- multiapi_serializer = MultiAPISerializer(self._autorestapi)
184
+ multiapi_serializer = self.serializer
167
185
  multiapi_serializer.serialize(code_model, self.no_async)
168
186
 
169
187
  _LOGGER.info("Done!")
170
188
  return True
189
+
190
+
191
+ class MultiAPIAutorest(MultiAPI, ReaderAndWriterAutorest):
192
+ def __init__(self, **kwargs: Any) -> None:
193
+ super().__init__(**kwargs)
194
+
195
+ @property
196
+ def serializer(self) -> MultiAPISerializer:
197
+ return MultiAPISerializerAutorest(self._autorestapi)
@@ -11,6 +11,7 @@ from .import_serializer import FileImportSerializer
11
11
 
12
12
  from ...jsonrpc import AutorestAPI
13
13
  from ..models import CodeModel
14
+ from ... import ReaderAndWriter, ReaderAndWriterAutorest
14
15
 
15
16
  __all__ = [
16
17
  "MultiAPISerializer",
@@ -32,9 +33,9 @@ def _get_file_path(filename: str, async_mode: bool) -> Path:
32
33
  return Path(filename)
33
34
 
34
35
 
35
- class MultiAPISerializer(object):
36
- def __init__(self, autorestapi: AutorestAPI) -> None:
37
- self._autorestapi = autorestapi
36
+ class MultiAPISerializer(ReaderAndWriter): # pylint: disable=abstract-method
37
+ def __init__(self, **kwargs: Any) -> None:
38
+ super().__init__(**kwargs)
38
39
  self.env = Environment(
39
40
  loader=PackageLoader("autorest.multiapi", "templates"),
40
41
  keep_trailing_newline=True,
@@ -52,20 +53,20 @@ class MultiAPISerializer(object):
52
53
  )
53
54
 
54
55
  # serialize init file
55
- self._autorestapi.write_file(
56
+ self.write_file(
56
57
  _get_file_path("__init__", async_mode), _render_template("init")
57
58
  )
58
59
 
59
60
  # serialize service client file
60
61
  imports = FileImportSerializer(code_model.client.imports(async_mode))
61
- self._autorestapi.write_file(
62
+ self.write_file(
62
63
  _get_file_path(code_model.client.filename, async_mode),
63
64
  _render_template("client", imports=imports),
64
65
  )
65
66
 
66
67
  # serialize config file
67
68
  imports = FileImportSerializer(code_model.config.imports(async_mode))
68
- self._autorestapi.write_file(
69
+ self.write_file(
69
70
  _get_file_path("_configuration", async_mode),
70
71
  _render_template("config", imports=imports),
71
72
  )
@@ -75,26 +76,22 @@ class MultiAPISerializer(object):
75
76
  imports = FileImportSerializer(
76
77
  code_model.operation_mixin_group.imports(async_mode)
77
78
  )
78
- self._autorestapi.write_file(
79
+ self.write_file(
79
80
  _get_file_path("_operations_mixin", async_mode),
80
81
  _render_template("operations_mixin", imports=imports),
81
82
  )
82
83
 
83
84
  # serialize models
84
- self._autorestapi.write_file(Path("models.py"), _render_template("models"))
85
+ self.write_file(Path("models.py"), _render_template("models"))
85
86
 
86
87
  def _serialize_version_file(self) -> None:
87
- if self._autorestapi.read_file("_version.py"):
88
- self._autorestapi.write_file(
89
- "_version.py", self._autorestapi.read_file("_version.py")
90
- )
91
- elif self._autorestapi.read_file("version.py"):
92
- self._autorestapi.write_file(
93
- "_version.py", self._autorestapi.read_file("version.py")
94
- )
88
+ if self.read_file("_version.py"):
89
+ self.write_file("_version.py", self.read_file("_version.py"))
90
+ elif self.read_file("version.py"):
91
+ self.write_file("_version.py", self.read_file("version.py"))
95
92
  else:
96
93
  template = self.env.get_template("multiapi_version.py.jinja2")
97
- self._autorestapi.write_file(Path("_version.py"), template.render())
94
+ self.write_file(Path("_version.py"), template.render())
98
95
 
99
96
  def serialize(self, code_model: CodeModel, no_async: Optional[bool]) -> None:
100
97
  self._serialize_helper(code_model, async_mode=False)
@@ -104,12 +101,10 @@ class MultiAPISerializer(object):
104
101
  self._serialize_version_file()
105
102
 
106
103
  # don't erase patch file
107
- if self._autorestapi.read_file("_patch.py"):
108
- self._autorestapi.write_file(
109
- "_patch.py", self._autorestapi.read_file("_patch.py")
110
- )
104
+ if self.read_file("_patch.py"):
105
+ self.write_file("_patch.py", self.read_file("_patch.py"))
111
106
 
112
- self._autorestapi.write_file(Path("py.typed"), "# Marker file for PEP 561.")
107
+ self.write_file(Path("py.typed"), "# Marker file for PEP 561.")
113
108
 
114
109
  if not code_model.client.client_side_validation:
115
110
  codegen_env = Environment(
@@ -120,7 +115,12 @@ class MultiAPISerializer(object):
120
115
  trim_blocks=True,
121
116
  lstrip_blocks=True,
122
117
  )
123
- self._autorestapi.write_file(
118
+ self.write_file(
124
119
  Path("_serialization.py"),
125
120
  codegen_env.get_template("serialization.py.jinja2").render(),
126
121
  )
122
+
123
+
124
+ class MultiAPISerializerAutorest(MultiAPISerializer, ReaderAndWriterAutorest):
125
+ def __init__(self, autorestapi: AutorestAPI) -> None:
126
+ super().__init__(autorestapi=autorestapi)
@@ -8,19 +8,20 @@ from pathlib import Path
8
8
  from jinja2 import Environment, PackageLoader
9
9
 
10
10
  from ...jsonrpc import AutorestAPI
11
+ from ... import ReaderAndWriter, ReaderAndWriterAutorest
11
12
 
12
13
 
13
- class MultiAPISerializer:
14
+ class MultiAPISerializer(ReaderAndWriter): # pylint: disable=abstract-method
14
15
  def __init__(
15
16
  self,
16
17
  conf: Dict[str, Any],
17
18
  async_mode: bool,
18
- autorestapi: AutorestAPI,
19
19
  service_client_filename: str,
20
+ **kwargs: Any
20
21
  ):
22
+ super().__init__(**kwargs)
21
23
  self.conf = conf
22
24
  self.async_mode = async_mode
23
- self._autorestapi = autorestapi
24
25
  self.service_client_filename = service_client_filename
25
26
  self.env = Environment(
26
27
  loader=PackageLoader("autorest.multiapi", "templates"),
@@ -37,53 +38,43 @@ class MultiAPISerializer:
37
38
  return Path(filename)
38
39
 
39
40
  def serialize(self):
40
- self._autorestapi.write_file(
41
+ self.write_file(
41
42
  self._get_file_path("__init__.py"), self.serialize_multiapi_init()
42
43
  )
43
44
 
44
45
  service_client_filename_with_py_extension = self.service_client_filename + ".py"
45
- self._autorestapi.write_file(
46
+ self.write_file(
46
47
  self._get_file_path(service_client_filename_with_py_extension),
47
48
  self.serialize_multiapi_client(),
48
49
  )
49
50
 
50
51
  configuration_filename = "_configuration.py"
51
- self._autorestapi.write_file(
52
+ self.write_file(
52
53
  self._get_file_path(configuration_filename),
53
54
  self.serialize_multiapi_config(),
54
55
  )
55
56
 
56
57
  operation_mixins_filename = "_operations_mixin.py"
57
58
  if self.conf["mixin_operations"]:
58
- self._autorestapi.write_file(
59
+ self.write_file(
59
60
  self._get_file_path(operation_mixins_filename),
60
61
  self.serialize_multiapi_operation_mixins(),
61
62
  )
62
63
 
63
- if self._autorestapi.read_file("_version.py"):
64
- self._autorestapi.write_file(
65
- "_version.py", self._autorestapi.read_file("_version.py")
66
- )
67
- elif self._autorestapi.read_file("version.py"):
68
- self._autorestapi.write_file(
69
- "_version.py", self._autorestapi.read_file("version.py")
70
- )
64
+ if self.read_file("_version.py"):
65
+ self.write_file("_version.py", self.read_file("_version.py"))
66
+ elif self.read_file("version.py"):
67
+ self.write_file("_version.py", self.read_file("version.py"))
71
68
  else:
72
- self._autorestapi.write_file(
73
- Path("_version.py"), self.serialize_multiapi_version()
74
- )
69
+ self.write_file(Path("_version.py"), self.serialize_multiapi_version())
75
70
 
76
71
  # don't erase patch file
77
- if self._autorestapi.read_file("_patch.py"):
78
- self._autorestapi.write_file(
79
- "_patch.py", self._autorestapi.read_file("_patch.py")
80
- )
72
+ if self.read_file("_patch.py"):
73
+ self.write_file("_patch.py", self.read_file("_patch.py"))
81
74
 
82
- self._autorestapi.write_file(
83
- Path("models.py"), self.serialize_multiapi_models()
84
- )
75
+ self.write_file(Path("models.py"), self.serialize_multiapi_models())
85
76
 
86
- self._autorestapi.write_file(Path("py.typed"), "# Marker file for PEP 561.")
77
+ self.write_file(Path("py.typed"), "# Marker file for PEP 561.")
87
78
 
88
79
  def serialize_multiapi_init(self) -> str:
89
80
  template = self.env.get_template("multiapi_init.py.jinja2")
@@ -112,3 +103,19 @@ class MultiAPISerializer:
112
103
  def serialize_multiapi_operation_mixins(self) -> str:
113
104
  template = self.env.get_template("multiapi_operations_mixin.py.jinja2")
114
105
  return template.render(**self.conf, async_mode=self.async_mode)
106
+
107
+
108
+ class MultiAPISerializerAutorest(MultiAPISerializer, ReaderAndWriterAutorest):
109
+ def __init__(
110
+ self,
111
+ autorestapi: AutorestAPI,
112
+ conf: Dict[str, Any],
113
+ async_mode: bool,
114
+ service_client_filename: str,
115
+ ):
116
+ super().__init__(
117
+ autorestapi=autorestapi,
118
+ conf=conf,
119
+ async_mode=async_mode,
120
+ service_client_filename=service_client_filename,
121
+ )
@@ -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,7 @@ 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
13
 
14
14
 
15
15
  def _remove_paging_maxpagesize(yaml_data: Dict[str, Any]) -> None:
@@ -92,12 +92,12 @@ def update_paging_response(yaml_data: Dict[str, Any]) -> None:
92
92
  )
93
93
 
94
94
 
95
- class PreProcessPlugin(YamlUpdatePlugin):
95
+ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
96
96
  """Add Python naming information."""
97
97
 
98
98
  @property
99
99
  def version_tolerant(self) -> bool:
100
- return bool(self._autorestapi.get_boolean_value("version-tolerant", True))
100
+ return self.options.get("version-tolerant", True)
101
101
 
102
102
  def get_operation_updater(
103
103
  self, yaml_data: Dict[str, Any]
@@ -133,7 +133,7 @@ class PreProcessPlugin(YamlUpdatePlugin):
133
133
  response["discriminator"] = "operation"
134
134
 
135
135
  def _update_lro_operation_helper(self, yaml_data: Dict[str, Any]) -> None:
136
- azure_arm = self._autorestapi.get_boolean_value("azure-arm", False)
136
+ azure_arm = self.options.get("azure-arm", False)
137
137
  for response in yaml_data.get("responses", []):
138
138
  response["discriminator"] = "lro"
139
139
  response["pollerSync"] = (
@@ -228,3 +228,12 @@ class PreProcessPlugin(YamlUpdatePlugin):
228
228
  update_client(yaml_data["client"])
229
229
  update_types(yaml_data["types"])
230
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": "6.0.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",