@autorest/python 5.10.0 → 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 (57) hide show
  1. package/ChangeLog.md +74 -0
  2. package/autorest/codegen/__init__.py +7 -7
  3. package/autorest/codegen/models/__init__.py +2 -1
  4. package/autorest/codegen/models/base_builder.py +16 -8
  5. package/autorest/codegen/models/client.py +5 -3
  6. package/autorest/codegen/models/code_model.py +19 -5
  7. package/autorest/codegen/models/imports.py +7 -0
  8. package/autorest/codegen/models/lro_operation.py +7 -3
  9. package/autorest/codegen/models/object_schema.py +3 -3
  10. package/autorest/codegen/models/operation.py +69 -38
  11. package/autorest/codegen/models/operation_group.py +13 -8
  12. package/autorest/codegen/models/paging_operation.py +5 -2
  13. package/autorest/codegen/models/parameter.py +46 -13
  14. package/autorest/codegen/models/parameter_list.py +62 -70
  15. package/autorest/codegen/models/primitive_schemas.py +11 -0
  16. package/autorest/codegen/models/request_builder.py +21 -8
  17. package/autorest/codegen/models/request_builder_parameter.py +9 -5
  18. package/autorest/codegen/models/request_builder_parameter_list.py +179 -77
  19. package/autorest/codegen/models/rest.py +3 -2
  20. package/autorest/codegen/models/schema_request.py +4 -17
  21. package/autorest/codegen/models/schema_response.py +4 -4
  22. package/autorest/codegen/serializers/__init__.py +57 -53
  23. package/autorest/codegen/serializers/builder_serializer.py +76 -46
  24. package/autorest/codegen/serializers/client_serializer.py +37 -9
  25. package/autorest/codegen/serializers/general_serializer.py +7 -5
  26. package/autorest/codegen/serializers/import_serializer.py +22 -7
  27. package/autorest/codegen/serializers/metadata_serializer.py +2 -2
  28. package/autorest/codegen/serializers/model_base_serializer.py +3 -3
  29. package/autorest/codegen/serializers/model_generic_serializer.py +1 -1
  30. package/autorest/codegen/serializers/model_python3_serializer.py +1 -1
  31. package/autorest/codegen/serializers/operation_groups_serializer.py +70 -0
  32. package/autorest/codegen/serializers/operations_init_serializer.py +34 -2
  33. package/autorest/codegen/serializers/patch_serializer.py +15 -0
  34. package/autorest/codegen/serializers/rest_serializer.py +9 -4
  35. package/autorest/codegen/serializers/utils.py +2 -2
  36. package/autorest/codegen/templates/config.py.jinja2 +1 -11
  37. package/autorest/codegen/templates/init.py.jinja2 +4 -7
  38. package/autorest/codegen/templates/metadata.json.jinja2 +2 -2
  39. package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
  40. package/autorest/codegen/templates/{operations_class.py.jinja2 → operation_group.py.jinja2} +2 -0
  41. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +26 -0
  42. package/autorest/codegen/templates/operation_tools.jinja2 +7 -0
  43. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +13 -0
  44. package/autorest/codegen/templates/patch.py.jinja2 +31 -0
  45. package/autorest/codegen/templates/request_builder.py.jinja2 +7 -2
  46. package/autorest/codegen/templates/request_builders.py.jinja2 +3 -3
  47. package/autorest/codegen/templates/setup.py.jinja2 +1 -1
  48. package/autorest/multiapi/serializers/__init__.py +3 -3
  49. package/autorest/multiapi/serializers/import_serializer.py +5 -5
  50. package/autorest/namer/name_converter.py +48 -3
  51. package/package.json +2 -2
  52. package/setup.py +1 -0
  53. package/autorest/codegen/serializers/operation_group_serializer.py +0 -71
  54. package/autorest/codegen/templates/operations_class_mixin.py.jinja2 +0 -16
  55. package/autorest/codegen/templates/operations_container.py.jinja2 +0 -42
  56. package/autorest/codegen/templates/operations_container_init.py.jinja2 +0 -24
  57. package/autorest/codegen/templates/operations_container_mixin.py.jinja2 +0 -23
