@autorest/python 6.1.11 → 6.2.1

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 (68) hide show
  1. package/autorest/_utils.py +2 -1
  2. package/autorest/codegen/__init__.py +23 -81
  3. package/autorest/codegen/models/__init__.py +5 -3
  4. package/autorest/codegen/models/{base_type.py → base.py} +24 -3
  5. package/autorest/codegen/models/base_builder.py +9 -5
  6. package/autorest/codegen/models/client.py +183 -13
  7. package/autorest/codegen/models/code_model.py +154 -141
  8. package/autorest/codegen/models/combined_type.py +5 -2
  9. package/autorest/codegen/models/constant_type.py +38 -4
  10. package/autorest/codegen/models/credential_types.py +1 -1
  11. package/autorest/codegen/models/dictionary_type.py +1 -1
  12. package/autorest/codegen/models/enum_type.py +5 -3
  13. package/autorest/codegen/models/imports.py +78 -29
  14. package/autorest/codegen/models/list_type.py +1 -1
  15. package/autorest/codegen/models/lro_operation.py +5 -1
  16. package/autorest/codegen/models/model_type.py +1 -2
  17. package/autorest/codegen/models/operation.py +34 -10
  18. package/autorest/codegen/models/operation_group.py +16 -5
  19. package/autorest/codegen/models/paging_operation.py +5 -4
  20. package/autorest/codegen/models/parameter.py +19 -6
  21. package/autorest/codegen/models/primitive_types.py +1 -2
  22. package/autorest/codegen/models/property.py +4 -4
  23. package/autorest/codegen/models/request_builder.py +17 -6
  24. package/autorest/codegen/models/request_builder_parameter.py +5 -2
  25. package/autorest/codegen/models/response.py +6 -3
  26. package/autorest/codegen/serializers/__init__.py +207 -135
  27. package/autorest/codegen/serializers/builder_serializer.py +2 -4
  28. package/autorest/codegen/serializers/client_serializer.py +41 -45
  29. package/autorest/codegen/serializers/general_serializer.py +80 -37
  30. package/autorest/codegen/serializers/import_serializer.py +30 -36
  31. package/autorest/codegen/serializers/metadata_serializer.py +36 -14
  32. package/autorest/codegen/serializers/model_serializer.py +34 -19
  33. package/autorest/codegen/serializers/operation_groups_serializer.py +22 -6
  34. package/autorest/codegen/serializers/operations_init_serializer.py +10 -4
  35. package/autorest/codegen/serializers/sample_serializer.py +144 -0
  36. package/autorest/codegen/templates/client.py.jinja2 +7 -15
  37. package/autorest/codegen/templates/client_container.py.jinja2 +12 -0
  38. package/autorest/codegen/templates/config.py.jinja2 +13 -26
  39. package/autorest/codegen/templates/config_container.py.jinja2 +16 -0
  40. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  41. package/autorest/codegen/templates/init.py.jinja2 +9 -3
  42. package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
  43. package/autorest/codegen/templates/metadata.json.jinja2 +13 -14
  44. package/autorest/codegen/templates/model_dpg.py.jinja2 +4 -4
  45. package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
  46. package/autorest/codegen/templates/operation.py.jinja2 +1 -1
  47. package/autorest/codegen/templates/operation_group.py.jinja2 +2 -2
  48. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +5 -5
  49. package/autorest/codegen/templates/operation_tools.jinja2 +2 -2
  50. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -4
  51. package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2} +0 -0
  52. package/autorest/codegen/templates/{LICENSE.jinja2 → packaging_templates/LICENSE.jinja2} +0 -0
  53. package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2} +0 -0
  54. package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2} +0 -0
  55. package/autorest/codegen/templates/{dev_requirements.txt.jinja2 → packaging_templates/dev_requirements.txt.jinja2} +0 -0
  56. package/autorest/codegen/templates/{setup.py.jinja2 → packaging_templates/setup.py.jinja2} +12 -9
  57. package/autorest/codegen/templates/request_builders.py.jinja2 +2 -2
  58. package/autorest/codegen/templates/sample.py.jinja2 +44 -0
  59. package/autorest/codegen/templates/vendor.py.jinja2 +4 -2
  60. package/autorest/m4reformatter/__init__.py +18 -4
  61. package/autorest/multiapi/models/imports.py +89 -18
  62. package/autorest/multiapi/serializers/import_serializer.py +88 -7
  63. package/autorest/multiapi/utils.py +6 -0
  64. package/autorest/preprocess/__init__.py +20 -8
  65. package/package.json +1 -1
  66. package/run_cadl.py +0 -1
  67. package/autorest/cadlflags/__init__.py +0 -130
  68. package/autorest/codegen/models/base_model.py +0 -28
