@autorest/python 6.0.1 → 6.1.2

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 (41) hide show
  1. package/ChangeLog.md +57 -0
  2. package/README.md +22 -3
  3. package/autorest/__init__.py +52 -14
  4. package/autorest/_utils.py +75 -0
  5. package/autorest/black/__init__.py +15 -8
  6. package/autorest/cadlflags/__init__.py +128 -0
  7. package/autorest/codegen/__init__.py +14 -21
  8. package/autorest/codegen/_utils.py +12 -0
  9. package/autorest/codegen/models/__init__.py +10 -1
  10. package/autorest/codegen/models/combined_type.py +4 -0
  11. package/autorest/codegen/models/model_type.py +18 -1
  12. package/autorest/codegen/models/parameter.py +5 -1
  13. package/autorest/codegen/models/property.py +1 -8
  14. package/autorest/codegen/models/request_builder_parameter.py +1 -1
  15. package/autorest/codegen/models/response.py +7 -0
  16. package/autorest/codegen/models/utils.py +0 -3
  17. package/autorest/codegen/serializers/__init__.py +20 -15
  18. package/autorest/codegen/serializers/builder_serializer.py +5 -5
  19. package/autorest/codegen/templates/README.md.jinja2 +3 -3
  20. package/autorest/codegen/templates/setup.py.jinja2 +1 -2
  21. package/autorest/jsonrpc/server.py +7 -1
  22. package/autorest/m2r/__init__.py +11 -4
  23. package/autorest/m4reformatter/__init__.py +13 -37
  24. package/autorest/multiapi/__init__.py +5 -6
  25. package/autorest/multiapi/serializers/__init__.py +5 -3
  26. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +4 -0
  27. package/autorest/multiclient/__init__.py +50 -0
  28. package/autorest/multiclient/templates/init.py.jinja2 +8 -0
  29. package/autorest/multiclient/templates/version.py.jinja2 +8 -0
  30. package/autorest/postprocess/__init__.py +1 -1
  31. package/autorest/preprocess/__init__.py +138 -17
  32. package/autorest/preprocess/helpers.py +0 -30
  33. package/install.py +3 -3
  34. package/package.json +3 -2
  35. package/prepare.py +2 -2
  36. package/requirements.txt +8 -9
  37. package/run-python3.js +2 -2
  38. package/run_cadl.py +27 -0
  39. package/setup.py +2 -3
  40. package/start.py +2 -2
  41. package/autorest/multiapi/serializers/multiapi_serializer.py +0 -121
@@ -306,6 +306,10 @@ class Parameter(_ParameterBase):
306
306
  def xml_serialization_ctxt(self) -> str:
307
307
  return self.type.xml_serialization_ctxt or ""
308
308
 
309
+ @property
310
+ def is_content_type(self) -> bool:
311
+ return bool(self.rest_api_name) and self.rest_api_name.lower() == "content-type"
312
+
309
313
  @property
310
314
  def method_location(self) -> ParameterMethodLocation:
311
315
  if not self.in_method_signature:
@@ -314,7 +318,7 @@ class Parameter(_ParameterBase):
314
318
  return ParameterMethodLocation.POSITIONAL
315
319
  if self.constant:
316
320
  return ParameterMethodLocation.KWARG
317
- if self.rest_api_name == "Content-Type":
321
+ if self.is_content_type:
318
322
  if self.in_overload:
319
323
  return ParameterMethodLocation.KEYWORD_ONLY
320
324
  return ParameterMethodLocation.KWARG
@@ -110,14 +110,7 @@ class Property(BaseModel): # pylint: disable=too-many-instance-attributes
110
110
  from .model_type import ModelType
111
111
 
112
112
  if isinstance(self.type, ModelType):
113
- is_polymorphic_subtype = (
114
- self.type.discriminator_value and not self.type.discriminated_subtypes
115
- )
116
- if (
117
- self.type.name not in (m.name for m in polymorphic_subtypes)
118
- and is_polymorphic_subtype
119
- ):
120
- polymorphic_subtypes.append(self.type)
113
+ self.type.get_polymorphic_subtypes(polymorphic_subtypes)
121
114
 
122
115
  @property
123
116
  def validation(self) -> Optional[Dict[str, Any]]:
@@ -95,7 +95,7 @@ class RequestBuilderParameter(Parameter):
95
95
  ) -> None:
96
96
  super().__init__(yaml_data, code_model, type)
97
97
  # we don't want any default content type behavior in request builder
