@autorest/python 5.13.0 → 5.16.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 (101) hide show
  1. package/ChangeLog.md +67 -0
  2. package/autorest/__init__.py +1 -2
  3. package/autorest/black/__init__.py +12 -5
  4. package/autorest/codegen/__init__.py +239 -105
  5. package/autorest/codegen/models/__init__.py +29 -18
  6. package/autorest/codegen/models/base_builder.py +48 -11
  7. package/autorest/codegen/models/base_model.py +6 -4
  8. package/autorest/codegen/models/base_schema.py +21 -24
  9. package/autorest/codegen/models/client.py +70 -20
  10. package/autorest/codegen/models/code_model.py +144 -129
  11. package/autorest/codegen/models/constant_schema.py +32 -16
  12. package/autorest/codegen/models/credential_model.py +55 -0
  13. package/autorest/codegen/models/credential_schema.py +21 -16
  14. package/autorest/codegen/models/credential_schema_policy.py +11 -15
  15. package/autorest/codegen/models/dictionary_schema.py +27 -24
  16. package/autorest/codegen/models/enum_schema.py +41 -62
  17. package/autorest/codegen/models/imports.py +72 -41
  18. package/autorest/codegen/models/list_schema.py +40 -18
  19. package/autorest/codegen/models/lro_operation.py +61 -25
  20. package/autorest/codegen/models/lro_paging_operation.py +5 -6
  21. package/autorest/codegen/models/object_schema.py +113 -59
  22. package/autorest/codegen/models/operation.py +251 -111
  23. package/autorest/codegen/models/operation_group.py +67 -32
  24. package/autorest/codegen/models/paging_operation.py +48 -21
  25. package/autorest/codegen/models/parameter.py +182 -90
  26. package/autorest/codegen/models/parameter_list.py +184 -163
  27. package/autorest/codegen/models/primitive_schemas.py +89 -70
  28. package/autorest/codegen/models/property.py +49 -31
  29. package/autorest/codegen/models/request_builder.py +67 -32
  30. package/autorest/codegen/models/request_builder_parameter.py +54 -23
  31. package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
  32. package/autorest/codegen/models/schema_request.py +16 -6
  33. package/autorest/codegen/models/schema_response.py +35 -17
  34. package/autorest/codegen/models/utils.py +24 -1
  35. package/autorest/codegen/serializers/__init__.py +273 -89
  36. package/autorest/codegen/serializers/builder_serializer.py +711 -333
  37. package/autorest/codegen/serializers/client_serializer.py +114 -43
  38. package/autorest/codegen/serializers/general_serializer.py +84 -25
  39. package/autorest/codegen/serializers/import_serializer.py +93 -31
  40. package/autorest/codegen/serializers/metadata_serializer.py +73 -24
  41. package/autorest/codegen/serializers/model_base_serializer.py +42 -14
  42. package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
  43. package/autorest/codegen/serializers/model_init_serializer.py +5 -1
  44. package/autorest/codegen/serializers/model_python3_serializer.py +9 -8
  45. package/autorest/codegen/serializers/operation_groups_serializer.py +20 -8
  46. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  47. package/autorest/codegen/serializers/patch_serializer.py +14 -2
  48. package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
  49. package/autorest/codegen/serializers/utils.py +60 -21
  50. package/autorest/codegen/templates/CHANGELOG.md.jinja2 +6 -0
  51. package/autorest/codegen/templates/LICENSE.jinja2 +21 -0
  52. package/autorest/codegen/templates/MANIFEST.in.jinja2 +7 -0
  53. package/autorest/codegen/templates/README.md.jinja2 +105 -0
  54. package/autorest/codegen/templates/config.py.jinja2 +4 -4
  55. package/autorest/codegen/templates/dev_requirements.txt.jinja2 +10 -0
  56. package/autorest/codegen/templates/enum.py.jinja2 +1 -1
  57. package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
  58. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  59. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  60. package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
  61. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
  62. package/autorest/codegen/templates/metadata.json.jinja2 +10 -9
  63. package/autorest/codegen/templates/model.py.jinja2 +1 -6
  64. package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
  65. package/autorest/codegen/templates/operation.py.jinja2 +8 -11
  66. package/autorest/codegen/templates/operation_group.py.jinja2 +15 -18
  67. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
  68. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  69. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  70. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  71. package/autorest/codegen/templates/request_builder.py.jinja2 +19 -14
  72. package/autorest/codegen/templates/setup.py.jinja2 +79 -20
  73. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  74. package/autorest/jsonrpc/__init__.py +7 -12
  75. package/autorest/jsonrpc/localapi.py +4 -3
  76. package/autorest/jsonrpc/server.py +13 -6
  77. package/autorest/jsonrpc/stdstream.py +13 -6
  78. package/autorest/m2r/__init__.py +5 -8
  79. package/autorest/multiapi/__init__.py +24 -14
  80. package/autorest/multiapi/models/client.py +21 -11
  81. package/autorest/multiapi/models/code_model.py +23 -10
  82. package/autorest/multiapi/models/config.py +4 -1
  83. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  84. package/autorest/multiapi/models/global_parameter.py +2 -1
  85. package/autorest/multiapi/models/global_parameters.py +14 -8
  86. package/autorest/multiapi/models/imports.py +35 -18
  87. package/autorest/multiapi/models/mixin_operation.py +5 -5
  88. package/autorest/multiapi/models/operation_group.py +2 -1
  89. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  90. package/autorest/multiapi/serializers/__init__.py +18 -23
  91. package/autorest/multiapi/serializers/import_serializer.py +47 -15
  92. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  93. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
  94. package/autorest/multiapi/utils.py +3 -3
  95. package/autorest/namer/__init__.py +2 -4
  96. package/autorest/namer/name_converter.py +200 -103
  97. package/autorest/namer/python_mappings.py +10 -22
  98. package/package.json +3 -3
  99. package/run-python3.js +2 -3
  100. package/venvtools.py +1 -1
  101. package/autorest/codegen/models/rest.py +0 -42