@@ -3,20 +3,22 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
- from typing import List, Dict, Optional, Any, Set, Union
6
+ from typing import List, Dict, Any, Set, Union
7
7
 
8
- from .base_type import BaseType
8
+ from .base import BaseType
9
9
  from .enum_type import EnumType
10
10
  from .model_type import ModelType
11
- from .operation_group import OperationGroup
12
- from .client import Client, Config
13
- from .request_builder import OverloadedRequestBuilder, RequestBuilder
14
- from .parameter import Parameter
11
+ from .client import Client
12
+ from .request_builder import RequestBuilder, OverloadedRequestBuilder
13
+ from .constant_type import ConstantType
15
14
 
16
15
 
17
- class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-public-methods
18
- """Holds all of the information we have parsed out of the yaml file. The CodeModel is what gets
19
- serialized by the serializers.
16
+ def _is_legacy(options) -> bool:
17
+ return not (options["version_tolerant"] or options["low_level_client"])
18
+
19
+
20
+ class CodeModel: # pylint: disable=too-many-public-methods
21
+ """Top level code model
20
22
 
21
23
  :param options: Options of the code model. I.e., whether this is for management generation
22
24
  :type options: dict[str, bool]
@@ -34,8 +36,6 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
34
36
  :param primitives: List of schemas we've created that are not EnumSchemas or ObjectSchemas. Maps their
35
37
  yaml id to our created schemas.
36
38
  :type primitives: Dict[int, ~autorest.models.BaseType]
37
- :param operation_groups: The operation groups we are going to serialize
38
- :type operation_groups: list[~autorest.models.OperationGroup]
39
39
  :param package_dependency: All the dependencies needed in setup.py
40
40
  :type package_dependency: Dict[str, str]
41
41
  """
@@ -44,71 +44,136 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
44
44
  self,
45
45
  yaml_data: Dict[str, Any],
46
46
  options: Dict[str, Any],
47
+ *,
48
+ is_subnamespace: bool = False,
47
49
  ) -> None:
48
50
  self.yaml_data = yaml_data
49
51
  self.options = options
52
+ self.namespace = self.yaml_data["namespace"]
50
53
  self.types_map: Dict[int, BaseType] = {} # map yaml id to schema
51
- self.operation_groups: List[OperationGroup] = []
52
54
  self._model_types: List[ModelType] = []
53
- self._client: Optional[Client] = None
54
- self._config: Optional[Config] = None
55
- self.request_builders: List[
56
- Union[RequestBuilder, OverloadedRequestBuilder]
57
- ] = []
58
- self.package_dependency: Dict[str, str] = {}
59
- self.namespace: str = yaml_data["client"]["namespace"].lower()
60
- self.module_name: str = self.yaml_data["client"]["moduleName"]
55
+ from . import build_type
56
+
57
+ for type_yaml in yaml_data.get("types", []):
58
+ build_type(yaml_data=type_yaml, code_model=self)
59
+ self.clients: List[Client] = [
60
+ Client.from_yaml(client_yaml_data, self)
61
+ for client_yaml_data in yaml_data["clients"]
62
+ ]
63
+ self.subnamespace_to_clients: Dict[str, List[Client]] = {
64
+ subnamespace: [
65
+ Client.from_yaml(client_yaml, self, is_subclient=True)
66
+ for client_yaml in client_yamls
67
+ ]
68
+ for subnamespace, client_yamls in yaml_data.get(
69
+ "subnamespaceToClients", {}
70
+ ).items()
71
+ }
72
+ if self.options["models_mode"] and self.model_types:
73
+ self.sort_model_types()
74
+ self.is_subnamespace = is_subnamespace
61
75
 
62
- def lookup_type(self, schema_id: int) -> BaseType:
63
- """Looks to see if the schema has already been created.
76
+ @property
77
+ def has_operations(self) -> bool:
78
+ if any(c for c in self.clients if c.has_operations):
79
+ return True
80
+ return any(
81
+ c
82
+ for clients in self.subnamespace_to_clients.values()
83
+ for c in clients
84
+ if c.has_operations
85
+ )
64
86
 