@@ -21,12 +21,13 @@ from ..models import (
21
21
  DictionarySchema,
22
22
  ListSchema,
23
23
  BaseSchema,
24
- SchemaRequest,
25
24
  Parameter,
26
25
  RequestBuilder,
27
26
  RequestBuilderParameter,
28
27
  EnumSchema,
29
28
  SchemaResponse,
29
+ IOSchema,
30
+ ParameterStyle,
30
31
  )
31
32
  from . import utils
32
33
 
@@ -56,7 +57,7 @@ def _json_dumps_template(template_representation: Any) -> Any:
56
57
  def _serialize_files_or_data_dict(multipart_parameters: List[Parameter]) -> str:
57
58
  # only for template use
58
59
  template = {
59
- param.serialized_name: param.schema.get_files_and_data_template_representation(
60
+ f'"{param.serialized_name}"': param.schema.get_files_and_data_template_representation(
60
61
  optional=not param.required,
61
62
  description=param.description,
62
63
  )
@@ -541,11 +542,11 @@ class RequestBuilderGenericSerializer(_RequestBuilderBaseSerializer):
541
542
  @staticmethod
542
543
  def _method_signature_and_response_type_annotation_template(method_signature: str, response_type_annotation: str):
543
544
  return utils.method_signature_and_response_type_annotation_template(
544
- 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
545
546
  )
546
547
 
547
548
  def _get_kwargs_to_pop(self, builder: BuilderType):
548
- return builder.parameters.kwargs_to_pop(is_python_3_file=False)
549
+ return builder.parameters.kwargs_to_pop(is_python3_file=False)
549
550
 
550
551
  def _body_params_to_pass_to_request_creation(self, builder: BuilderType) -> List[str]:
551
552
  if builder.parameters.has_body and not builder.parameters.body_kwarg_names:
@@ -563,11 +564,11 @@ class RequestBuilderPython3Serializer(_RequestBuilderBaseSerializer):
563
564
  @staticmethod
564
565
  def _method_signature_and_response_type_annotation_template(method_signature: str, response_type_annotation: str):
565
566
  return utils.method_signature_and_response_type_annotation_template(
566
- 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
567
568
  )
568
569
 
569
570
  def _get_kwargs_to_pop(self, builder: BuilderType):
570
- return builder.parameters.kwargs_to_pop(is_python_3_file=True)
571
+ return builder.parameters.kwargs_to_pop(is_python3_file=True)
571
572
 
572
573
  def _body_params_to_pass_to_request_creation(self, builder: BuilderType) -> List[str]:
573
574
  body_kwargs = list(builder.parameters.body_kwarg_names.keys())
@@ -620,7 +621,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
620
621
  def _response_type_annotation(self, builder: BuilderType, modify_if_head_as_boolean: bool = True) -> str:
621
622
  if (
622
623
  modify_if_head_as_boolean
623
- and builder.request_builder.method == "head"
624
+ and builder.request_builder.method.lower() == "head"
624
625
  and self.code_model.options["head_as_boolean"]
625
626
  ):
626
627
  return "bool"
@@ -643,7 +644,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
643
644
 
644
645
  def response_docstring(self, builder: BuilderType) -> List[str]:
645
646
  responses_with_body = [r for r in builder.responses if r.has_body]
646
- if builder.request_builder.method == "head" and self.code_model.options["head_as_boolean"]:
647
+ if builder.request_builder.method.lower() == "head" and self.code_model.options["head_as_boolean"]:
647
648
  response_docstring_text = "bool"
648
649
  rtype = "bool"
649
650
  elif responses_with_body:
@@ -690,28 +691,32 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
690
691
  return bool(builder.parameters.data_inputs)
691
692
 
692
693
  def _serialize_body_call(
693
- self, builder: BuilderType, send_xml: bool, ser_ctxt: Optional[str], ser_ctxt_name: str
694
+ self, builder: BuilderType, body_param: Parameter, send_xml: bool, ser_ctxt: Optional[str], ser_ctxt_name: str
694
695
  ) -> str:
695
- body_param = builder.parameters.body[0]
696
696
  body_is_xml = ", is_xml=True" if send_xml else ""
697
697
  pass_ser_ctxt = f", {ser_ctxt_name}={ser_ctxt_name}" if ser_ctxt else ""
698
+ body_kwarg_to_pass = builder.body_kwargs_to_pass_to_request_builder[0]
698
699
  if self.code_model.options["models_mode"]:
699
700
  return (
700
- f"{builder.serialized_body_kwarg} = self._serialize.body({body_param.serialized_name}, "
701
+ f"_{body_kwarg_to_pass} = self._serialize.body({body_param.serialized_name}, "
701
702
  f"'{ body_param.serialization_type }'{body_is_xml}{ pass_ser_ctxt })"
702
703
  )
703
- return f"{builder.serialized_body_kwarg} = {body_param.serialized_name}"
704
+ return f"_{body_kwarg_to_pass} = {body_param.serialized_name}"
704
705
 
705
- def _serialize_body(self, builder: BuilderType) -> List[str]:
706
+ def _serialize_body(self, builder: BuilderType, body_param: Parameter, body_kwarg: str) -> List[str]:
706
707
  retval = []
707
- send_xml = bool(builder.parameters.has_body and any(["xml" in ct for ct in builder.parameters.content_types]))
708
+ send_xml = bool(
709
+ builder.parameters.has_body and
710
+ any(["xml" in ct for ct in builder.parameters.content_types]) and
711
+ not isinstance(body_param.schema, IOSchema)
712
+ )
708
713
  ser_ctxt_name = "serialization_ctxt"
709
714
  ser_ctxt = builder.parameters.body[0].xml_serialization_ctxt if send_xml else None
710
715
  if ser_ctxt:
711
716
  retval.append(f'{ser_ctxt_name} = {{"xml": {{{ser_ctxt}}}}}')
712
- body_param = builder.parameters.body[0]
713
717
  serialize_body_call = self._serialize_body_call(
714
718
  builder,
719
+ body_param,
715
720
  send_xml,
716
721
  ser_ctxt,
717
722
  ser_ctxt_name,
@@ -723,15 +728,22 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
723
728
  retval.append(" " + serialize_body_call)
724
729
  if len(builder.body_kwargs_to_pass_to_request_builder) == 1:
725
730
  retval.append("else:")
726
- retval.append(f" {builder.serialized_body_kwarg} = None")
731
+ retval.append(f" _{body_kwarg} = None")
727
732
  return retval
728
733
 
729
- def _set_body_content_kwarg(self, builder: BuilderType, schema_request: SchemaRequest):
730
- retval = []
731
- if schema_request.is_stream_request:
732
- retval.append(f"content = {builder.parameters.body[0].serialized_name}")
733
- elif schema_request.body_parameter_has_schema and not builder.request_builder.multipart:
734
- retval.extend(self._serialize_body(builder))
734
+ def _set_body_content_kwarg(
735
+ self, builder: BuilderType, body_param: Parameter, body_kwarg: Parameter
736
+ ) -> List[str]:
737
+ retval: List[str] = []
738
+ if body_kwarg.serialized_name == "data" or body_kwarg.serialized_name == "files":
739
+ return retval
740
+ try:
741
+ if not body_param.style == ParameterStyle.binary:
742
+ retval.extend(self._serialize_body(builder, body_param, body_kwarg.serialized_name))
743
+ return retval
744
+ except AttributeError:
745
+ pass
746
+ retval.append(f"_{body_kwarg.serialized_name} = {body_param.serialized_name}")
735
747
  return retval
736
748
 
737
749
 
@@ -739,15 +751,28 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
739
751
  self, builder: BuilderType,
740
752
  ) -> List[str]:
741
753
  retval = []
742
- if len(builder.request_builder.schema_requests) == 1:
743
- retval.extend(self._set_body_content_kwarg(builder, builder.request_builder.schema_requests[0]))
754
+ body_kwargs = [
755
+ p for p in builder.request_builder.parameters.body
756
+ if p.content_types
757
+ ]
758
+ builder_params = []
759
+ if builder.parameters.has_body:
760
+ builder_params += builder.parameters.body
761
+ if builder.multiple_content_type_parameters.has_body:
762
+ builder_params += builder.multiple_content_type_parameters.body
763
+ if len(body_kwargs) == 1:
764
+ retval.extend(self._set_body_content_kwarg(builder, builder.parameters.body[0], body_kwargs[0]))
744
765
  else:
745
- for idx, schema_request in enumerate(builder.request_builder.schema_requests):
766
+ for idx, body_kwarg in enumerate(body_kwargs):
767
+ body_param = next(
768
+ b for b in builder_params
769
+ if body_kwarg in b.body_kwargs
770
+ )
746
771
  if_statement = "if" if idx == 0 else "elif"
747
772
  retval.append(
748
- f'{if_statement} content_type.split(";")[0] in {schema_request.pre_semicolon_media_types}:'
773
+ f'{if_statement} content_type.split(";")[0] in {body_kwarg.pre_semicolon_content_types}:'
749
774
  )
750
- retval.extend([" " + line for line in self._set_body_content_kwarg(builder, schema_request)])
775
+ retval.extend([" " + line for line in self._set_body_content_kwarg(builder, body_param, body_kwarg)])
751
776
  retval.extend(_content_type_error_check(builder))
752
777
 
753
778
  return retval
@@ -765,7 +790,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
765
790
  if self.code_model.options["version_tolerant"]:
766
791
  body_params_to_initialize = [p for p in body_params_to_initialize if p != "files"]
767
792
  for k in body_params_to_initialize:
768
- retval.append(f"{k} = None")
793
+ retval.append(f"_{k} = None")
769
794
  if builder.parameters.grouped:
770
795
  # request builders don't allow grouped parameters, so we group them before making the call
771
796
  retval.extend(_serialize_grouped_body(builder))
@@ -774,8 +799,8 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
774
799
  # unflatten before passing to request builder as well
775
800
  retval.extend(_serialize_flattened_body(builder))
776
801
  if request_builder.multipart or request_builder.parameters.data_inputs:
777
- param_name = "files" if request_builder.multipart else "data"
778
802
  if not self.code_model.options["version_tolerant"]:
803
+ param_name = "_files" if request_builder.multipart else "_data"
779
804
  retval.extend(_serialize_files_and_data_body(builder, param_name))
780
805
  elif builder.parameters.has_body and not builder.parameters.body[0].constant:
781
806
  retval.extend(self._serialize_body_parameters(builder))
@@ -798,18 +823,23 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
798
823
  continue
799
824
  high_level_name = cast(RequestBuilderParameter, parameter).name_in_high_level_operation
800
825
  retval.append(f" {parameter.serialized_name}={high_level_name},")
801
- template_url = template_url or f"self.{builder.name}.metadata['url']"
802
- 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},")
803
829
  retval.append(f")")
804
830
  if not self.code_model.options["version_tolerant"]:
805
831
  pass_files = ""
806
832
  if "files" in builder.body_kwargs_to_pass_to_request_builder:
807
- pass_files = ", files"
833
+ pass_files = ", _files"
808
834
  retval.append(f"request = _convert_request(request{pass_files})")
809
835
  if builder.parameters.path:
810
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
811
840
  retval.append(
812
- "request.url = self._client.format_url(request.url{})".format(
841
+ "request.url = self._client.format_url({}{})".format(
842
+ url_to_format,
813
843
  ", **path_format_arguments" if builder.parameters.path else ""
814
844
  )
815
845
  )
@@ -842,7 +872,7 @@ class _OperationBaseSerializer(_BuilderBaseSerializer): # pylint: disable=abstr
842
872
  if self.code_model.options["models_mode"]:
843
873
  retval.append(f"deserialized = self._deserialize('{response.serialization_type}', pipeline_response)")
844
874
  else:
845
- is_xml = any(["xml" in ct for ct in response.media_types])
875
+ is_xml = any(["xml" in ct for ct in response.content_types])
846
876
  deserialized_value = ""
847
877
  deserialized_value = "ET.fromstring(response.text())" if is_xml else "response.json()"
848
878
  retval.append(f"if response.content:")
@@ -980,11 +1010,11 @@ class SyncOperationGenericSerializer(_SyncOperationBaseSerializer):
980
1010
  @staticmethod
981
1011
  def _method_signature_and_response_type_annotation_template(method_signature: str, response_type_annotation: str):
982
1012
  return utils.method_signature_and_response_type_annotation_template(
983
- 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
984
1014
  )
985
1015
 
986
1016
  def _get_kwargs_to_pop(self, builder: BuilderType):
987
- return builder.parameters.kwargs_to_pop(is_python_3_file=False)
1017
+ return builder.parameters.kwargs_to_pop(is_python3_file=False)
988
1018
 
989
1019
 
990
1020
  class SyncOperationPython3Serializer(_SyncOperationBaseSerializer):
@@ -995,11 +1025,11 @@ class SyncOperationPython3Serializer(_SyncOperationBaseSerializer):
995
1025
  @staticmethod
996
1026
  def _method_signature_and_response_type_annotation_template(method_signature: str, response_type_annotation: str):
997
1027
  return utils.method_signature_and_response_type_annotation_template(
998
- 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
999
1029
  )
1000
1030
 
1001
1031
  def _get_kwargs_to_pop(self, builder: BuilderType):
1002
- return builder.parameters.kwargs_to_pop(is_python_3_file=True)
1032
+ return builder.parameters.kwargs_to_pop(is_python3_file=True)
1003
1033
 
1004
1034
  class AsyncOperationSerializer(SyncOperationPython3Serializer):
1005
1035
 
@@ -1032,7 +1062,7 @@ class _PagingOperationBaseSerializer(_OperationBaseSerializer): # pylint: disab
1032
1062
  def call_next_link_request_builder(self, builder: BuilderType) -> List[str]:
1033
1063
  if builder.next_request_builder:
1034
1064
  request_builder = builder.next_request_builder
1035
- template_url = f"'{request_builder.url}'"
1065
+ template_url = None if self.code_model.options["version_tolerant"] else f"'{request_builder.url}'"
1036
1066
  else:
1037
1067
  request_builder = builder.request_builder
1038
1068
  template_url = "next_link"
@@ -1420,14 +1450,14 @@ def get_operation_serializer(
1420
1450
  builder: BuilderType,
1421
1451
  code_model,
1422
1452
  async_mode: bool,
1423
- is_python_3_file: bool,
1453
+ is_python3_file: bool,
1424
1454
  ) -> _OperationBaseSerializer:
1425
1455
  retcls = _OperationBaseSerializer
1426
1456
  if isinstance(builder, LROPagingOperation):
1427
1457
  retcls = (
1428
1458
  AsyncLROPagingOperationSerializer if async_mode
1429
1459
  else (
1430
- SyncLROPagingOperationPython3Serializer if is_python_3_file
1460
+ SyncLROPagingOperationPython3Serializer if is_python3_file
1431
1461
  else SyncLROPagingOperationGenericSerializer
1432
1462
  )
1433
1463
  )
@@ -1435,22 +1465,22 @@ def get_operation_serializer(
1435
1465
  if isinstance(builder, LROOperation):
1436
1466
  retcls = (
1437
1467
  AsyncLROOperationSerializer if async_mode
1438
- else (SyncLROOperationPython3Serializer if is_python_3_file else SyncLROOperationGenericSerializer)
1468
+ else (SyncLROOperationPython3Serializer if is_python3_file else SyncLROOperationGenericSerializer)
1439
1469
  )
1440
1470
  return retcls(code_model)
1441
1471
  if isinstance(builder, PagingOperation):
1442
1472
  retcls = (
1443
1473
  AsyncPagingOperationSerializer if async_mode
1444
- else (SyncPagingOperationPython3Serializer if is_python_3_file else SyncPagingOperationGenericSerializer)
1474
+ else (SyncPagingOperationPython3Serializer if is_python3_file else SyncPagingOperationGenericSerializer)
1445
1475
  )
1446
1476
  return retcls(code_model)
1447
1477
  retcls = (
1448
1478
  AsyncOperationSerializer if async_mode
1449
- else (SyncOperationPython3Serializer if is_python_3_file else SyncOperationGenericSerializer)
1479
+ else (SyncOperationPython3Serializer if is_python3_file else SyncOperationGenericSerializer)
1450
1480
  )
1451
1481
  return retcls(code_model)
1452
1482
 
1453
1483
 
1454
- def get_request_builder_serializer(code_model, is_python_3_file: bool) -> _RequestBuilderBaseSerializer:
1455
- 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
1456
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,10 @@ def _get_import_clauses(
42
42
 
43
43
 
44
44
  class FileImportSerializer:
45
- def __init__(self, file_import: FileImport, is_python_3_file: bool) -> 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
+ self.async_mode = async_mode
48
49
 
49
50
  def _switch_typing_section_key(self, new_key: TypingSection):
50
51
  switched_dictionary = {}
@@ -66,15 +67,30 @@ class FileImportSerializer:
66
67
  def _add_type_checking_import(self):
67
68
  if (
68
69
  self._file_import.imports.get(TypingSection.TYPING) or
69
- (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))
70
71
  ):
71
72
  self._file_import.add_from_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
72
73
 
74
+ def _get_typing_definitions(self) -> str:
75
+ if not self._file_import.type_definitions:
76
+ return ""
77
+ spacing = "" if self.is_python3_file else " "
78
+ declarations: List[str] = [f"\n{spacing}T = TypeVar('T')"]
79
+ declarations.extend([
80
+ "{}{} = {}".format(
81
+ spacing,
82
+ type_name,
83
+ values[1] if self.async_mode else values[0]
84
+ )
85
+ for type_name, values in self._file_import.type_definitions.items()
86
+ ])
87
+ return "\n".join(declarations)
88
+
73
89
  def __str__(self) -> str:
74
90
  self._add_type_checking_import()
75
91
  regular_imports = ""
76
92
  regular_imports_dict = self._get_imports_dict(
77
- 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
78
94
  )
79
95
 
80
96
  if regular_imports_dict:
@@ -84,10 +100,9 @@ class FileImportSerializer:
84
100
 
85
101
  typing_imports = ""
86
102
  typing_imports_dict = self._get_imports_dict(
87
- 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
88
104
  )
89
105
  if typing_imports_dict:
90
106
  typing_imports += "\n\nif TYPE_CHECKING:\n # pylint: disable=unused-import,ungrouped-imports\n "
91
107
  typing_imports += "\n\n ".join(_get_import_clauses(typing_imports_dict, "\n "))
92
-
93
- return regular_imports + typing_imports
108
+ return regular_imports + typing_imports + self._get_typing_definitions()
@@ -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]:
@@ -0,0 +1,70 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+ from typing import Optional
7
+ import functools
8
+ from jinja2 import Environment
9
+
10
+ from ..models import (
11
+ CodeModel,
12
+ OperationGroup,
13
+ FileImport,
14
+ LROOperation,
15
+ PagingOperation
16
+ )
17
+ from .import_serializer import FileImportSerializer
18
+ from .builder_serializer import get_operation_serializer, get_request_builder_serializer
19
+
20
+ class OperationGroupsSerializer:
21
+ def __init__(
22
+ self,
23
+ code_model: CodeModel,
24
+ env: Environment,
25
+ async_mode: bool,
26
+ is_python3_file: bool,
27
+ operation_group: Optional[OperationGroup] = None,
28
+ ) -> None:
29
+ self.code_model = code_model
30
+ self.env = env
31
+ self.async_mode = async_mode
32
+ self.is_python3_file = is_python3_file
33
+ self.operation_group = operation_group
34
+
35
+ def serialize(self) -> str:
36
+ def _is_lro(operation):
37
+ return isinstance(operation, LROOperation)
38
+
39
+ def _is_paging(operation):
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
+ ))
47
+
48
+ template = self.env.get_or_select_template("operation_groups_container.py.jinja2")
49
+ return template.render(
50
+ code_model=self.code_model,
51
+ operation_groups=operation_groups,
52
+ imports=FileImportSerializer(
53
+ imports,
54
+ is_python3_file=self.is_python3_file,
55
+ async_mode=self.async_mode
56
+ ),
57
+ async_mode=self.async_mode,
58
+ is_python3_file=self.is_python3_file,
59
+ is_lro=_is_lro,
60
+ is_paging=_is_paging,
61
+ get_operation_serializer=functools.partial(
62
+ get_operation_serializer,
63
+ code_model=self.code_model,
64
+ async_mode=self.async_mode,
65
+ is_python3_file=self.is_python3_file,
66
+ ),
67
+ request_builder_serializer=get_request_builder_serializer(
68
+ self.code_model, self.is_python3_file,
69
+ ),
70
+ )