@@ -13,6 +13,7 @@ from .operation_mixin_group import OperationMixinGroup
13
13
  from .global_parameters import GlobalParameters
14
14
  from ..utils import _get_default_api_version_from_list
15
15
 
16
+
16
17
  class CodeModel: # pylint: disable=too-many-instance-attributes
17
18
  def __init__(
18
19
  self,
@@ -23,7 +24,7 @@ class CodeModel: # pylint: disable=too-many-instance-attributes
23
24
  default_version_metadata: Dict[str, Any],
24
25
  mod_to_api_version: Dict[str, str],
25
26
  version_path_to_metadata: Dict[Path, Dict[str, Any]],
26
- user_specified_default_api: Optional[str] = None
27
+ user_specified_default_api: Optional[str] = None,
27
28
  ):
28
29
  self.module_name = module_name
29
30
  self.package_name = package_name
@@ -33,9 +34,13 @@ class CodeModel: # pylint: disable=too-many-instance-attributes
33
34
  self.azure_arm = default_version_metadata["client"]["azure_arm"]
34
35
  self.default_version_metadata = default_version_metadata
35
36
  self.version_path_to_metadata = version_path_to_metadata
36
- self.service_client = Client(self.azure_arm, default_version_metadata, version_path_to_metadata)
37
+ self.service_client = Client(
38
+ self.azure_arm, default_version_metadata, version_path_to_metadata
39
+ )
37
40
  self.config = Config(default_version_metadata)
38
- self.operation_mixin_group = OperationMixinGroup(version_path_to_metadata, default_api_version)
41
+ self.operation_mixin_group = OperationMixinGroup(
42
+ version_path_to_metadata, default_api_version
43
+ )
39
44
  self.global_parameters = GlobalParameters(
40
45
  default_version_metadata["global_parameters"]
41
46
  )
@@ -45,17 +50,24 @@ class CodeModel: # pylint: disable=too-many-instance-attributes
45
50
  def operation_groups(self) -> List[OperationGroup]:
46
51
  operation_groups: List[OperationGroup] = []
47
52
  for version_path, metadata_json in self.version_path_to_metadata.items():
48
- if not metadata_json.get('operation_groups'):
53
+ if not metadata_json.get("operation_groups"):
49
54
  continue
50
- operation_groups_metadata = metadata_json['operation_groups']
51
- for operation_group_name, operation_group_class_name in operation_groups_metadata.items():
55
+ operation_groups_metadata = metadata_json["operation_groups"]
56
+ for (
57
+ operation_group_name,
58
+ operation_group_class_name,
59
+ ) in operation_groups_metadata.items():
52
60
  try:
53
- operation_group = [og for og in operation_groups if og.name == operation_group_name][0]
61
+ operation_group = [
62
+ og for og in operation_groups if og.name == operation_group_name
63
+ ][0]
54
64
  except IndexError:
55
65
  operation_group = OperationGroup(operation_group_name)
56
66
  operation_groups.append(operation_group)
57
67
  operation_group.append_available_api(version_path.name)
58
- operation_group.append_api_class_name_pair(version_path.name, operation_group_class_name)
68
+ operation_group.append_api_class_name_pair(
69
+ version_path.name, operation_group_class_name
70
+ )
59
71
  operation_groups.sort(key=lambda x: x.name)
60
72
  return operation_groups
61
73
 
@@ -110,7 +122,7 @@ class CodeModel: # pylint: disable=too-many-instance-attributes
110
122
  self.mod_to_api_version,
111
123
  api_versions_list,
112
124
  self.preview_mode,
113
- self.user_specified_default_api
125
+ self.user_specified_default_api,
114
126
  )
115
127
  if local_default_api_version == self.default_api_version:
116
128
  continue
@@ -129,5 +141,6 @@ class CodeModel: # pylint: disable=too-many-instance-attributes
129
141
  @property
130
142
  def default_models(self):
131
143
  return sorted(
132
- {self.default_api_version} | {versions for _, versions in self.last_rt_list.items()}
144
+ {self.default_api_version}
145
+ | {versions for _, versions in self.last_rt_list.items()}
133
146
  )
@@ -7,6 +7,7 @@ import json
7
7
  from typing import Any, Dict
8
8
  from .imports import FileImport
9
9
 
10
+
10
11
  class Config:
11
12
  def __init__(self, default_version_metadata: Dict[str, Any]):
12
13
  self.credential = default_version_metadata["config"]["credential"]
@@ -15,7 +16,9 @@ class Config:
15
16
 
16
17
  def imports(self, async_mode: bool) -> FileImport:
17
18
  imports_to_load = "async_imports" if async_mode else "sync_imports"
18
- return FileImport(json.loads(self.default_version_metadata['config'][imports_to_load]))
19
+ return FileImport(
20
+ json.loads(self.default_version_metadata["config"][imports_to_load])
21
+ )
19
22
 
20
23
  def credential_call(self, async_mode: bool) -> str:
21
24
  if async_mode:
@@ -4,6 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
 
7
+
7
8
  class ConstantGlobalParameter:
8
9
  def __init__(self, name: str, value: str):
9
10
  self.name = name
@@ -5,12 +5,13 @@
5
5
  # --------------------------------------------------------------------------
6
6
  from typing import Any, Dict
7
7
 
8
+
8
9
  class GlobalParameter:
9
10
  def __init__(
10
11
  self,
11
12
  name: str,
12
13
  global_parameter_metadata_sync: Dict[str, Any],
13
- global_parameter_metadata_async: Dict[str, Any]
14
+ global_parameter_metadata_async: Dict[str, Any],
14
15
  ):
15
16
  self.name = name
16
17
  self.global_parameter_metadata_sync = global_parameter_metadata_sync
@@ -7,17 +7,19 @@ from typing import Any, Dict, List
7
7
  from .global_parameter import GlobalParameter
8
8
  from .constant_global_parameter import ConstantGlobalParameter
9
9
 
10
+
10
11
  def _convert_global_parameters(sync_metadata, async_metadata):
11
12
  global_parameters = [
12
13
  GlobalParameter(
13
14
  name=parameter_name,
14
15
  global_parameter_metadata_sync=gp_sync,
15
- global_parameter_metadata_async=async_metadata[parameter_name]
16
+ global_parameter_metadata_async=async_metadata[parameter_name],
16
17
  )
17
18
  for parameter_name, gp_sync in sync_metadata.items()
18
19
  ]
19
20
  return global_parameters
20
21
 
22
+
21
23
  class GlobalParameters:
22
24
  def __init__(
23
25
  self,
@@ -31,12 +33,15 @@ class GlobalParameters:
31
33
  """Return global params specific to multiapi service client + config
32
34
  api_version, endpoint (re-adding it in specific are), and profile
33
35
  """
34
- service_client_params_sync = self.global_parameters_metadata["service_client_specific"]["sync"]
35
- service_client_params_async = self.global_parameters_metadata["service_client_specific"]["async"]
36
+ service_client_params_sync = self.global_parameters_metadata[
37
+ "service_client_specific"
38
+ ]["sync"]
39
+ service_client_params_async = self.global_parameters_metadata[
40
+ "service_client_specific"
41
+ ]["async"]
36
42
 
37
43
  return _convert_global_parameters(
38
- service_client_params_sync,
39
- service_client_params_async
44
+ service_client_params_sync, service_client_params_async
40
45
  )
41
46
 
42
47
  @property
@@ -45,13 +50,14 @@ class GlobalParameters:
45
50
  global_parameters_metadata_async = self.global_parameters_metadata["async"]
46
51
 
47
52
  return _convert_global_parameters(
48
- global_parameters_metadata_sync,
49
- global_parameters_metadata_async
53
+ global_parameters_metadata_sync, global_parameters_metadata_async
50
54
  )
51
55
 
52
56
  @property
53
57
  def constant_parameters(self) -> List[ConstantGlobalParameter]:
54
58
  return [
55
59
  ConstantGlobalParameter(constant_name, constant_value)
56
- for constant_name, constant_value in self.global_parameters_metadata["constant"].items()
60
+ for constant_name, constant_value in self.global_parameters_metadata[
61
+ "constant"
62
+ ].items()
57
63
  ]
@@ -4,7 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from enum import Enum
7
- from typing import Dict, Optional, Set
7
+ from typing import Dict, Optional, Set, Union, Tuple
8
8
 
9
9
 
10
10
  class ImportType(str, Enum):
@@ -13,6 +13,7 @@ class ImportType(str, Enum):
13
13
  AZURECORE = "azurecore"
14
14
  LOCAL = "local"
15
15
 
16
+
16
17
  class TypingSection(str, Enum):
17
18
  REGULAR = "regular" # this import is always a typing import
18
19
  CONDITIONAL = "conditional" # is a typing import when we're dealing with files that py2 will use, else regular
@@ -21,52 +22,66 @@ class TypingSection(str, Enum):
21
22
 
22
23
  class FileImport:
23
24
  def __init__(
24
- self, imports: Dict[TypingSection, Dict[ImportType, Dict[str, Set[Optional[str]]]]] = None
25
+ self,
26
+ imports: Dict[
27
+ TypingSection,
28
+ Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]],
29
+ ] = None,
25
30
  ) -> None:
26
31
  # Basic implementation
27
32
  # First level dict: TypingSection
28
33
  # Second level dict: ImportType
29
34
  # Third level dict: the package name.
30
35
  # Fourth level set: None if this import is a "import", the name to import if it's a "from"
31
- self._imports: Dict[TypingSection, Dict[ImportType, Dict[str, Set[Optional[str]]]]] = imports or dict()
36
+ self._imports: Dict[
37
+ TypingSection,
38
+ Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]],
39
+ ] = (
40
+ imports or dict()
41
+ )
32
42
 
33
43
  def _add_import(
34
44
  self,
35
45
  from_section: str,
36
46
  import_type: ImportType,
37
- name_import: Optional[str] = None,
38
- typing_section: TypingSection = TypingSection.REGULAR
47
+ name_import: Optional[Union[str, Tuple[str, str]]] = None,
48
+ typing_section: TypingSection = TypingSection.REGULAR,
39
49
  ) -> None:
40
- self._imports.setdefault(
41
- typing_section, dict()
42
- ).setdefault(
43
- import_type, dict()
44
- ).setdefault(
45
- from_section, set()
46
- ).add(name_import)
50
+ name_input: Optional[Union[str, Tuple[str, str]]] = None
51
+ if isinstance(name_import, list):
52
+ name_input = tuple(name_import)
53
+ else:
54
+ name_input = name_import
55
+ self._imports.setdefault(typing_section, dict()).setdefault(
56
+ import_type, dict()
57
+ ).setdefault(from_section, set()).add(name_input)
47
58
 
48
59
  def add_submodule_import(
49
60
  self,
50
61
  from_section: str,
51
62
  name_import: str,
52
63
  import_type: ImportType,
53
- typing_section: TypingSection = TypingSection.REGULAR
64
+ typing_section: TypingSection = TypingSection.REGULAR,
54
65
  ) -> None:
55
- """Add an import to this import block.
56
- """
66
+ """Add an import to this import block."""
57
67
  self._add_import(from_section, import_type, name_import, typing_section)
58
68
 
59
69
  def add_import(
60
70
  self,
61
71
  name_import: str,
62
72
  import_type: ImportType,
63
- typing_section: TypingSection = TypingSection.REGULAR
73
+ typing_section: TypingSection = TypingSection.REGULAR,
64
74
  ) -> None:
65
75
  # Implementation detail: a regular import is just a "from" with no from
66
76
  self._add_import(name_import, import_type, None, typing_section)
67
77
 
68
78
  @property
69
- def imports(self) -> Dict[TypingSection, Dict[ImportType, Dict[str, Set[Optional[str]]]]]:
79
+ def imports(
80
+ self,
81
+ ) -> Dict[
82
+ TypingSection,
83
+ Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]],
84
+ ]:
70
85
  return self._imports
71
86
 
72
87
  def merge(self, file_import: "FileImport") -> None:
@@ -75,4 +90,6 @@ class FileImport:
75
90
  for import_type, package_list in import_type_dict.items():
76
91
  for package_name, module_list in package_list.items():
77
92
  for module_name in module_list:
78
- self._add_import(package_name, import_type, module_name, typing_section)
93
+ self._add_import(
94
+ package_name, import_type, module_name, typing_section
95
+ )
@@ -6,15 +6,19 @@
6
6
  from typing import Any, Dict, List, TypeVar
7
7
  from ..utils import _sync_or_async
8
8
 
9
- T = TypeVar('T')
9
+ T = TypeVar("T")
10
10
  OrderedSet = Dict[T, None]
11
11
 
12
+
12
13
  class MixinOperation:
13
14
  def __init__(self, name: str, mixin_operation_metadata: Dict[str, Any]):
14
15
  self.name = name
15
16
  self.mixin_operation_metadata = mixin_operation_metadata
16
17
  self._available_apis: OrderedSet[str] = {}
17
18
 
19
+ def call(self, async_mode: bool) -> str:
20
+ return self.mixin_operation_metadata[_sync_or_async(async_mode)]["call"]
21
+
18
22
  def signature(self, async_mode: bool) -> str:
19
23
  return self.mixin_operation_metadata[_sync_or_async(async_mode)]["signature"]
20
24
 
@@ -26,10 +30,6 @@ class MixinOperation:
26
30
  return False
27
31
  return self.mixin_operation_metadata["async"]["coroutine"]
28
32
 
29
- @property
30
- def call(self) -> str:
31
- return self.mixin_operation_metadata["call"]
32
-
33
33
  @property
34
34
  def available_apis(self) -> List[str]:
35
35
  return list(self._available_apis.keys())
@@ -5,9 +5,10 @@
5
5
  # --------------------------------------------------------------------------
6
6
  from typing import Dict, List, TypeVar
7
7
 
8
- T = TypeVar('T')
8
+ T = TypeVar("T")
9
9
  OrderedSet = Dict[T, None]
10
10
 
11
+
11
12
  class OperationGroup:
12
13
  def __init__(self, name: str):
13
14
  self.name = name
@@ -9,11 +9,12 @@ from pathlib import Path
9
9
  from .imports import FileImport
10
10
  from .mixin_operation import MixinOperation
11
11
 
12
+
12
13
  class OperationMixinGroup:
13
14
  def __init__(
14
15
  self,
15
16
  version_path_to_metadata: Dict[Path, Dict[str, Any]],
16
- default_api_version: str
17
+ default_api_version: str,
17
18
  ):
18
19
  self.default_api_version = default_api_version
19
20
  self.version_path_to_metadata = version_path_to_metadata
@@ -22,9 +23,9 @@ class OperationMixinGroup:
22
23
  imports = FileImport()
23
24
  imports_to_load = "async_imports" if async_mode else "sync_imports"
24
25
  for metadata_json in self.version_path_to_metadata.values():
25
- if not metadata_json.get('operation_mixins'):
26
+ if not metadata_json.get("operation_mixins"):
26
27
  continue
27
- mixin_imports = metadata_json['operation_mixins'][imports_to_load]
28
+ mixin_imports = metadata_json["operation_mixins"][imports_to_load]
28
29
  if mixin_imports != "None":
29
30
  current_version_imports = FileImport(json.loads(mixin_imports))
30
31
  imports.merge(current_version_imports)
@@ -34,20 +35,24 @@ class OperationMixinGroup:
34
35
  self, mixin_operations: List[MixinOperation]
35
36
  ) -> List[MixinOperation]:
36
37
  default_api_version_path = [
37
- version_path for version_path in self.version_path_to_metadata.keys()
38
+ version_path
39
+ for version_path in self.version_path_to_metadata.keys()
38
40
  if version_path.name == self.default_api_version
39
41
  ][0]
40
- default_version_metadata = self.version_path_to_metadata[default_api_version_path]
42
+ default_version_metadata = self.version_path_to_metadata[
43
+ default_api_version_path
44
+ ]
41
45
  if not default_version_metadata.get("operation_mixins"):
42
46
  return mixin_operations
43
- for name, metadata in default_version_metadata["operation_mixins"]["operations"].items():
47
+ for name, metadata in default_version_metadata["operation_mixins"][
48
+ "operations"
49
+ ].items():
44
50
  if name.startswith("_"):
45
51
  continue
46
52
  mixin_operation = [mo for mo in mixin_operations if mo.name == name][0]
47
53
  mixin_operation.mixin_operation_metadata = metadata
48
54
  return mixin_operations
49
55
 
50
-
51
56
  @property
52
57
  def mixin_operations(self) -> List[MixinOperation]:
53
58
  mixin_operations: List[MixinOperation] = []
@@ -55,14 +60,20 @@ class OperationMixinGroup:
55
60
  if not metadata_json.get("operation_mixins"):
56
61
  continue
57
62
  mixin_operations_metadata = metadata_json["operation_mixins"]["operations"]
58
- for mixin_operation_name, mixin_operation_metadata in mixin_operations_metadata.items():
63
+ for (
64
+ mixin_operation_name,
65
+ mixin_operation_metadata,
66
+ ) in mixin_operations_metadata.items():
59
67
  if mixin_operation_name.startswith("_"):
60
68
  continue
61
69
  try:
62
- mixin_operation = [mo for mo in mixin_operations if mo.name == mixin_operation_name][0]
70
+ mixin_operation = [
71
+ mo for mo in mixin_operations if mo.name == mixin_operation_name
72
+ ][0]
63
73
  except IndexError:
64
74
  mixin_operation = MixinOperation(
65
- name=mixin_operation_name, mixin_operation_metadata=mixin_operation_metadata
75
+ name=mixin_operation_name,
76
+ mixin_operation_metadata=mixin_operation_metadata,
66
77
  )
67
78
  mixin_operations.append(mixin_operation)
68
79
  mixin_operation.append_available_api(version_path.name)
@@ -21,9 +21,10 @@ _FILE_TO_TEMPLATE = {
21
21
  "service_client": "multiapi_service_client.py.jinja2",
22
22
  "config": "multiapi_config.py.jinja2",
23
23
  "models": "multiapi_models.py.jinja2",
24
- "operations_mixin": "multiapi_operations_mixin.py.jinja2"
24
+ "operations_mixin": "multiapi_operations_mixin.py.jinja2",
25
25
  }
26
26
 
27
+
27
28
  def _get_file_path(filename: str, async_mode: bool) -> Path:
28
29
  filename += ".py"
29
30
  if async_mode:
@@ -43,44 +44,45 @@ class MultiAPISerializer(object):
43
44
  lstrip_blocks=True,
44
45
  )
45
46
 
46
-
47
47
  def _serialize_helper(self, code_model: CodeModel, async_mode: bool) -> None:
48
48
  def _render_template(file: str, **kwargs: Any) -> str:
49
49
  template = self.env.get_template(_FILE_TO_TEMPLATE[file])
50
- return template.render(code_model=code_model, async_mode=async_mode, **kwargs)
50
+ return template.render(
51
+ code_model=code_model, async_mode=async_mode, **kwargs
52
+ )
51
53
 
52
54
  # serialize init file
53
- self._autorestapi.write_file(_get_file_path("__init__", async_mode), _render_template("init"))
55
+ self._autorestapi.write_file(
56
+ _get_file_path("__init__", async_mode), _render_template("init")
57
+ )
54
58
 
55
59
  # serialize service client file
56
60
  imports = FileImportSerializer(
57
- code_model.service_client.imports(async_mode),
58
- is_python3_file=async_mode
61
+ code_model.service_client.imports(async_mode), is_python3_file=async_mode
59
62
  )
60
63
  self._autorestapi.write_file(
61
64
  _get_file_path(code_model.service_client.filename, async_mode),
62
- _render_template("service_client", imports=imports)
65
+ _render_template("service_client", imports=imports),
63
66
  )
64
67
 
65
68
  # serialize config file