65
- :param int schema_id: The yaml id of the schema
66
- :return: If created, we return the created schema, otherwise, we throw.
67
- :rtype: ~autorest.models.BaseType
68
- :raises: KeyError if schema is not found
69
- """
70
- try:
71
- return next(type for id, type in self.types_map.items() if id == schema_id)
72
- except StopIteration:
73
- raise KeyError(f"Couldn't find schema with id {schema_id}")
87
+ @property
88
+ def has_non_abstract_operations(self) -> bool:
89
+ for client in self.clients:
90
+ for operation_group in client.operation_groups:
91
+ for operation in operation_group.operations:
92
+ if not operation.abstract:
93
+ return True
94
+ for clients in self.subnamespace_to_clients.values():
95
+ for client in clients:
96
+ for operation_group in client.operation_groups:
97
+ for operation in operation_group.operations:
98
+ if not operation.abstract:
99
+ return True
100
+ return False
101
+
102
+ def lookup_request_builder(
103
+ self, request_builder_id: int
104
+ ) -> Union[RequestBuilder, OverloadedRequestBuilder]:
105
+ """Find the request builder based off of id"""
106
+ for client in self.clients:
107
+ try:
108
+ return client.lookup_request_builder(request_builder_id)
109
+ except KeyError:
110
+ pass
111
+ raise KeyError(f"No request builder with id {request_builder_id} found.")
112
+
113
+ @property
114
+ def rest_layer_name(self) -> str:
115
+ """If we have a separate rest layer, what is its name?"""
116
+ return "rest" if self.options["builders_visibility"] == "public" else "_rest"
117
+
118
+ @property
119
+ def client_filename(self) -> str:
120
+ return self.clients[0].filename
121
+
122
+ def need_vendored_code(self, async_mode: bool) -> bool:
123
+ """Whether we need to vendor code in the _vendor.py file for this SDK"""
124
+ if self.has_abstract_operations:
125
+ return True
126
+ if async_mode:
127
+ return self.need_mixin_abc
128
+ return (
129
+ self.need_request_converter or self.need_format_url or self.need_mixin_abc
130
+ )
74
131
 
75
132
  @property
76
- def credential(self) -> Optional[Parameter]:
77
- """The credential param, if one exists"""
78
- return self.client.parameters.credential
133
+ def need_request_converter(self) -> bool:
134
+ return any(c for c in self.clients if c.need_request_converter)
79
135
 
80
136
  @property
81
- def client(self) -> Client:
82
- if not self._client:
83
- raise ValueError("You haven't linked the client yet")
84
- return self._client
137
+ def need_format_url(self) -> bool:
138
+ return any(c for c in self.clients if c.need_format_url)
85
139
 
86
- @client.setter
87
- def client(self, val: Client) -> None:
88
- self._client = val
140
+ @property
141
+ def need_mixin_abc(self) -> bool:
142
+ return any(c for c in self.clients if c.has_mixin)
89
143
 
90
144
  @property
91
- def config(self) -> Config:
92
- if not self._config:
93
- raise ValueError("You haven't linked the config yet")
94
- return self._config
145
+ def has_abstract_operations(self) -> bool:
146
+ return any(c for c in self.clients if c.has_abstract_operations)
95
147
 
96
- @config.setter
97
- def config(self, val: Config) -> None:
98
- self._config = val
148
+ @property
149
+ def operations_folder_name(self) -> str:
150
+ """Get the name of the operations folder that holds operations."""
151
+ name = "operations"
152
+ if self.options["version_tolerant"] and not any(
153
+ og
154
+ for client in self.clients
155
+ for og in client.operation_groups
156
+ if not og.is_mixin
157
+ ):
158
+ name = f"_{name}"
159
+ return name
99
160
 
100
- def lookup_request_builder(
101
- self, request_builder_id: int
102
- ) -> Union[RequestBuilder, OverloadedRequestBuilder]:
103
- """Find the request builder based off of id"""
161
+ @property
162
+ def description(self) -> str:
163
+ return self.clients[0].description
164
+
165
+ def lookup_type(self, schema_id: int) -> BaseType:
166
+ """Looks to see if the schema has already been created.
167
+
168
+ :param int schema_id: The yaml id of the schema
169
+ :return: If created, we return the created schema, otherwise, we throw.
170
+ :rtype: ~autorest.models.BaseType
171
+ :raises: KeyError if schema is not found
172
+ """
104
173
  try:
105
- return next(
106
- rb
107
- for rb in self.request_builders
108
- if id(rb.yaml_data) == request_builder_id
109
- )
174
+ return next(type for id, type in self.types_map.items() if id == schema_id)
110
175
  except StopIteration:
111
- raise KeyError(f"No request builder with id {request_builder_id} found.")
176
+ raise KeyError(f"Couldn't find schema with id {schema_id}")
112
177
 
113
178
  @property
114
179
  def model_types(self) -> List[ModelType]:
@@ -132,9 +197,11 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
132
197
  """All of the enums"""
133
198
  return [t for t in self.types_map.values() if isinstance(t, EnumType)]
134
199
 
135
- @staticmethod
136
200
  def _sort_model_types_helper(
137
- current: ModelType, seen_schema_names: Set[str], seen_schema_yaml_ids: Set[int]
201
+ self,
202
+ current: ModelType,
203
+ seen_schema_names: Set[str],
204
+ seen_schema_yaml_ids: Set[int],
138
205
  ):
139
206
  if current.id in seen_schema_yaml_ids:
140
207
  return []
@@ -150,7 +217,7 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
150
217
  seen_schema_names.add(current.name)
151
218
  seen_schema_yaml_ids.add(current.id)
152
219
  ancestors = (
153
- CodeModel._sort_model_types_helper(
220
+ self._sort_model_types_helper(
154
221
  parent, seen_schema_names, seen_schema_yaml_ids
155
222
  )
156
223
  + ancestors
@@ -170,84 +237,12 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
170
237
  sorted_object_schemas: List[ModelType] = []
171
238
  for schema in sorted(self.model_types, key=lambda x: x.name.lower()):
172
239
  sorted_object_schemas.extend(
173
- CodeModel._sort_model_types_helper(
240
+ self._sort_model_types_helper(
174
241
  schema, seen_schema_names, seen_schema_yaml_ids
175
242
  )
176
243
  )
177
244
  self.model_types = sorted_object_schemas
178
245
 
179
- def format_lro_operations(self) -> None:
180
- """Adds operations and attributes needed for LROs.
181
- If there are LRO functions in here, will add initial LRO function. Will also set the return
182
- type of the LRO operation
183
- """
184
- for operation_group in self.operation_groups:
185
- i = 0
186
- while i < len(operation_group.operations):
187
- operation = operation_group.operations[i]
188
- if operation.operation_type in ("lro", "lropaging"):
189
- operation_group.operations.insert(i, operation.initial_operation) # type: ignore
190
- i += 1
191
- i += 1
192
-
193
- @property
194
- def operations_folder_name(self) -> str:
195
- """Get the name of the operations folder that holds operations."""
196
- name = "operations"
197
- if self.options["version_tolerant"] and not any(
198
- og for og in self.operation_groups if not og.is_mixin
199
- ):
200
- name = f"_{name}"
201
- return name
202
-
203
- @property
204
- def has_abstract_operations(self) -> bool:
205
- """Whether there is abstract operation in any operation group."""
206
- return any(og.has_abstract_operations for og in self.operation_groups)
207
-
208
- def need_vendored_code(self, async_mode: bool) -> bool:
209
- """Whether we need to vendor code in the _vendor.py file for this SDK"""
210
- if self.has_abstract_operations:
211
- return True
212
- if async_mode:
213
- return self.need_mixin_abc
214
- return (
215
- self.need_request_converter or self.need_format_url or self.need_mixin_abc
216
- )
217
-
218
- @property
219
- def need_request_converter(self) -> bool:
220
- """
221
- Whether we need to convert our created azure.core.rest.HttpRequests to
222
- azure.core.pipeline.transport.HttpRequests
223
- """
224
- return (
225
- self.options["show_operations"]
226
- and bool(self.request_builders)
227
- and not self.options["version_tolerant"]
228
- )
229
-
230
- @property
231
- def need_format_url(self) -> bool:
232
- """Whether we need to format urls. If so, we need to vendor core."""
233
- return any(rq for rq in self.request_builders if rq.parameters.path)
234
-
235
- @property
236
- def need_mixin_abc(self) -> bool:
237
- """Do we want a mixin ABC class for typing purposes?"""
238
- return any(o for o in self.operation_groups if o.is_mixin)
239
-
240
- @property
241
- def has_lro_operations(self) -> bool:
242
- """Are there any LRO operations in this SDK?"""
243
- return any(
244
- [
245
- operation.operation_type in ("lro", "lropaging")
246
- for operation_group in self.operation_groups
247
- for operation in operation_group.operations
248
- ]
249
- )
250
-
251
246
  @property
252
247
  def models_filename(self) -> str:
253
248
  """Get the names of the model file(s)"""
@@ -259,16 +254,34 @@ class CodeModel: # pylint: disable=too-many-instance-attributes, too-many-publi
259
254
  def enums_filename(self) -> str:
260
255
  """The name of the enums file"""
261
256
  if self.is_legacy:
262
- return f"_{self.module_name}_enums"
257
+ return f"_{self.clients[0].legacy_filename}_enums"
263
258
  return "_enums"
264
259
 
265
260
  @property
266
261
  def is_legacy(self) -> bool:
267
- return not (
268
- self.options["version_tolerant"] or self.options["low_level_client"]
269
- )
262
+ return _is_legacy(self.options)
270
263
 
271
264
  @property
272
- def rest_layer_name(self) -> str:
273
- """If we have a separate rest layer, what is its name?"""
274
- return "rest" if self.options["builders_visibility"] == "public" else "_rest"
265
+ def need_typing_extensions(self) -> bool:
266
+ if self.options["models_mode"] and any(
267
+ isinstance(p.type, ConstantType)
268
+ and (p.optional or self.options["models_mode"] == "dpg")
269
+ for model in self.model_types
270
+ for p in model.properties
271
+ ):
272
+ return True
273
+ if any(
274
+ isinstance(parameter.type, ConstantType)
275
+ for client in self.clients
276
+ for og in client.operation_groups
277
+ for op in og.operations
278
+ for parameter in op.parameters.method
279
+ ):
280
+ return True
281
+ if any(
282
+ isinstance(parameter.type, ConstantType)
283
+ for client in self.clients
284
+ for parameter in client.config.parameters.kwargs_to_pop
285
+ ):
286
+ return True
287
+ return False
@@ -6,7 +6,7 @@
6
6
  from typing import Any, Dict, List, Optional, TYPE_CHECKING
7
7
  import re
8
8
  from autorest.codegen.models.imports import FileImport, ImportType
9
- from .base_type import BaseType
9
+ from .base import BaseType
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from .code_model import CodeModel
@@ -21,7 +21,10 @@ class CombinedType(BaseType):
21
21
  """
