@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
@@ -8,18 +8,12 @@
8
8
 
9
9
  {% if code_model.options["builders_visibility"] == "embedded" and not async_mode %}
10
10
  {{ op_tools.declare_serializer(code_model, request_builders) }}
11
- {%- if not is_python3_file %}
12
- # fmt: off
13
- {% endif %}
14
11
  {% for operation_group in operation_groups %}
15
12
  {% for request_builder in request_builders | selectattr("group_name", "equalto", operation_group.property_name) | rejectattr("is_overload") %}
16
13
 
17
14
  {% include "request_builder.py.jinja2" %}
18
15
  {% endfor %}
19
16
  {% endfor %}
20
- {% if not is_python3_file %}
21
- # fmt: on
22
- {% endif %}
23
17
  {% endif %}
24
18
  {% for operation_group in operation_groups %}
25
19
  {% include "operation_group.py.jinja2" %}
@@ -8,8 +8,7 @@ Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python
8
8
  """
9
9
  {{ imports }}
10
10
 
11
- {% set type_annotation = ": List[str]" %}
12
- __all__{{ type_annotation if is_python3_file else "" }} = []{{ "" if is_python3_file else (" # type" + type_annotation) }} # Add all objects you want publicly available to users at this package level
11
+ __all__: List[str] = [] # Add all objects you want publicly available to users at this package level
13
12
 
14
13
  def patch_sdk():
15
14
  """Do not remove from this file.
@@ -4,9 +4,6 @@
4
4
  {{ imports }}
5
5
 
6
6
  {{ op_tools.declare_serializer(code_model, request_builders) }}
7
- {% if not is_python3_file %}
8
- # fmt: off
9
- {% endif %}
10
7
  {% for request_builder in request_builders %}
11
8
 
12
9
  {% include "request_builder.py.jinja2" %}
@@ -1,14 +1,9 @@
1
1
  # coding=utf-8
2
2
  {{ code_model.options['license_header'] }}
3
3
 
4
- try:
5
- {% for request_builder in request_builders %}
6
- from ._request_builders_py3 import {{ request_builder.name }}
7
- {% endfor %}
8
- except (SyntaxError, ImportError):
9
- {% for request_builder in request_builders %}
10
- from ._request_builders import {{ request_builder.name }} # type: ignore
11
- {% endfor %}
4
+ {% for request_builder in request_builders %}
5
+ from ._request_builders import {{ request_builder.name }}
6
+ {% endfor %}
12
7
 