66
69
  imports = FileImportSerializer(
67
- code_model.config.imports(async_mode),
68
- is_python3_file=async_mode
70
+ code_model.config.imports(async_mode), is_python3_file=async_mode
69
71
  )
70
72
  self._autorestapi.write_file(
71
73
  _get_file_path("_configuration", async_mode),
72
- _render_template("config", imports=imports)
74
+ _render_template("config", imports=imports),
73
75
  )
74
76
 
75
77
  # serialize mixins
76
78
  if code_model.operation_mixin_group.mixin_operations:
77
79
  imports = FileImportSerializer(
78
80
  code_model.operation_mixin_group.imports(async_mode),
79
- is_python3_file=async_mode
81
+ is_python3_file=async_mode,
80
82
  )
81
83
  self._autorestapi.write_file(
82
84
  _get_file_path("_operations_mixin", async_mode),
83
- _render_template("operations_mixin", imports=imports)
85
+ _render_template("operations_mixin", imports=imports),
84
86
  )
85
87
 
86
88
  # serialize models
@@ -89,21 +91,15 @@ class MultiAPISerializer(object):
89
91
  def _serialize_version_file(self) -> None:
90
92
  if self._autorestapi.read_file("_version.py"):
91
93
  self._autorestapi.write_file(
92
- "_version.py",
93
- self._autorestapi.read_file("_version.py")
94
+ "_version.py", self._autorestapi.read_file("_version.py")
94
95
  )
95
96
  elif self._autorestapi.read_file("version.py"):
96
97
  self._autorestapi.write_file(
97
- "_version.py",
98
- self._autorestapi.read_file("version.py")
98
+ "_version.py", self._autorestapi.read_file("version.py")
99
99
  )
100
100
  else:
101
101
  template = self.env.get_template("multiapi_version.py.jinja2")
102
- self._autorestapi.write_file(
103
- Path("_version.py"),
104
- template.render()
105
- )
106
-
102
+ self._autorestapi.write_file(Path("_version.py"), template.render())
107
103
 
108
104
  def serialize(self, code_model: CodeModel, no_async: Optional[bool]) -> None:
109
105
  self._serialize_helper(code_model, async_mode=False)
@@ -115,8 +111,7 @@ class MultiAPISerializer(object):
115
111
  # don't erase patch file
116
112
  if self._autorestapi.read_file("_patch.py"):
117
113
  self._autorestapi.write_file(
118
- "_patch.py",
119
- self._autorestapi.read_file("_patch.py")
114
+ "_patch.py", self._autorestapi.read_file("_patch.py")
120
115
  )
121
116
 
122
117
  self._autorestapi.write_file(Path("py.typed"), "# Marker file for PEP 561.")
@@ -7,19 +7,34 @@ from copy import deepcopy
7
7
  from typing import Dict, Set, Optional, List
8
8
  from ..models import ImportType, FileImport, TypingSection
9
9
 
10
- def _serialize_package(package_name: str, module_list: Set[Optional[str]], delimiter: str) -> str:
10
+
11
+ def _serialize_package(
12
+ package_name: str, module_list: Set[Optional[str]], delimiter: str
13
+ ) -> str:
11
14
  buffer = []
12
15
  if None in module_list:
13
16
  buffer.append(f"import {package_name}")
14
17
  if module_list != {None}:
15
18
  buffer.append(
16
19
  "from {} import {}".format(
17
- package_name, ", ".join(sorted([mod for mod in module_list if mod is not None]))
20
+ package_name,
21
+ ", ".join(
22
+ sorted(
23
+ [
24
+ mod if isinstance(mod, str) else f"{mod[0]} as {mod[1]}"
25
+ for mod in module_list
26
+ if mod is not None
27
+ ]
28
+ )
29
+ ),
18
30
  )
19
31
  )
20
32
  return delimiter.join(buffer)
21
33
 
22
- def _serialize_type(import_type_dict: Dict[str, Set[Optional[str]]], delimiter: str) -> str:
34
+
35
+ def _serialize_type(
36
+ import_type_dict: Dict[str, Set[Optional[str]]], delimiter: str
37
+ ) -> str:
23
38
  """Serialize a given import type."""
24
39
  import_list = []
25
40
  for package_name in sorted(list(import_type_dict.keys())):