22
22
 
23
23
  def __init__(
24
- self, yaml_data: Dict[str, Any], code_model: "CodeModel", types: List[BaseType]
24
+ self,
25
+ yaml_data: Dict[str, Any],
26
+ code_model: "CodeModel",
27
+ types: List[BaseType],
25
28
  ) -> None:
26
29
  super().__init__(yaml_data, code_model)
27
30
  self.types = types # the types that this type is combining
@@ -5,8 +5,9 @@
5
5
  # --------------------------------------------------------------------------
6
6
  import logging
7
7
  from typing import Dict, Any, Optional, TYPE_CHECKING
8
- from .base_type import BaseType
9
- from .imports import FileImport
8
+ from .base import BaseType
9
+ from .imports import FileImport, ImportType, TypingSection
10
+ from .primitive_types import IntegerType, BinaryType, StringType, BooleanType
10
11
  from .utils import add_to_description
11
12
 
12
13
  if TYPE_CHECKING:
@@ -75,7 +76,17 @@ class ConstantType(BaseType):
75
76
  return self.value_type.docstring_type(**kwargs)
76
77
 
77
78
  def type_annotation(self, **kwargs: Any) -> str:
78
- return self.value_type.type_annotation(**kwargs)
79
+ return (
80
+ f"Literal[{self.get_declaration()}]"
81
+ if self._is_literal
82
+ else self.value_type.type_annotation(**kwargs)
83
+ )
84
+
85
+ @property
86
+ def _is_literal(self) -> bool:
87
+ return isinstance(
88
+ self.value_type, (IntegerType, BinaryType, StringType, BooleanType)
89
+ )
79
90
 
