@autorest/python 5.11.2 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/ChangeLog.md +26 -0
  2. package/autorest/codegen/__init__.py +5 -5
  3. package/autorest/codegen/models/client.py +2 -2
  4. package/autorest/codegen/models/code_model.py +5 -1
  5. package/autorest/codegen/models/operation_group.py +5 -3
  6. package/autorest/codegen/models/parameter.py +4 -3
  7. package/autorest/codegen/models/parameter_list.py +30 -26
  8. package/autorest/codegen/models/request_builder.py +5 -1
  9. package/autorest/codegen/models/request_builder_parameter.py +4 -3
  10. package/autorest/codegen/models/request_builder_parameter_list.py +15 -6
  11. package/autorest/codegen/models/rest.py +3 -2
  12. package/autorest/codegen/serializers/__init__.py +48 -48
  13. package/autorest/codegen/serializers/builder_serializer.py +32 -27
  14. package/autorest/codegen/serializers/client_serializer.py +37 -9
  15. package/autorest/codegen/serializers/general_serializer.py +7 -5
  16. package/autorest/codegen/serializers/import_serializer.py +6 -6
  17. package/autorest/codegen/serializers/metadata_serializer.py +2 -2
  18. package/autorest/codegen/serializers/model_base_serializer.py +3 -3
  19. package/autorest/codegen/serializers/model_generic_serializer.py +1 -1
  20. package/autorest/codegen/serializers/model_python3_serializer.py +1 -1
  21. package/autorest/codegen/serializers/{operation_group_serializer.py → operation_groups_serializer.py} +27 -29
  22. package/autorest/codegen/serializers/operations_init_serializer.py +34 -2
  23. package/autorest/codegen/serializers/patch_serializer.py +15 -0
  24. package/autorest/codegen/serializers/rest_serializer.py +9 -4
  25. package/autorest/codegen/serializers/utils.py +2 -2
  26. package/autorest/codegen/templates/config.py.jinja2 +1 -11
  27. package/autorest/codegen/templates/init.py.jinja2 +4 -5
  28. package/autorest/codegen/templates/metadata.json.jinja2 +2 -2
  29. package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
  30. package/autorest/codegen/templates/{operations_class.py.jinja2 → operation_group.py.jinja2} +2 -0
  31. package/autorest/codegen/templates/{operations_container.py.jinja2 → operation_groups_container.py.jinja2} +7 -21
  32. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +13 -0
  33. package/autorest/codegen/templates/patch.py.jinja2 +31 -0
  34. package/autorest/codegen/templates/request_builder.py.jinja2 +7 -2
  35. package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
  36. package/autorest/codegen/templates/setup.py.jinja2 +1 -1
  37. package/autorest/multiapi/serializers/__init__.py +3 -3
  38. package/autorest/multiapi/serializers/import_serializer.py +5 -5
  39. package/autorest/namer/name_converter.py +1 -0
  40. package/package.json +2 -2
  41. package/setup.py +1 -0
  42. package/autorest/codegen/templates/operations_class_mixin.py.jinja2 +0 -16
  43. package/autorest/codegen/templates/operations_container_init.py.jinja2 +0 -24
  44. package/autorest/codegen/templates/operations_container_mixin.py.jinja2 +0 -21
  45. package/autorest/codegen/templates/operations_init.py.jinja2 +0 -26
@@ -57,7 +57,7 @@ def _json_dumps_template(template_representation: Any) -> Any:
57
57
  def _serialize_files_or_data_dict(multipart_parameters: List[Parameter]) -> str:
58
58
  # only for template use