@@ -27,7 +42,10 @@ def _serialize_type(import_type_dict: Dict[str, Set[Optional[str]]], delimiter:
27
42
  import_list.append(_serialize_package(package_name, module_list, delimiter))
28
43
  return delimiter.join(import_list)
29
44
 
30
- def _get_import_clauses(imports: Dict[ImportType, Dict[str, Set[Optional[str]]]], delimiter: str) -> List[str]:
45
+
46
+ def _get_import_clauses(
47
+ imports: Dict[ImportType, Dict[str, Set[Optional[str]]]], delimiter: str
48
+ ) -> List[str]:
31
49
  import_clause = []
32
50
  for import_type in ImportType:
33
51
  if import_type in imports:
@@ -42,33 +60,44 @@ class FileImportSerializer:
42
60
 
43
61
  def _switch_typing_section_key(self, new_key: TypingSection):
44
62
  switched_dictionary = {}
45
- switched_dictionary[new_key] = self._file_import.imports[TypingSection.CONDITIONAL]
63
+ switched_dictionary[new_key] = self._file_import.imports[
64
+ TypingSection.CONDITIONAL
65
+ ]
46
66
  return switched_dictionary
47
67
 
48
- def _get_imports_dict(self, baseline_typing_section: TypingSection, add_conditional_typing: bool):
68
+ def _get_imports_dict(
69
+ self, baseline_typing_section: TypingSection, add_conditional_typing: bool
70
+ ):
49
71
  # If this is a python 3 file, our regular imports include the CONDITIONAL category
50
72
  # If this is not a python 3 file, our typing imports include the CONDITIONAL category
51
73
  file_import_copy = deepcopy(self._file_import)
52
- if add_conditional_typing and self._file_import.imports.get(TypingSection.CONDITIONAL):
74
+ if add_conditional_typing and self._file_import.imports.get(
75
+ TypingSection.CONDITIONAL
76
+ ):
53
77
  # we switch the TypingSection key for the CONDITIONAL typing imports so we can merge
54
78
  # the imports together
55
- switched_imports_dictionary = self._switch_typing_section_key(baseline_typing_section)
79
+ switched_imports_dictionary = self._switch_typing_section_key(
80
+ baseline_typing_section
81
+ )
56
82
  switched_imports = FileImport(switched_imports_dictionary)
57
83
  file_import_copy.merge(switched_imports)
58
84
  return file_import_copy.imports.get(baseline_typing_section, {})
59
85
 
60
86
  def _add_type_checking_import(self):
61
- if (
62
- self._file_import.imports.get(TypingSection.TYPING) or
63
- (not self.is_python3_file and self._file_import.imports.get(TypingSection.CONDITIONAL))
87
+ if self._file_import.imports.get(TypingSection.TYPING) or (
88
+ not self.is_python3_file
89
+ and self._file_import.imports.get(TypingSection.CONDITIONAL)
64
90
  ):
65
- self._file_import.add_submodule_import("typing", "TYPE_CHECKING", ImportType.STDLIB)
91
+ self._file_import.add_submodule_import(
92
+ "typing", "TYPE_CHECKING", ImportType.STDLIB
93
+ )
66
94
 
67
95
  def __str__(self) -> str:
68
96
  self._add_type_checking_import()
69
97
  regular_imports = ""
70
98
  regular_imports_dict = self._get_imports_dict(
71
- baseline_typing_section=TypingSection.REGULAR, add_conditional_typing=self.is_python3_file
99
+ baseline_typing_section=TypingSection.REGULAR,
100
+ add_conditional_typing=self.is_python3_file,
72
101
  )
73
102
 
74
103
  if regular_imports_dict:
@@ -78,10 +107,13 @@ class FileImportSerializer:
78
107
 
79
108
  typing_imports = ""
80
109
  typing_imports_dict = self._get_imports_dict(
81
- baseline_typing_section=TypingSection.TYPING, add_conditional_typing=not self.is_python3_file
110
+ baseline_typing_section=TypingSection.TYPING,
111
+ add_conditional_typing=not self.is_python3_file,
82
112
  )
83
113
  if typing_imports_dict:
84
114
  typing_imports += "\n\nif TYPE_CHECKING:\n # pylint: disable=unused-import,ungrouped-imports\n "
85
- typing_imports += "\n\n ".join(_get_import_clauses(typing_imports_dict, "\n "))
115
+ typing_imports += "\n\n ".join(
116
+ _get_import_clauses(typing_imports_dict, "\n ")
117
+ )
86
118
 
87
119
  return regular_imports + typing_imports