98
- if self.rest_api_name == "Content-Type":
98
+ if self.is_content_type:
99
99
  self.client_default_value = None
100
100
  if self.grouped_by and self.client_name[0] == "_":
101
101
  # we don't want hidden parameters for grouped by in request builders
@@ -55,6 +55,10 @@ class Response(BaseModel):
55
55
  self.type = type
56
56
  self.nullable = yaml_data.get("nullable")
57
57
 
58
+ def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
59
+ if self.type:
60
+ self.type.get_polymorphic_subtypes(polymorphic_subtypes)
61
+
58
62
  def get_json_template_representation(self) -> Any:
59
63
  if not self.type:
60
64
  return None
@@ -137,6 +141,9 @@ class PagingResponse(Response):
137
141
  super().__init__(*args, **kwargs)
138
142
  self.item_type = self.code_model.lookup_type(id(self.yaml_data["itemType"]))
139
143
 
144
+ def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
145
+ return self.item_type.get_polymorphic_subtypes(polymorphic_subtypes)
146
+
140
147
  def get_json_template_representation(self) -> Any:
141
148
  return self.item_type.get_json_template_representation()
142
149
 
@@ -3,11 +3,8 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
- import re
7
6
  from typing import TypeVar, Dict
8
7
 
9
- JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
10
-
11
8
  T = TypeVar("T")
12
9
  OrderedSet = Dict[T, None]
13
10
 
@@ -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 Dict, List, Optional, Any, Union
6
+ from typing import Dict, List, Optional, Any, Union, cast
7
7
  from pathlib import Path
8
8
  from jinja2 import PackageLoader, Environment, FileSystemLoader, StrictUndefined
9
9
  from autorest.codegen.models.operation_group import OperationGroup
@@ -40,8 +40,10 @@ _REGENERATE_FILES = {"setup.py", "MANIFEST.in"}
40
40
 
41
41
 
42
42
  class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
43
- def __init__(self, code_model: CodeModel, **kwargs: Any) -> None:
44
- super().__init__(**kwargs)
43
+ def __init__(
44
+ self, code_model: CodeModel, *, output_folder: Union[str, Path], **kwargs: Any
45
+ ) -> None:
46
+ super().__init__(output_folder=output_folder, **kwargs)
45
47
  self.code_model = code_model
46
48
 
47
49
  @property
@@ -133,7 +135,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
133
135
  if self.read_file(namespace_path / Path("models.py")):
134
136
  self.write_file(
135
137
  namespace_path / Path("models.py"),
136
- self.read_file(namespace_path / Path("models.py")),
138
+ cast(str, self.read_file(namespace_path / Path("models.py"))),
137
139
  )
138
140
 
139
141
  if self.code_model.options["package_mode"]:
@@ -150,7 +152,9 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
150
152
  self.write_file(output_name, render_result)
151
153
 
152
154
  def _prepare_params() -> Dict[Any, Any]:
153
- package_parts = package_name.split("-")[:-1]
155
+ package_parts = (self.code_model.options["package_name"] or "").split("-")[
156
+ :-1
157
+ ]
154
158
  token_cred = isinstance(
155
159
  getattr(self.code_model.credential, "type", None), TokenCredentialType
156
160
  )
@@ -177,14 +181,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
177
181
  params.update(self.code_model.package_dependency)
178
182
  return params
179
183
 
180
- package_name = (
181
- self.code_model.options["package_name"]
182
- or self.code_model.client.name.lower()
183
- )
184
- count = package_name.count("-") + 1
185
- for _ in range(count):
186
- out_path = out_path / Path("..")
187
-
184
+ out_path = out_path / Path("../" * (self.code_model.namespace.count(".") + 1))
188
185
  if self.code_model.options["package_mode"] in ("dataplane", "mgmtplane"):