80
91
  @classmethod
81
92
  def from_yaml(
@@ -112,11 +123,34 @@ class ConstantType(BaseType):
112
123
  description=description,
113
124
  )
114
125
 
115
- def imports(self, **kwargs: Any) -> FileImport:
126
+ def _imports_shared(self, **kwargs: Any):
116
127
  file_import = FileImport()
117
128
  file_import.merge(self.value_type.imports(**kwargs))
118
129
  return file_import
119
130
 
131
+ def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
132
+ return self._imports_shared(**kwargs)
133
+
134
+ def imports(self, **kwargs: Any) -> FileImport:
135
+ file_import = self._imports_shared(**kwargs)
136
+ if self._is_literal:
137
+ file_import.add_import("sys", ImportType.STDLIB)
138
+ file_import.add_submodule_import(
139
+ "typing_extensions",
140
+ "Literal",
141
+ ImportType.BYVERSION,
142
+ TypingSection.REGULAR,
143
+ None,
144
+ (
145
+ (
146
+ (3, 8),
147
+ "typing",
148
+ "pylint: disable=no-name-in-module, ungrouped-imports",
149
+ ),
150
+ ),
151
+ )
152
+ return file_import
153
+
120
154
  @property
121
155
  def instance_check_template(self) -> str:
122
156
  return self.value_type.instance_check_template