59
59
  template = {
60
- param.serialized_name: param.schema.get_files_and_data_template_representation(
60
+ f'"{param.serialized_name}"': param.schema.get_files_and_data_template_representation(
61
61
  optional=not param.required,
62
62
  description=param.description,
63
63
  )
@@ -542,11 +542,11 @@ class RequestBuilderGenericSerializer(_RequestBuilderBaseSerializer):
542
542
  @staticmethod
543
543
  def _method_signature_and_response_type_annotation_template(method_signature: str, response_type_annotation: str):
544
544
  return utils.method_signature_and_response_type_annotation_template(
545
- is_python_3_file=False, method_signature=method_signature, response_type_annotation=response_type_annotation
545
+ is_python3_file=False, method_signature=method_signature, response_type_annotation=response_type_annotation
546
546
  )
547
547
 
548
548
  def _get_kwargs_to_pop(self, builder: BuilderType):
549
- return builder.parameters.kwargs_to_pop(is_python_3_file=False)
549
+ return builder.parameters.kwargs_to_pop(is_python3_file=False)
550
550
 
551
551
  def _body_params_to_pass_to_request_creation(self, builder: BuilderType) -> List[str]:
552
552
  if builder.parameters.has_body and not builder.parameters.body_kwarg_names:
@@ -564,11 +564,11 @@ class RequestBuilderPython3Serializer(_RequestBuilderBaseSerializer):
564
564
  @staticmethod
565
565
  def _method_signature_and_response_type_annotation_template(method_signature: str, response_type_annotation: str):
566
566
  return utils.method_signature_and_response_type_annotation_template(
567
- is_python_3_file=True, method_signature=method_signature, response_type_annotation=response_type_annotation
567
+ is_python3_file=True, method_signature=method_signature, response_type_annotation=response_type_annotation
568
568
  )
569
569
 
570
570
  def _get_kwargs_to_pop(self, builder: BuilderType):
571
- return builder.parameters.kwargs_to_pop(is_python_3_file=True)
571
+ return builder.parameters.kwargs_to_pop(is_python3_file=True)
572
572
 
573
573
  def _body_params_to_pass_to_request_creation(self, builder: BuilderType) -> List[str]:
574
574
  body_kwargs = list(builder.parameters.body_kwarg_names.keys())
@@ -698,10 +698,10 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
698
698
  body_kwarg_to_pass = builder.body_kwargs_to_pass_to_request_builder[0]
699
699
  if self.code_model.options["models_mode"]:
700
700
  return (
701
- f"{body_kwarg_to_pass} = self._serialize.body({body_param.serialized_name}, "
701
+ f"_{body_kwarg_to_pass} = self._serialize.body({body_param.serialized_name}, "
702
702
  f"'{ body_param.serialization_type }'{body_is_xml}{ pass_ser_ctxt })"
703
703
  )
704
- return f"{body_kwarg_to_pass} = {body_param.serialized_name}"
704
+ return f"_{body_kwarg_to_pass} = {body_param.serialized_name}"
705
705
 
706
706
  def _serialize_body(self, builder: BuilderType, body_param: Parameter, body_kwarg: str) -> List[str]:
707
707
  retval = []
@@ -728,7 +728,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
728
728
  retval.append(" " + serialize_body_call)
729
729
  if len(builder.body_kwargs_to_pass_to_request_builder) == 1:
730
730
  retval.append("else:")
731
- retval.append(f" {body_kwarg} = None")
731
+ retval.append(f" _{body_kwarg} = None")
732
732
  return retval
733
733
 
734
734
  def _set_body_content_kwarg(
@@ -743,7 +743,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
743
743
  return retval
744
744
  except AttributeError:
745
745
  pass
746
- retval.append(f"{body_kwarg.serialized_name} = {body_param.serialized_name}")
746
+ retval.append(f"_{body_kwarg.serialized_name} = {body_param.serialized_name}")
747
747
  return retval
748
748
 
749
749
 
@@ -790,7 +790,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
790
790
  if self.code_model.options["version_tolerant"]:
791
791
  body_params_to_initialize = [p for p in body_params_to_initialize if p != "files"]
792
792
  for k in body_params_to_initialize:
793
- retval.append(f"{k} = None")
793
+ retval.append(f"_{k} = None")
794
794
  if builder.parameters.grouped:
795
795
  # request builders don't allow grouped parameters, so we group them before making the call
796
796
  retval.extend(_serialize_grouped_body(builder))
@@ -799,8 +799,8 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
799
799
  # unflatten before passing to request builder as well
800
800
  retval.extend(_serialize_flattened_body(builder))
801
801
  if request_builder.multipart or request_builder.parameters.data_inputs:
802
- param_name = "files" if request_builder.multipart else "data"
803
802
  if not self.code_model.options["version_tolerant"]:
803
+ param_name = "_files" if request_builder.multipart else "_data"
804
804
  retval.extend(_serialize_files_and_data_body(builder, param_name))
805
805
  elif builder.parameters.has_body and not builder.parameters.body[0].constant:
806
806
  retval.extend(self._serialize_body_parameters(builder))
@@ -823,18 +823,23 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
823
823
  continue
824
824
  high_level_name = cast(RequestBuilderParameter, parameter).name_in_high_level_operation
825
825
  retval.append(f" {parameter.serialized_name}={high_level_name},")
826
- template_url = template_url or f"self.{builder.name}.metadata['url']"
827
- retval.append(f" template_url={template_url},")
826
+ if not self.code_model.options["version_tolerant"]:
827
+ template_url = template_url or f"self.{builder.name}.metadata['url']"
828
+ retval.append(f" template_url={template_url},")
828
829
  retval.append(f")")
829
830
  if not self.code_model.options["version_tolerant"]:
830
831
  pass_files = ""
831
832
  if "files" in builder.body_kwargs_to_pass_to_request_builder:
832
- pass_files = ", files"
833
+ pass_files = ", _files"
833
834
  retval.append(f"request = _convert_request(request{pass_files})")
834
835
  if builder.parameters.path:
835
836
  retval.extend(self.serialize_path(builder))
837
+ url_to_format = "request.url"
838
+ if self.code_model.options["version_tolerant"] and template_url:
839
+ url_to_format = template_url
836
840
  retval.append(
837
- "request.url = self._client.format_url(request.url{})".format(
841
+ "request.url = self._client.format_url({}{})".format(
842
+ url_to_format,
838
843
  ", **path_format_arguments" if builder.parameters.path else ""
839
844
  )
840
845
  )
@@ -1005,11 +1010,11 @@ class SyncOperationGenericSerializer(_SyncOperationBaseSerializer):
1005
1010
  @staticmethod
1006
1011
  def _method_signature_and_response_type_annotation_template(method_signature: str, response_type_annotation: str):
1007
1012
  return utils.method_signature_and_response_type_annotation_template(
1008
- is_python_3_file=False, method_signature=method_signature, response_type_annotation=response_type_annotation
1013
+ is_python3_file=False, method_signature=method_signature, response_type_annotation=response_type_annotation
1009
1014
  )
1010
1015
 
1011
1016
  def _get_kwargs_to_pop(self, builder: BuilderType):
1012
- return builder.parameters.kwargs_to_pop(is_python_3_file=False)
1017
+ return builder.parameters.kwargs_to_pop(is_python3_file=False)
1013
1018
 
1014
1019
 
1015
1020
  class SyncOperationPython3Serializer(_SyncOperationBaseSerializer):
@@ -1020,11 +1025,11 @@ class SyncOperationPython3Serializer(_SyncOperationBaseSerializer):
1020
1025
  @staticmethod
1021
1026
  def _method_signature_and_response_type_annotation_template(method_signature: str, response_type_annotation: str):
1022
1027
  return utils.method_signature_and_response_type_annotation_template(
1023
- is_python_3_file=True, method_signature=method_signature, response_type_annotation=response_type_annotation
1028
+ is_python3_file=True, method_signature=method_signature, response_type_annotation=response_type_annotation
1024
1029
  )
1025
1030
 
1026
1031
  def _get_kwargs_to_pop(self, builder: BuilderType):
1027
- return builder.parameters.kwargs_to_pop(is_python_3_file=True)
1032
+ return builder.parameters.kwargs_to_pop(is_python3_file=True)
1028
1033
 
1029
1034
  class AsyncOperationSerializer(SyncOperationPython3Serializer):
1030
1035
 
@@ -1057,7 +1062,7 @@ class _PagingOperationBaseSerializer(_OperationBaseSerializer): # pylint: disab
1057
1062
  def call_next_link_request_builder(self, builder: BuilderType) -> List[str]:
1058
1063
  if builder.next_request_builder:
1059
1064
  request_builder = builder.next_request_builder
1060
- template_url = f"'{request_builder.url}'"
1065
+ template_url = None if self.code_model.options["version_tolerant"] else f"'{request_builder.url}'"
1061
1066
  else:
1062
1067
  request_builder = builder.request_builder
1063
1068
  template_url = "next_link"
@@ -1445,14 +1450,14 @@ def get_operation_serializer(
1445
1450
  builder: BuilderType,
1446
1451
  code_model,
1447
1452
  async_mode: bool,
1448
- is_python_3_file: bool,
1453
+ is_python3_file: bool,
1449
1454
  ) -> _OperationBaseSerializer:
1450
1455
  retcls = _OperationBaseSerializer
1451
1456
  if isinstance(builder, LROPagingOperation):
1452
1457
  retcls = (
1453
1458
  AsyncLROPagingOperationSerializer if async_mode
1454
1459
  else (
1455
- SyncLROPagingOperationPython3Serializer if is_python_3_file
1460
+ SyncLROPagingOperationPython3Serializer if is_python3_file
1456
1461
  else SyncLROPagingOperationGenericSerializer
1457
1462
  )
1458
1463
  )
@@ -1460,22 +1465,22 @@ def get_operation_serializer(
1460
1465
  if isinstance(builder, LROOperation):
1461
1466
  retcls = (
1462
1467
  AsyncLROOperationSerializer if async_mode
1463
- else (SyncLROOperationPython3Serializer if is_python_3_file else SyncLROOperationGenericSerializer)
1468
+ else (SyncLROOperationPython3Serializer if is_python3_file else SyncLROOperationGenericSerializer)
1464
1469
  )
1465
1470
  return retcls(code_model)
1466
1471
  if isinstance(builder, PagingOperation):
1467
1472
  retcls = (
1468
1473
  AsyncPagingOperationSerializer if async_mode
1469
- else (SyncPagingOperationPython3Serializer if is_python_3_file else SyncPagingOperationGenericSerializer)
1474
+ else (SyncPagingOperationPython3Serializer if is_python3_file else SyncPagingOperationGenericSerializer)
1470
1475
  )
1471
1476
  return retcls(code_model)
1472
1477
  retcls = (
1473
1478
  AsyncOperationSerializer if async_mode
1474
- else (SyncOperationPython3Serializer if is_python_3_file else SyncOperationGenericSerializer)
1479
+ else (SyncOperationPython3Serializer if is_python3_file else SyncOperationGenericSerializer)
1475
1480
  )
1476
1481
  return retcls(code_model)
1477
1482
 
1478
1483
 
1479
- def get_request_builder_serializer(code_model, is_python_3_file: bool) -> _RequestBuilderBaseSerializer:
1480
- retcls = RequestBuilderPython3Serializer if is_python_3_file else RequestBuilderGenericSerializer
1484
+ def get_request_builder_serializer(code_model, is_python3_file: bool) -> _RequestBuilderBaseSerializer:
1485
+ retcls = RequestBuilderPython3Serializer if is_python3_file else RequestBuilderGenericSerializer
1481
1486
  return retcls(code_model)
@@ -9,27 +9,32 @@ from ..models import CodeModel
9
9
 
10
10
 
11
11
  class ClientSerializer:
12
- def __init__(self, code_model: CodeModel) -> None:
12
+ def __init__(self, code_model: CodeModel, is_python3_file: bool) -> None:
13
13
  self.code_model = code_model
14
+ self.is_python3_file = is_python3_file
14
15
 
15
16
  def _init_signature(self, async_mode: bool) -> str:
16
17
  return utils.serialize_method(
17
18
  function_def="def",
18
19
  method_name="__init__",
19
20
  is_in_class=True,
20
- method_param_signatures=self.code_model.service_client.parameters.client_method_signature(async_mode),
21
+ method_param_signatures=self.code_model.service_client.parameters.client_method_signature(
22
+ async_mode or self.is_python3_file
23
+ ),
21
24
  )
22
25
 
23
26
  def init_signature_and_response_type_annotation(self, async_mode: bool) -> str:
24
27
  init_signature = self._init_signature(async_mode)
25
28
  return utils.method_signature_and_response_type_annotation_template(
26
- is_python_3_file=async_mode,
29
+ is_python3_file=async_mode or self.is_python3_file,
27
30
  method_signature=init_signature,
28
31
  response_type_annotation="None",
29
32
  )
30
33
 
31
34
  def pop_kwargs_from_signature(self, async_mode: bool) -> List[str]:
32
- return utils.pop_kwargs_from_signature(self.code_model.service_client.parameters.kwargs_to_pop(async_mode))
35
+ return utils.pop_kwargs_from_signature(self.code_model.service_client.parameters.kwargs_to_pop(
36
+ async_mode or self.is_python3_file
37
+ ))
33
38
 
34
39
  def class_definition(self, async_mode) -> str:
35
40
  class_name = self.code_model.class_name
@@ -37,7 +42,7 @@ class ClientSerializer:
37
42
  base_class = ""
38
43
  if has_mixin_og:
39
44
  base_class = f"{class_name}OperationsMixin"
40
- elif not async_mode:
45
+ elif not (async_mode or self.is_python3_file):
41
46
  base_class = "object"
42
47
  if base_class:
43
48
  return f"class {class_name}({base_class}):"
@@ -107,13 +112,15 @@ class ClientSerializer:
107
112
  function_def="def",
108
113
  method_name=self.code_model.send_request_name,
109
114
  is_in_class=True,
110
- method_param_signatures=self.code_model.service_client.send_request_signature(async_mode),
115
+ method_param_signatures=self.code_model.service_client.send_request_signature(
116
+ async_mode, async_mode or self.is_python3_file
117
+ ),
111
118
  )
112
119
 
113
120
  def send_request_signature_and_response_type_annotation(self, async_mode: bool) -> str:
114
121
  send_request_signature = self._send_request_signature(async_mode)
115
122
  return utils.method_signature_and_response_type_annotation_template(
116
- is_python_3_file=async_mode,
123
+ is_python3_file=async_mode or self.is_python3_file,
117
124
  method_signature=send_request_signature,
118
125
  response_type_annotation="Awaitable[AsyncHttpResponse]" if async_mode else "HttpResponse",
119
126
  )
@@ -179,11 +186,32 @@ class ClientSerializer:
179
186
 
180
187
  class ConfigSerializer:
181
188
 
182
- def __init__(self, code_model: CodeModel) -> None:
189
+ def __init__(self, code_model: CodeModel, is_python3_file: bool) -> None:
183
190
  self.code_model = code_model
191
+ self.is_python3_file = is_python3_file
192
+
193
+ def _init_signature(self, async_mode: bool) -> str:
194
+ return utils.serialize_method(
195
+ function_def="def",
196
+ method_name="__init__",
197
+ is_in_class=True,
198
+ method_param_signatures=self.code_model.global_parameters.config_method_signature(
199
+ async_mode or self.is_python3_file
200
+ ),
201
+ )
202
+
203
+ def init_signature_and_response_type_annotation(self, async_mode: bool) -> str:
204
+ init_signature = self._init_signature(async_mode)
205
+ return utils.method_signature_and_response_type_annotation_template(
206
+ is_python3_file=async_mode or self.is_python3_file,
207
+ method_signature=init_signature,
208
+ response_type_annotation="None",
209
+ )
184
210
 
185
211
  def pop_kwargs_from_signature(self, async_mode: bool) -> List[str]:
186
- return utils.pop_kwargs_from_signature(self.code_model.global_parameters.config_kwargs_to_pop(async_mode))
212
+ return utils.pop_kwargs_from_signature(self.code_model.global_parameters.config_kwargs_to_pop(
213
+ async_mode or self.is_python3_file
214
+ ))
187
215
 
188
216
  def set_constants(self) -> List[str]:
189
217
  return [
@@ -54,13 +54,14 @@ class GeneralSerializer:
54
54
  ):
55
55
  self._correct_credential_parameter()
56
56
 
57
+ python3_only = self.code_model.options["python3_only"]
57
58
  return template.render(
58
59
  code_model=self.code_model,
59
60
  async_mode=self.async_mode,
60
- serializer=ClientSerializer(self.code_model),
61
+ serializer=ClientSerializer(self.code_model, is_python3_file=python3_only),
61
62
  imports=FileImportSerializer(
62
63
  self.code_model.service_client.imports(self.async_mode),
63
- is_python_3_file=self.async_mode
64
+ is_python3_file=self.async_mode or python3_only
64
65
  ),
65
66
  )
66
67
 
@@ -80,7 +81,7 @@ class GeneralSerializer:
80
81
  code_model=self.code_model,
81
82
  imports=FileImportSerializer(
82
83
  file_import,
83
- is_python_3_file=self.async_mode,
84
+ is_python3_file=self.async_mode,
84
85
  )
85
86
  )
86
87
 
@@ -99,15 +100,16 @@ class GeneralSerializer:
99
100
  self._correct_credential_parameter()
100
101
 
101
102
  template = self.env.get_template("config.py.jinja2")
103
+ python3_only = self.code_model.options["python3_only"]
102
104
  return template.render(
103
105
  code_model=self.code_model,
104
106
  async_mode=self.async_mode,
105
107
  imports=FileImportSerializer(
106
108
  config_imports(
107
109
  self.code_model, self.code_model.global_parameters, self.async_mode
108
- ), is_python_3_file=self.async_mode
110
+ ), is_python3_file=self.async_mode or python3_only
109
111
  ),
110
- serializer=ConfigSerializer(self.code_model),
112
+ serializer=ConfigSerializer(self.code_model, is_python3_file=python3_only),
111
113
  sdk_moniker=sdk_moniker,
112
114
  )
113
115
 
@@ -42,9 +42,9 @@ def _get_import_clauses(
42
42
 
43
43
 
44
44
  class FileImportSerializer:
45
- def __init__(self, file_import: FileImport, is_python_3_file: bool, async_mode: bool = False) -> None:
45
+ def __init__(self, file_import: FileImport, is_python3_file: bool, async_mode: bool = False) -> None:
46
46
  self._file_import = file_import
47
- self.is_python_3_file = is_python_3_file
47
+ self.is_python3_file = is_python3_file
48
48
  self.async_mode = async_mode
49
49
 
50
50
  def _switch_typing_section_key(self, new_key: TypingSection):
@@ -67,14 +67,14 @@ class FileImportSerializer:
67
67
  def _add_type_checking_import(self):
68
68
  if (
69
69
  self._file_import.imports.get(TypingSection.TYPING) or
70
- (not self.is_python_3_file and self._file_import.imports.get(TypingSection.CONDITIONAL))
70
+ (not self.is_python3_file and self._file_import.imports.get(TypingSection.CONDITIONAL))
71
71
  ):
72
72
  self._file_import.add_from_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
73
73
 
74
74
  def _get_typing_definitions(self) -> str:
75
75
  if not self._file_import.type_definitions:
76
76
  return ""
77
- spacing = "" if self.is_python_3_file else " "
77
+ spacing = "" if self.is_python3_file else " "
78
78
  declarations: List[str] = [f"\n{spacing}T = TypeVar('T')"]
79
79
  declarations.extend([
80
80
  "{}{} = {}".format(
@@ -90,7 +90,7 @@ class FileImportSerializer:
90
90
  self._add_type_checking_import()
91
91
  regular_imports = ""
92
92
  regular_imports_dict = self._get_imports_dict(
93
- baseline_typing_section=TypingSection.REGULAR, add_conditional_typing=self.is_python_3_file
93
+ baseline_typing_section=TypingSection.REGULAR, add_conditional_typing=self.is_python3_file
94
94
  )
95
95
 
96
96
  if regular_imports_dict:
@@ -100,7 +100,7 @@ class FileImportSerializer:
100
100
 
101
101
  typing_imports = ""
102
102
  typing_imports_dict = self._get_imports_dict(
103
- baseline_typing_section=TypingSection.TYPING, add_conditional_typing=not self.is_python_3_file
103
+ baseline_typing_section=TypingSection.TYPING, add_conditional_typing=not self.is_python3_file
104
104
  )
105
105
  if typing_imports_dict:
106
106
  typing_imports += "\n\nif TYPE_CHECKING:\n # pylint: disable=unused-import,ungrouped-imports\n "
@@ -185,9 +185,9 @@ class MetadataSerializer:
185
185
  config_imports(self.code_model, async_global_parameters, async_mode=True).imports
186
186
  ),
187
187
  get_async_operation_serializer=functools.partial(
188
- get_operation_serializer, code_model=self.code_model, async_mode=True, is_python_3_file=True
188
+ get_operation_serializer, code_model=self.code_model, async_mode=True, is_python3_file=True
189
189
  ),
190
190
  get_sync_operation_serializer=functools.partial(
191
- get_operation_serializer, code_model=self.code_model, async_mode=False, is_python_3_file=False
191
+ get_operation_serializer, code_model=self.code_model, async_mode=False, is_python3_file=False
192
192
  ),
193
193
  )
@@ -24,17 +24,17 @@ def _documentation_string(
24
24
 
25
25
 
26
26
  class ModelBaseSerializer:
27
- def __init__(self, code_model: CodeModel, env: Environment, is_python_3_file: bool) -> None:
27
+ def __init__(self, code_model: CodeModel, env: Environment, is_python3_file: bool) -> None:
28
28
  self.code_model = code_model
29
29
  self.env = env
30
- self.is_python_3_file = is_python_3_file
30
+ self.is_python3_file = is_python3_file
31
31
 
32
32
  def serialize(self) -> str:
33
33
  # Generate the models
34
34
  template = self.env.get_template("model_container.py.jinja2")
35
35
  return template.render(
36
36
  code_model=self.code_model,
37
- imports=FileImportSerializer(self.imports(), is_python_3_file=self.is_python_3_file),
37
+ imports=FileImportSerializer(self.imports(), is_python3_file=self.is_python3_file),
38
38
  str=str,
39
39
  init_line=self.init_line,
40
40
  init_args=self.init_args,
@@ -13,7 +13,7 @@ class ModelGenericSerializer(ModelBaseSerializer):
13
13
 
14
14
  def __init__(self, code_model: CodeModel, env: Environment) -> None:
15
15
  super(ModelGenericSerializer, self).__init__(
16
- code_model=code_model, env=env, is_python_3_file=False
16
+ code_model=code_model, env=env, is_python3_file=False
17
17
  )
18
18
 
19
19
  def init_line(self, model: ObjectSchema) -> List[str]:
@@ -14,7 +14,7 @@ class ModelPython3Serializer(ModelBaseSerializer):
14
14
 
15
15
  def __init__(self, code_model: CodeModel, env: Environment) -> None:
16
16
  super(ModelPython3Serializer, self).__init__(
17
- code_model=code_model, env=env, is_python_3_file=True
17
+ code_model=code_model, env=env, is_python3_file=True
18
18
  )
19
19
 
20
20
  def init_line(self, model: ObjectSchema) -> List[str]:
@@ -3,30 +3,34 @@
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 Optional
6
7
  import functools
7
- from copy import copy
8
- from typing import List
9
8
  from jinja2 import Environment
10
9
 
10
+ from ..models import (
11
+ CodeModel,
12
+ OperationGroup,
13
+ FileImport,
14
+ LROOperation,
15
+ PagingOperation
16
+ )
11
17
  from .import_serializer import FileImportSerializer
12
- from ..models import LROOperation, PagingOperation, CodeModel, OperationGroup
13
18
  from .builder_serializer import get_operation_serializer, get_request_builder_serializer
14
19
 
15
-
16
- class OperationGroupSerializer:
20
+ class OperationGroupsSerializer:
17
21
  def __init__(
18
22
  self,
19
23
  code_model: CodeModel,
20
24
  env: Environment,
21
- operation_groups: List[OperationGroup],
22
25
  async_mode: bool,
23
- is_python_3_file: bool,
26
+ is_python3_file: bool,
27
+ operation_group: Optional[OperationGroup] = None,
24
28
  ) -> None:
25
29
  self.code_model = code_model
26
30
  self.env = env
27
- self.operation_groups = operation_groups
28
31
  self.async_mode = async_mode
29
- self.is_python_3_file = is_python_3_file
32
+ self.is_python3_file = is_python3_file
33
+ self.operation_group = operation_group
30
34
 
31
35
  def serialize(self) -> str:
32
36
  def _is_lro(operation):
@@ -34,39 +38,33 @@ class OperationGroupSerializer:
34
38
 
35
39
  def _is_paging(operation):
36
40
  return isinstance(operation, PagingOperation)
41
+ operation_groups = [self.operation_group] if self.operation_group else self.code_model.operation_groups
42
+ imports = FileImport()
43
+ for operation_group in operation_groups:
44
+ imports.merge(operation_group.imports(
45
+ async_mode=self.async_mode,
46
+ ))
37
47
 
38
- operation_group_template = self.env.get_template("operations_container.py.jinja2")
39
- if not self.code_model.options["combine_operation_files"] and self.operation_groups[0].is_empty_operation_group:
40
- operation_group_template = self.env.get_template("operations_container_mixin.py.jinja2")
41
-
42
- has_schemas = self.code_model.schemas or self.code_model.enums
43
-
44
- # extract all operations from operation_groups
45
- operaions_all = [operation for groups in self.operation_groups for operation in groups.operations]
46
- operation_group_temp = copy(self.operation_groups[0])
47
- operation_group_temp.operations = operaions_all
48
-
49
- return operation_group_template.render(
48
+ template = self.env.get_or_select_template("operation_groups_container.py.jinja2")
49
+ return template.render(
50
50
  code_model=self.code_model,
51
- operation_groups=self.operation_groups,
51
+ operation_groups=operation_groups,
52
52
  imports=FileImportSerializer(
53
- operation_group_temp.imports(
54
- async_mode=self.async_mode,
55
- has_schemas=bool(has_schemas)
56
- ), is_python_3_file=self.is_python_3_file,
53
+ imports,
54
+ is_python3_file=self.is_python3_file,
57
55
  async_mode=self.async_mode
58
56
  ),
59
57
  async_mode=self.async_mode,
60
- is_python_3_file=self.is_python_3_file,
58
+ is_python3_file=self.is_python3_file,
61
59
  is_lro=_is_lro,
62
60
  is_paging=_is_paging,
63
61
  get_operation_serializer=functools.partial(
64
62
  get_operation_serializer,
65
63
  code_model=self.code_model,
66
64
  async_mode=self.async_mode,
67
- is_python_3_file=self.is_python_3_file,
65
+ is_python3_file=self.is_python3_file,
68
66
  ),
69
67
  request_builder_serializer=get_request_builder_serializer(
70
- self.code_model, self.is_python_3_file,
68
+ self.code_model, self.is_python3_file,
71
69
  ),
72
70
  )
@@ -3,7 +3,10 @@
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 List
6
7
  from jinja2 import Environment
8
+
9
+ from autorest.codegen.models.operation_group import OperationGroup
7
10
  from ..models import CodeModel
8
11
 
9
12
 
@@ -13,9 +16,38 @@ class OperationsInitSerializer:
13
16
  self.env = env
14
17
  self.async_mode = async_mode
15
18
 
19
+ def _operation_group_imports_helper(self, filename_suffix: str = "") -> List[str]:
20
+ def _get_filename(operation_group: OperationGroup) -> str:
21
+ prefix = "_operations" if self.code_model.options["combine_operation_files"] else operation_group.filename
22
+ return prefix + filename_suffix
23
+ return [
24
+ f"from .{_get_filename(og)} import {og.class_name}"
25
+ for og in self.code_model.operation_groups
26
+ ]
27
+
28
+ def operation_group_imports(self) -> List[str]:
29
+ typed_py3_files = self.code_model.options["add_python3_operation_files"]
30
+ py3_only = self.code_model.options["python3_only"]
31
+ if typed_py3_files and not py3_only and not self.async_mode:
32
+ retval: List[str] = ["try:"]
33
+ retval.extend([
34
+ f" {line}"
35
+ for line in self._operation_group_imports_helper(filename_suffix="_py3")
36
+ ])
37
+ retval.append("except (SyntaxError, ImportError):")
38
+ retval.extend([
39
+ f" {line}"
40
+ for line in self._operation_group_imports_helper()
41
+ ])
42
+ return retval
43
+ return self._operation_group_imports_helper()
44
+
16
45
  def serialize(self) -> str:
17
- operation_group_init_template = self.env.get_template("operations_container_init.py.jinja2")
46
+ operation_group_init_template = self.env.get_template("operations_folder_init.py.jinja2")
18
47
 
19
48
  return operation_group_init_template.render(
20
- code_model=self.code_model, operation_groups=self.code_model.operation_groups, async_mode=self.async_mode
49
+ code_model=self.code_model,
50
+ operation_groups=self.code_model.operation_groups,
51
+ async_mode=self.async_mode,
52
+ operation_group_imports=self.operation_group_imports,
21
53
  )
@@ -0,0 +1,15 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+ from jinja2 import Environment
7
+
8
+
9
+ class PatchSerializer:
10
+ def __init__(self, env: Environment) -> None:
11
+ self.env = env
12
+
13
+ def serialize(self) -> str:
14
+ template = self.env.get_template("patch.py.jinja2")
15
+ return template.render()
@@ -20,6 +20,7 @@ class RestSerializer:
20
20
  self.code_model = code_model
21
21
  self.env = env
22
22
  self.request_builders = request_builders
23
+ self.builder_group_name = request_builders[0].builder_group_name
23
24
 
24
25
  def serialize_init(self) -> str:
25
26
  template = self.env.get_template("rest_init.py.jinja2")
@@ -33,8 +34,10 @@ class RestPython3Serializer(RestSerializer):
33
34
  return template.render(
34
35
  code_model=self.code_model,
35
36
  request_builders=self.request_builders,
36
- imports=FileImportSerializer(self.code_model.rest.imports(), is_python_3_file=True),
37
- is_python_3_file=True,
37
+ imports=FileImportSerializer(self.code_model.rest.imports(
38
+ self.builder_group_name
39
+ ), is_python3_file=True),
40
+ is_python3_file=True,
38
41
  request_builder_serializer=RequestBuilderPython3Serializer(self.code_model),
39
42
  )
40
43
 
@@ -46,7 +49,9 @@ class RestGenericSerializer(RestSerializer):
46
49
  return template.render(
47
50
  code_model=self.code_model,
48
51
  request_builders=self.request_builders,
49
- imports=FileImportSerializer(self.code_model.rest.imports(), is_python_3_file=False),
50
- is_python_3_file=False,
52
+ imports=FileImportSerializer(self.code_model.rest.imports(
53
+ self.builder_group_name
54
+ ), is_python3_file=False),
55
+ is_python3_file=False,
51
56
  request_builder_serializer=RequestBuilderGenericSerializer(self.code_model),
52
57
  )
@@ -90,11 +90,11 @@ def serialize_path(
90
90
 
91
91
  def method_signature_and_response_type_annotation_template(
92
92
  *,
93
- is_python_3_file: bool,
93
+ is_python3_file: bool,
94
94
  method_signature: str,
95
95
  response_type_annotation: str,
96
96
  ) -> str:
97
- if is_python_3_file:
97
+ if is_python3_file:
98
98
  return f"{method_signature} -> {response_type_annotation}:"
99
99
  return f"{method_signature}:\n # type: (...) -> {response_type_annotation}"
100
100