13
8
  __all__ = [
14
9
  {% for request_builder in request_builders %}
@@ -106,7 +106,7 @@ class RawDeserializer:
106
106
  except NameError:
107
107
  pass
108
108
 
109
- return ET.fromstring(data_as_str)
109
+ return ET.fromstring(data_as_str) # nosec
110
110
  except ET.ParseError:
111
111
  # It might be because the server has an issue, and returned JSON with
112
112
  # content-type XML....
@@ -831,7 +831,7 @@ class Serializer(object):
831
831
  return custom_serializer(data)
832
832
  if data_type == 'str':
833
833
  return cls.serialize_unicode(data)
834
- return eval(data_type)(data)
834
+ return eval(data_type)(data) # nosec
835
835
 
836
836
  @classmethod
837
837
  def serialize_unicode(cls, data):
@@ -1765,7 +1765,7 @@ class Deserializer(object):
1765
1765
 
1766
1766
  if data_type == 'str':
1767
1767
  return self.deserialize_unicode(attr)
1768
- return eval(data_type)(attr)
1768
+ return eval(data_type)(attr) # nosec
1769
1769
 
1770
1770
  @staticmethod
1771
1771
  def deserialize_unicode(data):
@@ -85,7 +85,7 @@ setup(
85
85
  {% if code_model.is_legacy %}
86
86
  "{{ dependency_msrest }}",
87
87
  {% else %}
88
- "isodate>=0.6.1",
88
+ "isodate<1.0.0,>=0.6.1",
89
89
  {% endif %}
90
90
  {% if azure_arm %}
91
91
  "{{ dependency_azure_mgmt_core }}",
@@ -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
@@ -494,6 +496,13 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
494
496
  in_overriden = (
495
497
  body_parameter["type"]["type"] == "combined" if body_parameter else False
496
498
  )
499
+ abstract = False
500
+ if body_parameter and (
501
+ body_parameter.get("entries")
502
+ or len(body_parameter["type"].get("types", [])) > 2
503
+ ):
504
+ # this means it's formdata or urlencoded, or there are more than 2 types of body
505
+ abstract = True
497
506
  return {
498
507
  "name": yaml_data["language"]["default"]["name"],
499
508
  "description": yaml_data["language"]["default"]["description"],
@@ -520,6 +529,7 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
520
529
  "discriminator": "operation",
521
530
  "isOverload": is_overload,
522
531
  "apiVersions": _get_api_versions(yaml_data.get("apiVersions", [])),
532
+ "abstract": abstract,
523
533
  }
524
534
 
525
535
  def get_operation_creator(
@@ -1072,9 +1082,7 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
1072
1082
  "skipUrlEncoding": True,
1073
1083
  "inOverload": False,
1074
1084
  }
1075
- if self._autorestapi.get_boolean_value(
1076
- "version-tolerant"
1077
- ) or self._autorestapi.get_boolean_value("low-level-client"):
1085
+ if self.version_tolerant or self.low_level_client:
1078
1086
  parameters.append(credential)
1079
1087
  else:
1080
1088
  parameters.insert(0, credential)
@@ -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,24 +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
- imports = FileImportSerializer(
61
- code_model.client.imports(async_mode), is_python3_file=async_mode
62
- )
63
- self._autorestapi.write_file(
61
+ imports = FileImportSerializer(code_model.client.imports(async_mode))
62
+ self.write_file(
64
63
  _get_file_path(code_model.client.filename, async_mode),
65
64
  _render_template("client", imports=imports),
66
65
  )
67
66
 
68
67
  # serialize config file
69
- imports = FileImportSerializer(
70
- code_model.config.imports(async_mode), is_python3_file=async_mode
71
- )
72
- self._autorestapi.write_file(
68
+ imports = FileImportSerializer(code_model.config.imports(async_mode))
69
+ self.write_file(
73
70
  _get_file_path("_configuration", async_mode),
74
71
  _render_template("config", imports=imports),
75
72
  )
@@ -77,29 +74,24 @@ class MultiAPISerializer(object):
77
74
  # serialize mixins
78
75
  if code_model.operation_mixin_group.mixin_operations:
79
76
  imports = FileImportSerializer(
80
- code_model.operation_mixin_group.imports(async_mode),
81
- is_python3_file=async_mode,
77
+ code_model.operation_mixin_group.imports(async_mode)
82
78
  )
83
- self._autorestapi.write_file(
79
+ self.write_file(
84
80
  _get_file_path("_operations_mixin", async_mode),
85
81
  _render_template("operations_mixin", imports=imports),
86
82
  )
87
83
 
88
84
  # serialize models
89
- self._autorestapi.write_file(Path("models.py"), _render_template("models"))
85
+ self.write_file(Path("models.py"), _render_template("models"))
90
86
 
91
87
  def _serialize_version_file(self) -> None:
92
- if self._autorestapi.read_file("_version.py"):
93
- self._autorestapi.write_file(
94
- "_version.py", self._autorestapi.read_file("_version.py")
95
- )
96
- elif self._autorestapi.read_file("version.py"):
97
- self._autorestapi.write_file(
98
- "_version.py", self._autorestapi.read_file("version.py")
99
- )
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"))
100
92
  else:
101
93
  template = self.env.get_template("multiapi_version.py.jinja2")
102
- self._autorestapi.write_file(Path("_version.py"), template.render())
94
+ self.write_file(Path("_version.py"), template.render())
103
95
 
104
96
  def serialize(self, code_model: CodeModel, no_async: Optional[bool]) -> None:
105
97
  self._serialize_helper(code_model, async_mode=False)
@@ -109,12 +101,10 @@ class MultiAPISerializer(object):
109
101
  self._serialize_version_file()
110
102
 
111
103
  # don't erase patch file
112
- if self._autorestapi.read_file("_patch.py"):
113
- self._autorestapi.write_file(
114
- "_patch.py", self._autorestapi.read_file("_patch.py")
115
- )
104
+ if self.read_file("_patch.py"):
105
+ self.write_file("_patch.py", self.read_file("_patch.py"))
116
106
 
117
- self._autorestapi.write_file(Path("py.typed"), "# Marker file for PEP 561.")
107
+ self.write_file(Path("py.typed"), "# Marker file for PEP 561.")
118
108
 
119
109
  if not code_model.client.client_side_validation:
120
110
  codegen_env = Environment(
@@ -125,7 +115,12 @@ class MultiAPISerializer(object):
125
115
  trim_blocks=True,
126
116
  lstrip_blocks=True,
127
117
  )
128
- self._autorestapi.write_file(
118
+ self.write_file(
129
119
  Path("_serialization.py"),
130
120
  codegen_env.get_template("serialization.py.jinja2").render(),
131
121
  )
122
+
123
+
124
+ class MultiAPISerializerAutorest(MultiAPISerializer, ReaderAndWriterAutorest):
125
+ def __init__(self, autorestapi: AutorestAPI) -> None:
126
+ super().__init__(autorestapi=autorestapi)
@@ -54,9 +54,8 @@ def _get_import_clauses(
54
54
 
55
55
 
56
56
  class FileImportSerializer:
57
- def __init__(self, file_import: FileImport, is_python3_file: bool) -> None:
57
+ def __init__(self, file_import: FileImport) -> None:
58
58
  self._file_import = file_import
59
- self.is_python3_file = is_python3_file
60
59
 
61
60
  def _switch_typing_section_key(self, new_key: TypingSection):
62
61
  switched_dictionary = {}
@@ -84,10 +83,7 @@ class FileImportSerializer:
84
83
  return file_import_copy.imports.get(baseline_typing_section, {})
85
84
 
86
85
  def _add_type_checking_import(self):
87
- if self._file_import.imports.get(TypingSection.TYPING) or (
88
- not self.is_python3_file
89
- and self._file_import.imports.get(TypingSection.CONDITIONAL)
90
- ):
86
+ if self._file_import.imports.get(TypingSection.TYPING):
91
87
  self._file_import.add_submodule_import(
92
88
  "typing", "TYPE_CHECKING", ImportType.STDLIB
93
89
  )
@@ -97,7 +93,7 @@ class FileImportSerializer:
97
93
  regular_imports = ""
98
94
  regular_imports_dict = self._get_imports_dict(
99
95
  baseline_typing_section=TypingSection.REGULAR,
100
- add_conditional_typing=self.is_python3_file,
96
+ add_conditional_typing=True,
101
97
  )
102
98
 
103
99
  if regular_imports_dict:
@@ -108,7 +104,7 @@ class FileImportSerializer:
108
104
  typing_imports = ""
109
105
  typing_imports_dict = self._get_imports_dict(
110
106
  baseline_typing_section=TypingSection.TYPING,
111
- add_conditional_typing=not self.is_python3_file,
107
+ add_conditional_typing=False,
112
108
  )
113
109
  if typing_imports_dict:
114
110
  typing_imports += "\n\nif TYPE_CHECKING:\n # pylint: disable=unused-import,ungrouped-imports\n "
@@ -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
+ )