@@ -17,7 +17,7 @@ from typing import (
17
17
  )
18
18
 
19
19
  from .imports import FileImport, ImportType, TypingSection
20
- from .base_type import BaseType
20
+ from .base import BaseType
21
21
 
22
22
  if TYPE_CHECKING:
23
23
  from .code_model import CodeModel
@@ -4,7 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from typing import Any, Dict, Optional, TYPE_CHECKING, List
7
- from .base_type import BaseType
7
+ from .base import BaseType
8
8
  from .imports import FileImport, ImportType, TypingSection
9
9
 
10
10
  if TYPE_CHECKING:
@@ -5,9 +5,9 @@
5
5
  # --------------------------------------------------------------------------
6
6
  from typing import Any, Dict, List, TYPE_CHECKING, Optional
7
7
 
8
- from .base_type import BaseType
8
+ from .base import BaseType
9
9
  from .imports import FileImport, ImportType, TypingSection
10
- from .base_model import BaseModel
10
+ from .base import BaseModel
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from .code_model import CodeModel
@@ -126,7 +126,9 @@ class EnumType(BaseType):
126
126
  def docstring_type(self, **kwargs: Any) -> str:
127
127
  """The python type used for RST syntax input and type annotation."""
128
128
  if self.code_model.options["models_mode"]:
129
- return f"{self.value_type.type_annotation(**kwargs)} or ~{self.code_model.namespace}.models.{self.name}"
129
+ type_annotation = self.value_type.type_annotation(**kwargs)
130
+ enum_type_annotation = f"{self.code_model.namespace}.models.{self.name}"
131
+ return f"{type_annotation} or ~{enum_type_annotation}"
130
132
  return self.value_type.type_annotation(**kwargs)
131
133
 
132
134
  def get_json_template_representation(