@autorest/python 5.14.0 → 5.17.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 (120) hide show
  1. package/ChangeLog.md +91 -2
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +2 -3
  4. package/autorest/black/__init__.py +12 -5
  5. package/autorest/codegen/__init__.py +130 -179
  6. package/autorest/codegen/models/__init__.py +122 -78
  7. package/autorest/codegen/models/base_builder.py +70 -72
  8. package/autorest/codegen/models/base_model.py +7 -5
  9. package/autorest/codegen/models/{base_schema.py → base_type.py} +62 -49
  10. package/autorest/codegen/models/client.py +195 -36
  11. package/autorest/codegen/models/code_model.py +165 -299
  12. package/autorest/codegen/models/combined_type.py +107 -0
  13. package/autorest/codegen/models/constant_type.py +122 -0
  14. package/autorest/codegen/models/credential_types.py +224 -0
  15. package/autorest/codegen/models/dictionary_type.py +116 -0
  16. package/autorest/codegen/models/enum_type.py +195 -0
  17. package/autorest/codegen/models/imports.py +95 -41
  18. package/autorest/codegen/models/list_type.py +134 -0
  19. package/autorest/codegen/models/lro_operation.py +90 -133
  20. package/autorest/codegen/models/lro_paging_operation.py +28 -12
  21. package/autorest/codegen/models/model_type.py +239 -0
  22. package/autorest/codegen/models/operation.py +415 -241
  23. package/autorest/codegen/models/operation_group.py +82 -88
  24. package/autorest/codegen/models/paging_operation.py +101 -117
  25. package/autorest/codegen/models/parameter.py +307 -322
  26. package/autorest/codegen/models/parameter_list.py +366 -357
  27. package/autorest/codegen/models/primitive_types.py +544 -0
  28. package/autorest/codegen/models/property.py +122 -134
  29. package/autorest/codegen/models/request_builder.py +138 -86
  30. package/autorest/codegen/models/request_builder_parameter.py +122 -79
  31. package/autorest/codegen/models/response.py +325 -0
  32. package/autorest/codegen/models/utils.py +17 -1
  33. package/autorest/codegen/serializers/__init__.py +242 -118
  34. package/autorest/codegen/serializers/builder_serializer.py +863 -1027
  35. package/autorest/codegen/serializers/client_serializer.py +148 -82
  36. package/autorest/codegen/serializers/general_serializer.py +44 -47
  37. package/autorest/codegen/serializers/import_serializer.py +96 -31
  38. package/autorest/codegen/serializers/metadata_serializer.py +39 -79
  39. package/autorest/codegen/serializers/model_base_serializer.py +65 -29
  40. package/autorest/codegen/serializers/model_generic_serializer.py +9 -10
  41. package/autorest/codegen/serializers/model_init_serializer.py +4 -2
  42. package/autorest/codegen/serializers/model_python3_serializer.py +29 -22
  43. package/autorest/codegen/serializers/operation_groups_serializer.py +21 -18
  44. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  45. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  46. package/autorest/codegen/serializers/patch_serializer.py +14 -2
  47. package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
  48. package/autorest/codegen/serializers/utils.py +0 -103
  49. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  50. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
  51. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  52. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  53. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -2
  54. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  55. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  56. package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
  57. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
  58. package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
  59. package/autorest/codegen/templates/model.py.jinja2 +23 -29
  60. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  61. package/autorest/codegen/templates/model_init.py.jinja2 +9 -8
  62. package/autorest/codegen/templates/operation.py.jinja2 +10 -15
  63. package/autorest/codegen/templates/operation_group.py.jinja2 +14 -13
  64. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
  65. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  66. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  67. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  68. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  69. package/autorest/codegen/templates/request_builder.py.jinja2 +20 -13
  70. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  71. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  72. package/autorest/jsonrpc/__init__.py +7 -12
  73. package/autorest/jsonrpc/localapi.py +4 -3
  74. package/autorest/jsonrpc/server.py +28 -9
  75. package/autorest/jsonrpc/stdstream.py +13 -6
  76. package/autorest/m2r/__init__.py +5 -8
  77. package/autorest/m4reformatter/__init__.py +1108 -0
  78. package/autorest/multiapi/__init__.py +24 -14
  79. package/autorest/multiapi/models/client.py +21 -11
  80. package/autorest/multiapi/models/code_model.py +23 -10
  81. package/autorest/multiapi/models/config.py +4 -1
  82. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  83. package/autorest/multiapi/models/global_parameter.py +2 -1
  84. package/autorest/multiapi/models/global_parameters.py +14 -8
  85. package/autorest/multiapi/models/imports.py +35 -18
  86. package/autorest/multiapi/models/mixin_operation.py +5 -5
  87. package/autorest/multiapi/models/operation_group.py +2 -1
  88. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  89. package/autorest/multiapi/serializers/__init__.py +20 -25
  90. package/autorest/multiapi/serializers/import_serializer.py +47 -15
  91. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  92. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  93. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  94. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  95. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  96. package/autorest/multiapi/utils.py +3 -3
  97. package/autorest/postprocess/__init__.py +202 -0
  98. package/autorest/postprocess/get_all.py +19 -0
  99. package/autorest/postprocess/venvtools.py +73 -0
  100. package/autorest/preprocess/__init__.py +209 -0
  101. package/autorest/preprocess/helpers.py +54 -0
  102. package/autorest/{namer → preprocess}/python_mappings.py +25 -32
  103. package/package.json +3 -3
  104. package/run-python3.js +2 -3
  105. package/venvtools.py +1 -1
  106. package/autorest/codegen/models/constant_schema.py +0 -97
  107. package/autorest/codegen/models/credential_schema.py +0 -90
  108. package/autorest/codegen/models/credential_schema_policy.py +0 -77
  109. package/autorest/codegen/models/dictionary_schema.py +0 -103
  110. package/autorest/codegen/models/enum_schema.py +0 -246
  111. package/autorest/codegen/models/list_schema.py +0 -113
  112. package/autorest/codegen/models/object_schema.py +0 -249
  113. package/autorest/codegen/models/primitive_schemas.py +0 -476
  114. package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
  115. package/autorest/codegen/models/rest.py +0 -42
  116. package/autorest/codegen/models/schema_request.py +0 -45
  117. package/autorest/codegen/models/schema_response.py +0 -123
  118. package/autorest/codegen/serializers/rest_serializer.py +0 -57
  119. package/autorest/namer/__init__.py +0 -25
  120. package/autorest/namer/name_converter.py +0 -412