189
186
  env = Environment(
190
187
  loader=PackageLoader("autorest.codegen", "templates"),
@@ -484,5 +481,13 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
484
481
 
485
482
 
486
483
  class JinjaSerializerAutorest(JinjaSerializer, ReaderAndWriterAutorest):
487
- def __init__(self, autorestapi: AutorestAPI, code_model: CodeModel) -> None:
488
- super().__init__(autorestapi=autorestapi, code_model=code_model)
484
+ def __init__(
485
+ self,
486
+ autorestapi: AutorestAPI,
487
+ code_model: CodeModel,
488
+ *,
489
+ output_folder: Union[str, Path],
490
+ ) -> None:
491
+ super().__init__(
492
+ autorestapi=autorestapi, code_model=code_model, output_folder=output_folder
493
+ )
@@ -79,9 +79,7 @@ def _improve_json_string(template_representation: str) -> Any:
79
79
 
80
80
  def _json_dumps_template(template_representation: Any) -> Any:
81
81
  # only for template use, since it wraps everything in strings
82
- return _improve_json_string(
83
- json.dumps(template_representation, sort_keys=True, indent=4)
84
- )
82
+ return _improve_json_string(json.dumps(template_representation, indent=4))
85
83
 
86
84
 
87
85
  def _get_polymorphic_subtype_template(polymorphic_subtype: ModelType) -> List[str]:
@@ -533,7 +531,7 @@ class _OperationSerializer(
533
531
  polymorphic_subtypes: List[ModelType] = []
534
532
  if not response.type:
535
533
  continue
536
- response.type.get_polymorphic_subtypes(polymorphic_subtypes)
534
+ response.get_polymorphic_subtypes(polymorphic_subtypes)
537
535
  if polymorphic_subtypes:
538
536
  # we just assume one kind of polymorphic body for input
539
537
  discriminator_name = cast(
@@ -693,7 +691,9 @@ class _OperationSerializer(
693
691
  if (
694
692
  not body_param.default_content_type
695
693
  and not next(
696
- p for p in builder.parameters if p.rest_api_name == "Content-Type"
694
+ p
695
+ for p in builder.parameters
696
+ if p.rest_api_name.lower() == "content-type"
697
697
  ).optional
698
698
  ):
699
699
  content_types = "'" + "', '".join(body_param.content_types) + "'"
@@ -2,7 +2,7 @@
2
2
  # Microsoft Azure SDK for Python
3
3
 
4
4
  This is the Microsoft {{package_pprint_name}} Client Library.
5
- This package has been tested with Python 3.6+.
5
+ This package has been tested with Python 3.7+.
6
6
  For a more complete view of Azure libraries, see the [azure sdk python release](https://aka.ms/azsdk/python/all).
7
7
 
8
8
  # Usage
@@ -17,7 +17,7 @@ Additional code samples for different Azure services are available at [Samples R
17
17
 
18
18
  If you encounter any bugs or have suggestions, please file an issue in the
19
19
  [Issues](https://github.com/Azure/azure-sdk-for-python/issues)
20
- section of the project.
20
+ section of the project.
21
21
 
22
22
 
23
23
  ![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-python%2F{{package_name}}%2FREADME.png)
@@ -35,7 +35,7 @@ python -m pip install {{ package_name }}
35
35
 
36
36
  #### Prequisites
37
37
 
38
- - Python 3.6 or later is required to use this package.
38
+ - Python 3.7 or later is required to use this package.
39
39
  - You need an [Azure subscription][azure_sub] to use this package.
40
40
  - An existing {{ package_pprint_name }} instance.
41
41
 
@@ -54,7 +54,6 @@ setup(
54
54
  "Programming Language :: Python",
55
55
  "Programming Language :: Python :: 3 :: Only",
56
56
  "Programming Language :: Python :: 3",
57
- "Programming Language :: Python :: 3.6",
58
57
  "Programming Language :: Python :: 3.7",
59
58
  "Programming Language :: Python :: 3.8",
60
59
  "Programming Language :: Python :: 3.9",
@@ -94,7 +93,7 @@ setup(
94
93
  {% endif %}
95
94
  ],
96
95
  {% if package_mode %}
97
- python_requires=">=3.6",
96
+ python_requires=">=3.7",
98
97
  {% else %}
99
98
  long_description="""\
100
99
  {{ code_model.client.description }}
@@ -26,6 +26,7 @@ def GetPluginNames():
26
26
  "black",
27
27
  "multiapiscript",
28
28
  "postprocess",
29
+ "multiclientscript",
29
30
  ]
30
31
 
31
32
 
@@ -56,11 +57,16 @@ def Process(plugin_name: str, session_id: str) -> bool:
56
57
  from ..black import BlackScriptPluginAutorest as PluginToLoad # type: ignore
57
58
  elif plugin_name == "multiapiscript":
58
59
  from ..multiapi import MultiApiScriptPluginAutorest as PluginToLoad # type: ignore
60
+ elif plugin_name == "multiclientscript":
61
+ from ..multiclient import MultiClientPluginAutorest as PluginToLoad # type: ignore
59
62
  else:
60
63
  _LOGGER.fatal("Unknown plugin name %s", plugin_name)
61
64
  raise RuntimeError(f"Unknown plugin name {plugin_name}")
62
65
 
63
- plugin = PluginToLoad(autorestapi=stdstream_connection)
66
+ plugin = PluginToLoad(
67
+ autorestapi=stdstream_connection,
68
+ output_folder=stdstream_connection.get_value("output-folder"),
69
+ )
64
70
 
65
71
  try:
66
72
  _LOGGER.debug("Starting plugin %s", PluginToLoad.__name__)
@@ -8,20 +8,21 @@
8
8
  import logging
9
9
  from typing import Any, Dict, Set
10
10
 
11
- import m2r
11
+ import m2r2
12
12
 
13
13
  from .. import YamlUpdatePluginAutorest, YamlUpdatePlugin
14
+ from .._utils import parse_args
14
15
 
15
16
 
16
17
  _LOGGER = logging.getLogger(__name__)
17
18
 
18
19
 
19
- class AutorestRender(m2r.RestRenderer):
20
+ class AutorestRender(m2r2.RestRenderer):
20
21
  """Redefine the concept of inline HTML in the renderer, we don't want to define a new format
21
22
  in the description/summary.
22
23
  """
23
24
 
24
- def inline_html(self, html: str) -> str:
25
+ def inline_html(self, html: str) -> str: # pylint: disable=no-self-use
25
26
  """Do not render inline HTML with a role definition."""
26
27
  return f":code:`{html}`"
27
28
 
@@ -55,7 +56,7 @@ class M2R(YamlUpdatePlugin): # pylint: disable=abstract-method
55
56
  def convert_to_rst(string_to_convert: str) -> str:
56
57
  """Convert that string from MD to RST."""
57
58
  try:
58
- return m2r.convert(string_to_convert, renderer=AutorestRender()).strip()
59
+ return m2r2.convert(string_to_convert, renderer=AutorestRender()).strip()
59
60
  except Exception: # pylint: disable=broad-except
60
61
  return string_to_convert
61
62
 
@@ -63,3 +64,9 @@ class M2R(YamlUpdatePlugin): # pylint: disable=abstract-method
63
64
  class M2RAutorest(YamlUpdatePluginAutorest, M2R):
64
65
  def get_options(self) -> Dict[str, Any]:
65
66
  return {}
67
+
68
+
69
+ if __name__ == "__main__":
70
+ # CADL pipeline will call this
71
+ args = parse_args()
72
+ M2R(output_folder=args.output_folder, cadl_file=args.cadl_file).process()
@@ -6,27 +6,25 @@
6
6
  # --------------------------------------------------------------------------
7
7
  """The modelerfour reformatter autorest plugin.
8
8
  """
9
- import re
10
9
  import copy
11
10
  import logging
12
11
  from typing import Callable, Dict, Any, Iterable, List, Optional, Set
13
12
 
13
+ from .._utils import (
14
+ to_snake_case,
15
+ KNOWN_TYPES,
16
+ get_body_type_for_description,
17
+ JSON_REGEXP,
18
+ )
14
19
  from .. import YamlUpdatePluginAutorest
15
20
 
16
- JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
21
+
17
22
  ORIGINAL_ID_TO_UPDATED_TYPE: Dict[int, Dict[str, Any]] = {}
18
23
  OAUTH_TYPE = "OAuth2"
19
24
  KEY_TYPE = "Key"
20
25
 
21
26
  _LOGGER = logging.getLogger(__name__)
22
27
 
23
- # used if we want to get a string / binary type etc
24
- KNOWN_TYPES: Dict[str, Dict[str, Any]] = {
25
- "string": {"type": "string"},
26
- "binary": {"type": "binary"},
27
- "anydict": {"type": "dict", "elementType": {"type": "any"}},
28
- }
29
-
30
28
 
31
29
  def is_body(yaml_data: Dict[str, Any]) -> bool:
32
30
  """Return true if passed in parameter is a body param"""
@@ -328,14 +326,6 @@ def get_all_body_types(yaml_data: Dict[str, Any]) -> List[Dict[str, Any]]:
328
326
  return list(seen_body_types.values())
329
327
 
330
328
 
331
- def get_body_type_for_description(body_parameter: Dict[str, Any]) -> str:
332
- if body_parameter["type"]["type"] == "binary":
333
- return "binary"
334
- if body_parameter["type"]["type"] == "string":
335
- return "string"
336
- return "JSON"
337
-
338
-
339
329
  def add_lro_information(operation: Dict[str, Any], yaml_data: Dict[str, Any]) -> None:
340
330
  operation["discriminator"] = "lro"
341
331
  extensions = yaml_data["extensions"]
@@ -478,7 +468,7 @@ class M4Reformatter(
478
468
  group_name, yaml_data, body_type, content_types=content_types
479
469
  )
480
470
  for parameter in overload["parameters"]:
481
- if parameter["restApiName"] == "Content-Type":
471
+ if parameter["restApiName"].lower() == "content-type":
482
472
  parameter["clientDefaultValue"] = overload["bodyParameter"][
483
473
  "defaultContentType"
484
474
  ]
@@ -556,23 +546,6 @@ class M4Reformatter(
556
546
  else None
557
547
  )
558
548
  content_types = None
559
- if ( # pylint: disable=too-many-boolean-expressions
560
- body_parameter
561
- and body_parameter["type"]["type"] != "combined"
562
- and yaml_data.get("requestMediaTypes")
563
- and any(
564
- ct for ct in yaml_data["requestMediaTypes"] if JSON_REGEXP.match(ct)
565
- )
566
- and body_parameter["type"]["type"] in ("model", "dict", "list")
567
- and not body_parameter["type"]["xmlMetadata"]
568
- and not body_parameter.get("flattened")
569
- and not body_parameter.get("groupedBy")
570
- ):
571
- combined_type = update_types(
572
- [body_parameter["type"], KNOWN_TYPES["binary"]]
573
- )
574
- body_parameter["type"] = combined_type
575
- content_types = body_parameter["contentTypes"]
576
549
  operation = self._update_operation_helper(group_name, yaml_data, body_parameter)
577
550
  operation["overloads"] = self.update_overloads(
578
551
  group_name, yaml_data, body_parameter, content_types=content_types
@@ -842,7 +815,10 @@ class M4Reformatter(
842
815
  continue
843
816
  if is_body(param):
844
817
  continue
845
- if param["language"]["default"].get("serializedName") == "Content-Type":
818
+ if (
819
+ param["language"]["default"].get("serializedName").lower()
820
+ == "content-type"
821
+ ):
846
822
  param = self._update_content_type_parameter(
847
823
  param,
848
824
  body_parameter,
@@ -1100,7 +1076,7 @@ class M4Reformatter(
1100
1076
  if yaml_data.get("globalParameters")
1101
1077
  else "",
1102
1078
  "namespace": self._autorestapi.get_value("namespace")
1103
- or yaml_data["language"]["default"]["name"],
1079
+ or to_snake_case(yaml_data["info"]["title"].replace(" ", "")),
1104
1080
  }
1105
1081
 
1106
1082
  def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
@@ -41,7 +41,7 @@ class MultiApiScriptPluginAutorest(MultiApiScriptPlugin, PluginAutorest):
41
41
  return MultiAPIAutorest(
42
42
  autorestapi=self._autorestapi,
43
43
  input_package_name=self.options.get("package-name"),
44
- output_folder=self.options["output-folder"],
44
+ output_folder=self.output_folder,
45
45
  user_specified_default_api=self.options.get("default-api"),
46
46
  no_async=self.options.get("no-async", False),
47
47
  )
@@ -49,7 +49,6 @@ class MultiApiScriptPluginAutorest(MultiApiScriptPlugin, PluginAutorest):
49
49
  def get_options(self) -> Dict[str, Any]:
50
50
  options = {
51
51
  "package-name": self._autorestapi.get_value("package-name"),
52
- "output-folder": self._autorestapi.get_value("output-folder"),
53
52
  "default-api": self._autorestapi.get_value("default-api"),
54
53
  "no-async": self._autorestapi.get_value("no-async"),
55
54
  }
@@ -66,15 +65,13 @@ class MultiAPI(ReaderAndWriter): # pylint: disable=abstract-method
66
65
  user_specified_default_api: Optional[str] = None,
67
66
  **kwargs: Any,
68
67
  ) -> None:
69
- super().__init__(**kwargs)
68
+ super().__init__(output_folder=Path(output_folder).resolve(), **kwargs)
70
69
  if input_package_name is None:
71
70
  raise ValueError(
72
71
  "package-name is required, either provide it as args or check your readme configuration"
73
72
  )
74
73
  self.input_package_name = input_package_name
75
74
  _LOGGER.debug("Received package name %s", input_package_name)
76
-
77
- self.output_folder = Path(output_folder).resolve()
78
75
  _LOGGER.debug("Received output-folder %s", output_folder)
79
76
  self.output_package_name: str = ""
80
77
  self.no_async = no_async
@@ -194,4 +191,6 @@ class MultiAPIAutorest(MultiAPI, ReaderAndWriterAutorest):
194
191
 
195
192
  @property
196
193
  def serializer(self) -> MultiAPISerializer:
197
- return MultiAPISerializerAutorest(self._autorestapi)
194
+ return MultiAPISerializerAutorest(
195
+ self._autorestapi, output_folder=self.output_folder
196
+ )
@@ -4,7 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from pathlib import Path
7
- from typing import Any, Optional
7
+ from typing import Any, Optional, Union
8
8
  from jinja2 import PackageLoader, Environment
9
9
 
10
10
  from .import_serializer import FileImportSerializer
@@ -122,5 +122,7 @@ class MultiAPISerializer(ReaderAndWriter): # pylint: disable=abstract-method
122
122
 
123
123
 
124
124
  class MultiAPISerializerAutorest(MultiAPISerializer, ReaderAndWriterAutorest):
125
- def __init__(self, autorestapi: AutorestAPI) -> None:
126
- super().__init__(autorestapi=autorestapi)
125
+ def __init__(
126
+ self, autorestapi: AutorestAPI, *, output_folder: Union[str, Path]
127
+ ) -> None:
128
+ super().__init__(autorestapi=autorestapi, output_folder=output_folder)
@@ -15,4 +15,8 @@ try:
15
15
  patch_sdk()
16
16
  except ImportError:
17
17
  pass
18
+
19
+ from ._version import VERSION
20
+
21
+ __version__ = VERSION
18
22
  {% endif %}
@@ -0,0 +1,50 @@
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
+ import logging
7
+ from typing import Any, Dict
8
+ from pathlib import Path
9
+ from jinja2 import Environment, PackageLoader
10
+ from .. import Plugin, PluginAutorest
11
+
12
+ _LOGGER = logging.getLogger(__name__)
13
+
14
+
15
+ class MultiClientPlugin(Plugin): # pylint: disable=abstract-method
16
+ def process(self) -> bool:
17
+ _LOGGER.info("Generating files for multi client")
18
+
19
+ env = Environment(
20
+ loader=PackageLoader("autorest.multiclient", "templates"),
21
+ keep_trailing_newline=True,
22
+ line_statement_prefix="##",
23
+ line_comment_prefix="###",
24
+ trim_blocks=True,
25
+ lstrip_blocks=True,
26
+ )
27
+
28
+ # __init__.py
29
+ template = env.get_template("init.py.jinja2")
30
+ self.write_file(Path("__init__.py"), template.render())
31
+
32
+ # _version.py
33
+ template = env.get_template("version.py.jinja2")
34
+ self.write_file(
35
+ Path("_version.py"),
36
+ template.render(
37
+ package_version=self.options.get("package-version") or "1.0.0b1"
38
+ ),
39
+ )
40
+
41
+ # py.typed
42
+ self.write_file(Path("py.typed"), "# Marker file for PEP 561.")
43
+
44
+ _LOGGER.info("Generating Done for multi client!")
45
+ return True
46
+
47
+
48
+ class MultiClientPluginAutorest(MultiClientPlugin, PluginAutorest):
49
+ def get_options(self) -> Dict[str, Any]:
50
+ return {"package-version": self._autorestapi.get_value("package-version")}
@@ -0,0 +1,8 @@
1
+ # --------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for license information.
4
+ # Code generated by Microsoft (R) AutoRest Code Generator.
5
+ # Changes may cause incorrect behavior and will be lost if the code is regenerated.
6
+ # --------------------------------------------------------------------------
7
+ from ._version import VERSION
8
+ __version__ = VERSION
@@ -0,0 +1,8 @@
1
+ # coding=utf-8
2
+ # --------------------------------------------------------------------------
3
+ # Copyright (c) Microsoft Corporation. All rights reserved.
4
+ # Licensed under the MIT License. See License.txt in the project root for
5
+ # license information.
6
+ # --------------------------------------------------------------------------
7
+
8
+ VERSION = "{{ package_version }}"
@@ -66,7 +66,7 @@ class PostProcessPlugin(Plugin): # pylint: disable=abstract-method
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
68
  file_content = self.read_file(init_file.relative_to(self.output_folder))
69
- if not "pkgutil" in file_content:
69
+ if "pkgutil" not in file_content:
70
70
  return dir, namespace
71
71
  except StopIteration:
72
72
  pass