@@ -0,0 +1,122 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+ import logging
7
+ from typing import Dict, Any, Optional, TYPE_CHECKING
8
+ from .base_type import BaseType
9
+ from .imports import FileImport
10
+ from .utils import add_to_description
11
+
12
+ if TYPE_CHECKING:
13
+ from .code_model import CodeModel
14
+
15
+ _LOGGER = logging.getLogger(__name__)
16
+
17
+
18
+ class ConstantType(BaseType):
19
+ """Schema for constants that will be serialized.
20
+
21
+ :param yaml_data: the yaml data for this schema
22
+ :type yaml_data: dict[str, Any]
23
+ :param str value: The actual value of this constant.
24
+ :param schema: The schema for the value of this constant.
25
+ :type schema: ~autorest.models.PrimitiveType
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ yaml_data: Dict[str, Any],
31
+ code_model: "CodeModel",
32
+ value_type: BaseType,
33
+ value: Optional[str],
34
+ ) -> None:
35
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
36
+ self.value_type = value_type
37
+ self.value = value
38
+
39
+ def get_declaration(self, value=None):
40
+ if value and value != self.value:
41
+ _LOGGER.warning(
42
+ "Passed in value of %s differs from constant value of %s. Choosing constant value",
43
+ str(value),
44
+ str(self.value),
45
+ )
46
+ if self.value is None:
47
+ return "None"
48
+ return self.value_type.get_declaration(self.value)
49
+
50
+ def description(self, *, is_operation_file: bool) -> str:
51
+ if is_operation_file:
52
+ return ""
53
+ return add_to_description(
54
+ self.yaml_data.get("description", ""),
55
+ f"Default value is {self.get_declaration()}.",
56
+ )
57
+
58
+ @property
59
+ def serialization_type(self) -> str:
60
+ """Returns the serialization value for msrest.
61
+
62
+ :return: The serialization value for msrest
63
+ :rtype: str
64
+ """
65
+ return self.value_type.serialization_type
66
+
67
+ def docstring_text(self, **kwargs: Any) -> str:
68
+ return "constant"
69
+
70
+ def docstring_type(self, **kwargs: Any) -> str:
71
+ """The python type used for RST syntax input and type annotation.
72
+
73
+ :param str namespace: Optional. The namespace for the models.
74
+ """
75
+ return self.value_type.docstring_type(**kwargs)
76
+
77
+ def type_annotation(self, **kwargs: Any) -> str:
78
+ return self.value_type.type_annotation(**kwargs)
79
+
80
+ @classmethod
81
+ def from_yaml(
82
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
83
+ ) -> "ConstantType":
84
+ """Constructs a ConstantType from yaml data.
85
+
86
+ :param yaml_data: the yaml data from which we will construct this schema
87
+ :type yaml_data: dict[str, Any]
88
+
89
+ :return: A created ConstantType
90
+ :rtype: ~autorest.models.ConstantType
91
+ """
92
+ from . import build_type
93
+
94
+ return cls(
95
+ yaml_data=yaml_data,
96
+ code_model=code_model,
97
+ value_type=build_type(yaml_data["valueType"], code_model),
98
+ value=yaml_data["value"],
99
+ )
100
+
101
+ def get_json_template_representation(
102
+ self,
103
+ *,
104
+ optional: bool = True,
105
+ # pylint: disable=unused-argument
106
+ client_default_value_declaration: Optional[str] = None,
107
+ description: Optional[str] = None,
108
+ ) -> Any:
109
+ return self.value_type.get_json_template_representation(
110
+ optional=optional,
111
+ client_default_value_declaration=self.get_declaration(),
112
+ description=description,
113
+ )
114
+
115
+ def imports(self, **kwargs: Any) -> FileImport:
116
+ file_import = FileImport()
117
+ file_import.merge(self.value_type.imports(**kwargs))
118
+ return file_import
119
+
120
+ @property
121
+ def instance_check_template(self) -> str:
122
+ return self.value_type.instance_check_template
@@ -0,0 +1,224 @@
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 abc import abstractmethod
7
+ from typing import (
8
+ Optional,
9
+ Any,
10
+ Dict,
11
+ TYPE_CHECKING,
12
+ List,
13
+ Generic,
14
+ TypeVar,
15
+ Union,
16
+ cast,
17
+ )
18
+
19
+ from .imports import FileImport, ImportType, TypingSection
20
+ from .base_type import BaseType
21
+
22
+ if TYPE_CHECKING:
23
+ from .code_model import CodeModel
24
+
25
+
26
+ class _CredentialPolicyBaseType:
27
+ """Base class for our different credential policy types.
28
+
29
+ Inherited by our BearerTokenCredentialPolicy and AzureKeyCredentialPolicy types.
30
+ """
31
+
32
+ def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
33
+ self.yaml_data = yaml_data
34
+ self.code_model = code_model
35
+
36
+ @abstractmethod
37
+ def call(self, async_mode: bool) -> str:
38
+ """
39
+ How to call this credential policy. Used to initialize the credential policy in the config file.
40
+ """
41
+ ...
42
+
43
+
44
+ class BearerTokenCredentialPolicyType(_CredentialPolicyBaseType):
45
+ """Credential policy type representing BearerTokenCredentialPolicy"""
46
+
47
+ def __init__(
48
+ self,
49
+ yaml_data: Dict[str, Any],
50
+ code_model: "CodeModel",
51
+ credential_scopes: List[str],
52
+ ) -> None:
53
+ super().__init__(yaml_data, code_model)
54
+ self.credential_scopes = credential_scopes
55
+
56
+ def call(self, async_mode: bool) -> str:
57
+ policy_name = f"{'Async' if async_mode else ''}BearerTokenCredentialPolicy"
58
+ return f"policies.{policy_name}(self.credential, *self.credential_scopes, **kwargs)"
59
+
60
+ @classmethod
61
+ def from_yaml(
62
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
63
+ ) -> "BearerTokenCredentialPolicyType":
64
+ return cls(yaml_data, code_model, yaml_data["credentialScopes"])
65
+
66
+
67
+ class ARMChallengeAuthenticationPolicyType(BearerTokenCredentialPolicyType):
68
+ """Credential policy type representing ARMChallengeAuthenticationPolicy"""
69
+
70
+ def call(self, async_mode: bool) -> str:
71
+ policy_name = f"{'Async' if async_mode else ''}ARMChallengeAuthenticationPolicy"
72
+ return f"{policy_name}(self.credential, *self.credential_scopes, **kwargs)"
73
+
74
+
75
+ class AzureKeyCredentialPolicyType(_CredentialPolicyBaseType):
76
+ def __init__(
77
+ self, yaml_data: Dict[str, Any], code_model: "CodeModel", key: str
78
+ ) -> None:
79
+ super().__init__(yaml_data, code_model)
80
+ self.key = key
81
+
82
+ def call(self, async_mode: bool) -> str:
83
+ return f'policies.AzureKeyCredentialPolicy(self.credential, "{self.key}", **kwargs)'
84
+
85
+ @classmethod
86
+ def from_yaml(
87
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
88
+ ) -> "AzureKeyCredentialPolicyType":
89
+ return cls(yaml_data, code_model, yaml_data["key"])
90
+
91
+
92
+ CredentialPolicyType = TypeVar(
93
+ "CredentialPolicyType",
94
+ bound=Union[
95
+ BearerTokenCredentialPolicyType,
96
+ ARMChallengeAuthenticationPolicyType,
97
+ AzureKeyCredentialPolicyType,
98
+ ],
99
+ )
100
+
101
+
102
+ class CredentialType(
103
+ Generic[CredentialPolicyType], BaseType
104
+ ): # pylint:disable=abstract-method
105
+ """Store info about the type of the credential. Can be either an AzureKeyCredential or a TokenCredential"""
106
+
107
+ def __init__(
108
+ self,
109
+ yaml_data: Dict[str, Any],
110
+ code_model: "CodeModel",
111
+ policy: CredentialPolicyType,
112
+ ) -> None:
113
+ super().__init__(yaml_data, code_model)
114
+ self.policy = policy
115
+
116
+ def description(
117
+ self, *, is_operation_file: bool # pylint: disable=unused-argument
118
+ ) -> str:
119
+ return ""
120
+
121
+ def get_json_template_representation(
122
+ self,
123
+ *,
124
+ optional: bool = True,
125
+ client_default_value_declaration: Optional[str] = None,
126
+ description: Optional[str] = None,
127
+ ) -> Any:
128
+ raise TypeError(
129
+ "You should not try to get a JSON template representation of a CredentialSchema"
130
+ )
131
+
132
+ def docstring_text(self, **kwargs: Any) -> str:
133
+ return "credential"
134
+
135
+ @property
136
+ def serialization_type(self) -> str:
137
+ return self.docstring_type()
138
+
139
+ @classmethod
140
+ def from_yaml(
141
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
142
+ ) -> "CredentialType":
143
+ from . import build_type
144
+
145
+ return cls(
146
+ yaml_data,
147
+ code_model,
148
+ policy=cast(
149
+ CredentialPolicyType, build_type(yaml_data["policy"], code_model)
150
+ ),
151
+ )
152
+
153
+
154
+ class TokenCredentialType(
155
+ CredentialType[ # pylint: disable=unsubscriptable-object
156
+ Union[BearerTokenCredentialPolicyType, ARMChallengeAuthenticationPolicyType]
157
+ ]
158
+ ):
159
+ """Type of a token credential. Used by BearerAuth and ARMChallenge policies"""
160
+
161
+ def type_annotation(self, **kwargs: Any) -> str: # pylint: disable=no-self-use
162
+ if kwargs.pop("async_mode"):
163
+ return '"AsyncTokenCredential"'
164
+ return '"TokenCredential"'
165
+
166
+ def docstring_type(self, **kwargs: Any) -> str: # pylint: disable=no-self-use
167
+ if kwargs.pop("async_mode"):
168
+ return "~azure.core.credentials_async.AsyncTokenCredential"
169
+ return "~azure.core.credentials.TokenCredential"
170
+
171
+ def imports(self, **kwargs: Any) -> FileImport: # pylint: disable=no-self-use
172
+ file_import = FileImport()
173
+ if kwargs.pop("async_mode"):
174
+ file_import.add_submodule_import(
175
+ "azure.core.credentials_async",
176
+ "AsyncTokenCredential",
177
+ ImportType.AZURECORE,
178
+ typing_section=TypingSection.TYPING,
179
+ )
180
+ else:
181
+ file_import.add_submodule_import(
182
+ "azure.core.credentials",
183
+ "TokenCredential",
184
+ ImportType.AZURECORE,
185
+ typing_section=TypingSection.TYPING,
186
+ )
187
+ return file_import
188
+
189
+ @property
190
+ def instance_check_template(self) -> str:
191
+ return "hasattr({}, get_token)"
192
+
193
+
194
+ class AzureKeyCredentialType(
195
+ # pylint: disable=unsubscriptable-object
196
+ CredentialType[AzureKeyCredentialPolicyType]
197
+ ):
198
+ """Type for an AzureKeyCredential"""
199
+
200
+ def docstring_type( # pylint: disable=no-self-use
201
+ self, **kwargs: Any # pylint: disable=unused-argument
202
+ ) -> str:
203
+ return "~azure.core.credentials.AzureKeyCredential"
204
+
205
+ def type_annotation( # pylint: disable=no-self-use
206
+ self, **kwargs: Any # pylint: disable=unused-argument
207
+ ) -> str:
208
+ return "AzureKeyCredential"
209
+
210
+ @property
211
+ def instance_check_template(self) -> str:
212
+ return "isinstance({}, AzureKeyCredential)"
213
+
214
+ def imports( # pylint: disable=no-self-use
215
+ self, **kwargs: Any # pylint: disable=unused-argument
216
+ ) -> FileImport:
217
+ file_import = FileImport()
218
+ file_import.add_submodule_import(
219
+ "azure.core.credentials",
220
+ "AzureKeyCredential",
221
+ ImportType.AZURECORE,
222
+ typing_section=TypingSection.CONDITIONAL,
223
+ )
224
+ return file_import
@@ -0,0 +1,116 @@
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 Any, Dict, Optional, TYPE_CHECKING
7
+ from .base_type import BaseType
8
+ from .imports import FileImport, ImportType, TypingSection
9
+
10
+ if TYPE_CHECKING:
11
+ from .code_model import CodeModel
12
+
13
+
14
+ class DictionaryType(BaseType):
15
+ """Schema for dictionaries that will be serialized.
16
+
17
+ :param yaml_data: the yaml data for this schema
18
+ :type yaml_data: dict[str, Any]
19
+ :param element_type: The type of the value for the dictionary
20
+ :type element_type: ~autorest.models.BaseType
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ yaml_data: Dict[str, Any],
26
+ code_model: "CodeModel",
27
+ element_type: BaseType,
28
+ ) -> None:
29
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
30
+ self.element_type = element_type
31
+
32
+ @property
33
+ def serialization_type(self) -> str:
34
+ """Returns the serialization value for msrest.
35
+
36
+ :return: The serialization value for msrest
37
+ :rtype: str
38
+ """
39
+ return f"{{{self.element_type.serialization_type}}}"
40
+
41
+ def type_annotation(self, **kwargs: Any) -> str:
42
+ """The python type used for type annotation
43
+
44
+ :return: The type annotation for this schema
45
+ :rtype: str
46
+ """
47
+ return f"Dict[str, {self.element_type.type_annotation(**kwargs)}]"
48
+
49
+ def description(self, *, is_operation_file: bool) -> str:
50
+ return "" if is_operation_file else self.yaml_data.get("description", "")
51
+
52
+ def docstring_text(self, **kwargs: Any) -> str:
53
+ return f"dict mapping str to {self.element_type.docstring_text(**kwargs)}"
54
+
55
+ @property
56
+ def xml_serialization_ctxt(self) -> Optional[str]:
57
+ """No serialization ctxt for dictionaries"""
58
+ return None
59
+
60
+ def docstring_type(self, **kwargs: Any) -> str:
61
+ """The python type used for RST syntax input and type annotation.
62
+
63
+ :param str namespace: Optional. The namespace for the models.
64
+ """
65
+ return f"dict[str, {self.element_type.docstring_type(**kwargs)}]"
66
+
67
+ def get_json_template_representation(
68
+ self,
69
+ *,
70
+ optional: bool = True,
71
+ client_default_value_declaration: Optional[str] = None,
72
+ description: Optional[str] = None,
73
+ ) -> Any:
74
+ return {
75
+ f'"str"': self.element_type.get_json_template_representation(
76
+ optional=optional,
77
+ client_default_value_declaration=client_default_value_declaration,
78
+ description=description,
79
+ )
80
+ }
81
+
82
+ @classmethod
83
+ def from_yaml(
84
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
85
+ ) -> "DictionaryType":
86
+ """Constructs a DictionaryType from yaml data.
87
+
88
+ :param yaml_data: the yaml data from which we will construct this schema
89
+ :type yaml_data: dict[str, Any]
90
+
91
+ :return: A created DictionaryType
92
+ :rtype: ~autorest.models.DictionaryType
93
+ """
94
+ element_schema: Dict[str, Any] = yaml_data["elementType"]
95
+
96
+ from . import build_type # pylint: disable=import-outside-toplevel
97
+
98
+ element_type = build_type(yaml_data=element_schema, code_model=code_model)
99
+
100
+ return cls(
101
+ yaml_data=yaml_data,
102
+ code_model=code_model,
103
+ element_type=element_type,
104
+ )
105
+
106
+ def imports(self, **kwargs: Any) -> FileImport:
107
+ file_import = FileImport()
108
+ file_import.add_submodule_import(
109
+ "typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL
110
+ )
111
+ file_import.merge(self.element_type.imports(**kwargs))
112
+ return file_import
113
+
114
+ @property
115
+ def instance_check_template(self) -> str:
116
+ return "isinstance({}, dict)"
@@ -0,0 +1,195 @@
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 Any, Dict, List, TYPE_CHECKING, Optional
7
+
8
+ from .base_type import BaseType
9
+ from .imports import FileImport, ImportType, TypingSection
10
+ from .base_model import BaseModel
11
+
12
+ if TYPE_CHECKING:
13
+ from .code_model import CodeModel
14
+
15
+
16
+ class EnumValue(BaseModel):
17
+ """Model containing necessary information for a single value of an enum.
18
+
19
+ :param str name: The name of this enum value
20
+ :param str value: The value of this enum value
21
+ :param str description: Optional. The description for this enum value
22
+ """
23
+
24
+ def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
25
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
26
+ self.name: str = self.yaml_data["name"]
27
+ self.value: str = self.yaml_data["value"]
28
+ self.description: Optional[str] = self.yaml_data.get("description")
29
+
30
+ @classmethod
31
+ def from_yaml(
32
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
33
+ ) -> "EnumValue":
34
+ """Constructs an EnumValue from yaml data.
35
+
36
+ :param yaml_data: the yaml data from which we will construct this object
37
+ :type yaml_data: dict[str, Any]
38
+
39
+ :return: A created EnumValue
40
+ :rtype: ~autorest.models.EnumValue
41
+ """
42
+ return cls(
43
+ yaml_data=yaml_data,
44
+ code_model=code_model,
45
+ )
46
+
47
+
48
+ class EnumType(BaseType):
49
+ """Schema for enums that will be serialized.
50
+
51
+ :param yaml_data: the yaml data for this schema
52
+ :type yaml_data: dict[str, Any]
53
+ :param str description: The description of this enum
54
+ :param str name: The name of the enum.
55
+ :type element_type: ~autorest.models.PrimitiveType
56
+ :param values: List of the values for this enum
57
+ :type values: list[~autorest.models.EnumValue]
58
+ """
59
+
60
+ def __init__(
61
+ self,
62
+ yaml_data: Dict[str, Any],
63
+ code_model: "CodeModel",
64
+ values: List["EnumValue"],
65
+ value_type: BaseType,
66
+ ) -> None:
67
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
68
+ self.name: str = yaml_data["name"]
69
+ self.values = values
70
+ self.value_type = value_type
71
+
72
+ def __lt__(self, other):
73
+ return self.name.lower() < other.name.lower()
74
+
75
+ @property
76
+ def serialization_type(self) -> str:
77
+ """Returns the serialization value for msrest.
78
+
79
+ :return: The serialization value for msrest
80
+ :rtype: str
81
+ """
82
+ return self.value_type.serialization_type
83
+
84
+ def description(
85
+ self, *, is_operation_file: bool # pylint: disable=unused-argument
86
+ ) -> str:
87
+ possible_values = [self.get_declaration(v.value) for v in self.values]
88
+ if not possible_values:
89
+ return ""
90
+ if len(possible_values) == 1:
91
+ return possible_values[0]
92
+ if len(possible_values) == 2:
93
+ possible_values_str = " and ".join(possible_values)
94
+ else:
95
+ possible_values_str = (
96
+ ", ".join(possible_values[: len(possible_values) - 1])
97
+ + f", and {possible_values[-1]}"
98
+ )
99
+
100
+ enum_description = f"Known values are: {possible_values_str}."
101
+ return enum_description
102
+
103
+ def type_annotation(self, **kwargs: Any) -> str:
104
+ """The python type used for type annotation
105
+
106
+ :return: The type annotation for this schema
107
+ :rtype: str
108
+ """
109
+ if self.code_model.options["models_mode"]:
110
+ return (
111
+ f"Union[{self.value_type.type_annotation(**kwargs)},"
112
+ f' "_models.{self.name}"]'
113
+ )
114
+ return self.value_type.type_annotation(**kwargs)
115
+
116
+ def get_declaration(self, value: Any) -> str:
117
+ return self.value_type.get_declaration(value)
118
+
119
+ def docstring_text(self, **kwargs: Any) -> str:
120
+ if self.code_model.options["models_mode"]:
121
+ return self.name
122
+ return self.value_type.type_annotation(**kwargs)
123
+
124
+ def docstring_type(self, **kwargs: Any) -> str:
125
+ """The python type used for RST syntax input and type annotation."""
126
+ if self.code_model.options["models_mode"]:
127
+ return f"{self.value_type.type_annotation(**kwargs)} or ~{self.code_model.namespace}.models.{self.name}"
128
+ return self.value_type.type_annotation(**kwargs)
129
+
130
+ def get_json_template_representation(
131
+ self,
132
+ *,
133
+ optional: bool = True,
134
+ client_default_value_declaration: Optional[str] = None,
135
+ description: Optional[str] = None,
136
+ ) -> Any:
137
+ # for better display effect, use the only value instead of var type
138
+ return self.value_type.get_json_template_representation(
139
+ optional=optional,
140
+ client_default_value_declaration=client_default_value_declaration,
141
+ description=description,
142
+ )
143
+
144
+ @property
145
+ def instance_check_template(self) -> str:
146
+ return self.value_type.instance_check_template
147
+
148
+ @classmethod
149
+ def from_yaml(
150
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
151
+ ) -> "EnumType":
152
+ """Constructs an EnumType from yaml data.
153
+
154
+ :param yaml_data: the yaml data from which we will construct this schema
155
+ :type yaml_data: dict[str, Any]
156
+
157
+ :return: A created EnumType
158
+ :rtype: ~autorest.models.EnumType
159
+ """
160
+ from . import build_type
161
+
162
+ return cls(
163
+ yaml_data=yaml_data,
164
+ code_model=code_model,
165
+ value_type=build_type(yaml_data["valueType"], code_model),
166
+ values=[
167
+ EnumValue.from_yaml(value, code_model) for value in yaml_data["values"]
168
+ ],
169
+ )
170
+
171
+ def imports(self, **kwargs: Any) -> FileImport:
172
+ is_operation_file = kwargs.pop("is_operation_file", False)
173
+ file_import = FileImport()
174
+ if self.code_model.options["models_mode"]:
175
+ file_import.add_submodule_import(
176
+ "typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL
177
+ )
178
+ if not is_operation_file:
179
+ file_import.add_submodule_import(
180
+ "..",
181
+ "models",
182
+ ImportType.LOCAL,
183
+ TypingSection.TYPING,
184
+ alias="_models",
185
+ )
186
+ file_import.merge(
187
+ self.value_type.imports(is_operation_file=is_operation_file, **kwargs)
188
+ )
189
+ relative_path = kwargs.pop("relative_path", None)
190
+ if self.code_model.options["models_mode"] and relative_path:
191
+ # add import for enums in operations file
192
+ file_import.add_submodule_import(
193
+ relative_path, "models", ImportType.LOCAL, alias="_models"
194
+ )
195
+ return file_import