@autorest/python 5.15.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 (86) hide show
  1. package/ChangeLog.md +20 -0
  2. package/autorest/__init__.py +1 -2
  3. package/autorest/black/__init__.py +12 -5
  4. package/autorest/codegen/__init__.py +145 -73
  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 +19 -18
  9. package/autorest/codegen/models/client.py +65 -21
  10. package/autorest/codegen/models/code_model.py +107 -61
  11. package/autorest/codegen/models/constant_schema.py +25 -13
  12. package/autorest/codegen/models/credential_model.py +23 -15
  13. package/autorest/codegen/models/credential_schema.py +18 -14
  14. package/autorest/codegen/models/credential_schema_policy.py +11 -15
  15. package/autorest/codegen/models/dictionary_schema.py +20 -17
  16. package/autorest/codegen/models/enum_schema.py +35 -25
  17. package/autorest/codegen/models/imports.py +70 -41
  18. package/autorest/codegen/models/list_schema.py +25 -13
  19. package/autorest/codegen/models/lro_operation.py +58 -22
  20. package/autorest/codegen/models/lro_paging_operation.py +2 -3
  21. package/autorest/codegen/models/object_schema.py +99 -49
  22. package/autorest/codegen/models/operation.py +236 -117
  23. package/autorest/codegen/models/operation_group.py +64 -34
  24. package/autorest/codegen/models/paging_operation.py +45 -18
  25. package/autorest/codegen/models/parameter.py +151 -83
  26. package/autorest/codegen/models/parameter_list.py +183 -162
  27. package/autorest/codegen/models/primitive_schemas.py +84 -55
  28. package/autorest/codegen/models/property.py +44 -26
  29. package/autorest/codegen/models/request_builder.py +65 -30
  30. package/autorest/codegen/models/request_builder_parameter.py +47 -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 +18 -13
  34. package/autorest/codegen/models/utils.py +5 -2
  35. package/autorest/codegen/serializers/__init__.py +182 -91
  36. package/autorest/codegen/serializers/builder_serializer.py +667 -331
  37. package/autorest/codegen/serializers/client_serializer.py +98 -37
  38. package/autorest/codegen/serializers/general_serializer.py +61 -26
  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 +35 -15
  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 +7 -6
  45. package/autorest/codegen/serializers/operation_groups_serializer.py +20 -9
  46. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  47. package/autorest/codegen/serializers/patch_serializer.py +4 -1
  48. package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
  49. package/autorest/codegen/serializers/utils.py +35 -21
  50. package/autorest/codegen/templates/init.py.jinja2 +2 -2
  51. package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
  52. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
  53. package/autorest/codegen/templates/metadata.json.jinja2 +7 -6
  54. package/autorest/codegen/templates/operation.py.jinja2 +7 -9
  55. package/autorest/codegen/templates/operation_group.py.jinja2 +2 -8
  56. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  57. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  58. package/autorest/codegen/templates/request_builder.py.jinja2 +18 -11
  59. package/autorest/jsonrpc/__init__.py +7 -12
  60. package/autorest/jsonrpc/localapi.py +4 -3
  61. package/autorest/jsonrpc/server.py +13 -6
  62. package/autorest/jsonrpc/stdstream.py +13 -6
  63. package/autorest/m2r/__init__.py +5 -8
  64. package/autorest/multiapi/__init__.py +24 -14
  65. package/autorest/multiapi/models/client.py +21 -11
  66. package/autorest/multiapi/models/code_model.py +23 -10
  67. package/autorest/multiapi/models/config.py +4 -1
  68. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  69. package/autorest/multiapi/models/global_parameter.py +2 -1
  70. package/autorest/multiapi/models/global_parameters.py +14 -8
  71. package/autorest/multiapi/models/imports.py +24 -17
  72. package/autorest/multiapi/models/mixin_operation.py +5 -5
  73. package/autorest/multiapi/models/operation_group.py +2 -1
  74. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  75. package/autorest/multiapi/serializers/__init__.py +18 -23
  76. package/autorest/multiapi/serializers/import_serializer.py +47 -17
  77. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  78. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
  79. package/autorest/multiapi/utils.py +3 -3
  80. package/autorest/namer/__init__.py +2 -4
  81. package/autorest/namer/name_converter.py +200 -103
  82. package/autorest/namer/python_mappings.py +10 -22
  83. package/package.json +2 -2
  84. package/run-python3.js +2 -3
  85. package/venvtools.py +1 -1
  86. package/autorest/codegen/models/rest.py +0 -42
@@ -3,10 +3,14 @@
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 Any, Dict, Optional
6
+ from typing import Any, Dict, Optional, TYPE_CHECKING
7
7
  from .base_schema import BaseSchema
8
8
  from .imports import FileImport, ImportType, TypingSection
9
9
 
10
+ if TYPE_CHECKING:
11
+ from .code_model import CodeModel
12
+
13
+
10
14
  class DictionarySchema(BaseSchema):
11
15
  """Schema for dictionaries that will be serialized.
12
16
 
@@ -18,11 +22,11 @@ class DictionarySchema(BaseSchema):
18
22
 
19
23
  def __init__(
20
24
  self,
21
- namespace: str,
22
25
  yaml_data: Dict[str, Any],
23
- element_type: "BaseSchema"
26
+ code_model: "CodeModel",
27
+ element_type: "BaseSchema",
24
28
  ) -> None:
25
- super(DictionarySchema, self).__init__(namespace=namespace, yaml_data=yaml_data)
29
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
26
30
  self.element_type = element_type
27
31
 
28
32
  @property
@@ -55,20 +59,19 @@ class DictionarySchema(BaseSchema):
55
59
  return f"dict[str, {self.element_type.docstring_type}]"
56
60
 
57
61
  def xml_serialization_ctxt(self) -> Optional[str]:
58
- raise NotImplementedError("Dictionary schema does not support XML serialization.")
62
+ raise NotImplementedError(
63
+ "Dictionary schema does not support XML serialization."
64
+ )
59
65
 
60
66
  def get_json_template_representation(self, **kwargs: Any) -> Any:
61
67
  return {
62
- f'"{"str"}"' : self.element_type.get_json_template_representation(**kwargs)
63
- }
64
-
65
- def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
66
- return {
67
- f'"{"str"}"' : self.element_type.get_files_and_data_template_representation(**kwargs)
68
+ f'"{"str"}"': self.element_type.get_json_template_representation(**kwargs)
68
69
  }
69
70
 
70
71
  @classmethod
71
- def from_yaml(cls, namespace: str, yaml_data: Dict[str, Any], **kwargs: Any) -> "DictionarySchema":
72
+ def from_yaml(
73
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
74
+ ) -> "DictionarySchema":
72
75
  """Constructs a DictionarySchema from yaml data.
73
76
 
74
77
  :param yaml_data: the yaml data from which we will construct this schema
@@ -81,19 +84,19 @@ class DictionarySchema(BaseSchema):
81
84
 
82
85
  from . import build_schema # pylint: disable=import-outside-toplevel
83
86
 
84
- element_type = build_schema(
85
- yaml_data=element_schema, **kwargs
86
- )
87
+ element_type = build_schema(yaml_data=element_schema, code_model=code_model)
87
88
 
88
89
  return cls(
89
- namespace=namespace,
90
90
  yaml_data=yaml_data,
91
+ code_model=code_model,
91
92
  element_type=element_type,
92
93
  )
93
94
 
94
95
  def imports(self) -> FileImport:
95
96
  file_import = FileImport()
96
- file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL)
97
+ file_import.add_submodule_import(
98
+ "typing", "Dict", ImportType.STDLIB, TypingSection.CONDITIONAL
99
+ )
97
100
  file_import.merge(self.element_type.imports())
98
101
  return file_import
99
102
 
@@ -3,11 +3,14 @@
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 Any, Dict, List, Optional, Set, Type
6
+ from typing import Any, Dict, List, Optional, Set, Type, TYPE_CHECKING
7
7
  from .base_schema import BaseSchema
8
8
  from .primitive_schemas import PrimitiveSchema, get_primitive_schema, StringSchema
9
9
  from .imports import FileImport, ImportType, TypingSection
10
10
 
11
+ if TYPE_CHECKING:
12
+ from .code_model import CodeModel
13
+
11
14
 
12
15
  class EnumValue:
13
16
  """Model containing necessary information for a single value of an enum.
@@ -17,7 +20,9 @@ class EnumValue:
17
20
  :param str description: Optional. The description for this enum value
18
21
  """
19
22
 
20
- def __init__(self, name: str, value: str, description: Optional[str] = None) -> None:
23
+ def __init__(
24
+ self, name: str, value: str, description: Optional[str] = None
25
+ ) -> None:
21
26
  self.name = name
22
27
  self.value = value
23
28
  self.description = description
@@ -53,14 +58,14 @@ class EnumSchema(BaseSchema):
53
58
 
54
59
  def __init__(
55
60
  self,
56
- namespace: str,
57
61
  yaml_data: Dict[str, Any],
62
+ code_model: "CodeModel",
58
63
  description: str,
59
64
  name: str,
60
65
  values: List["EnumValue"],
61
66
  enum_type: PrimitiveSchema,
62
67
  ) -> None:
63
- super(EnumSchema, self).__init__(namespace=namespace, yaml_data=yaml_data)
68
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
64
69
  self.description = description
65
70
  self.name = name
66
71
  self.values = values
@@ -95,9 +100,8 @@ class EnumSchema(BaseSchema):
95
100
 
96
101
  @property
97
102
  def docstring_type(self) -> str:
98
- """The python type used for RST syntax input and type annotation.
99
- """
100
- return f"{self.enum_type.type_annotation()} or ~{self.namespace}.models.{self.name}"
103
+ """The python type used for RST syntax input and type annotation."""
104
+ return f"{self.enum_type.type_annotation()} or ~{self.code_model.namespace}.models.{self.name}"
101
105
 
102
106
  @staticmethod
103
107
  def _get_enum_values(yaml_data: List[Dict[str, Any]]) -> List["EnumValue"]:
@@ -121,21 +125,23 @@ class EnumSchema(BaseSchema):
121
125
 
122
126
  def _template_kwargs(self, **kwargs: Any) -> Any:
123
127
  if len(self.values) == 1 and not kwargs.get("default_value_declaration"):
124
- kwargs['default_value_declaration'] = self.enum_type.get_declaration(self.values[0].value)
128
+ kwargs["default_value_declaration"] = self.enum_type.get_declaration(
129
+ self.values[0].value
130
+ )
125
131
  description = kwargs.pop("description", "")
126
132
  kwargs["description"] = description
127
133
  return kwargs
128
134
 
129
-
130
135
  def get_json_template_representation(self, **kwargs: Any) -> Any:
131
136
  # for better display effect, use the only value instead of var type
132
- return self.enum_type.get_json_template_representation(**self._template_kwargs(**kwargs))
133
-
134
- def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
135
- return self.enum_type.get_files_and_data_template_representation(**self._template_kwargs(**kwargs))
137
+ return self.enum_type.get_json_template_representation(
138
+ **self._template_kwargs(**kwargs)
139
+ )
136
140
 
137
141
  @classmethod
138
- def from_yaml(cls, namespace: str, yaml_data: Dict[str, Any], **kwargs: Any) -> "EnumSchema":
142
+ def from_yaml(
143
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
144
+ ) -> "EnumSchema":
139
145
  """Constructs an EnumSchema from yaml data.
140
146
 
141
147
  :param yaml_data: the yaml data from which we will construct this schema
@@ -148,13 +154,13 @@ class EnumSchema(BaseSchema):
148
154
 
149
155
  # choice type doesn't always exist. if there is no choiceType, we default to string
150
156
  if yaml_data.get("choiceType"):
151
- enum_type = get_primitive_schema(namespace, yaml_data["choiceType"])
157
+ enum_type = get_primitive_schema(yaml_data["choiceType"], code_model)
152
158
  else:
153
- enum_type = StringSchema(namespace, {"type": "str"})
159
+ enum_type = StringSchema({"type": "str"}, code_model)
154
160
  values = EnumSchema._get_enum_values(yaml_data["choices"])
155
161
  return cls(
156
- namespace=namespace,
157
162
  yaml_data=yaml_data,
163
+ code_model=code_model,
158
164
  description=yaml_data["language"]["python"]["description"],
159
165
  name=name,
160
166
  values=values,
@@ -163,13 +169,14 @@ class EnumSchema(BaseSchema):
163
169
 
164
170
  def imports(self) -> FileImport:
165
171
  file_import = FileImport()
166
- file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
172
+ file_import.add_submodule_import(
173
+ "typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL
174
+ )
167
175
  file_import.merge(self.enum_type.imports())
168
176
  return file_import
169
177
 
170
178
 
171
179
  class HiddenModelEnumSchema(EnumSchema):
172
-
173
180
  def imports(self) -> FileImport:
174
181
  file_import = FileImport()
175
182
  file_import.merge(self.enum_type.imports())
@@ -185,7 +192,9 @@ class HiddenModelEnumSchema(EnumSchema):
185
192
 
186
193
  @property
187
194
  def docstring_text(self) -> str:
188
- return f"{self.enum_type.type_annotation()}. {self.extra_description_information}"
195
+ return (
196
+ f"{self.enum_type.type_annotation()}. {self.extra_description_information}"
197
+ )
189
198
 
190
199
  @property
191
200
  def extra_description_information(self):
@@ -197,18 +206,19 @@ class HiddenModelEnumSchema(EnumSchema):
197
206
  if len(possible_values) == 2:
198
207
  possible_values_str = " or ".join(possible_values)
199
208
  else:
200
- possible_values_str = ", ".join(
201
- possible_values[: len(possible_values) - 1]
202
- ) + f", and {possible_values[-1]}"
209
+ possible_values_str = (
210
+ ", ".join(possible_values[: len(possible_values) - 1])
211
+ + f", and {possible_values[-1]}"
212
+ )
203
213
 
204
214
  return "Known values are: {}.".format(possible_values_str)
205
215
 
206
216
  @property
207
217
  def docstring_type(self) -> str:
208
- """The python type used for RST syntax input and type annotation.
209
- """
218
+ """The python type used for RST syntax input and type annotation."""
210
219
  return self.enum_type.type_annotation()
211
220
 
221
+
212
222
  def get_enum_schema(code_model) -> Type[EnumSchema]:
213
223
  if code_model.options["models_mode"]:
214
224
  return EnumSchema
@@ -4,7 +4,8 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from enum import Enum
7
- from typing import Dict, List, Optional, Tuple, Union, Set
7
+ from typing import Dict, List, Optional, Tuple, Union, Set, Mapping
8
+
8
9
 
9
10
  class ImportType(str, Enum):
10
11
  STDLIB = "stdlib"
@@ -12,11 +13,13 @@ class ImportType(str, Enum):
12
13
  AZURECORE = "azurecore"
13
14
  LOCAL = "local"
14
15
 
16
+
15
17
  class TypingSection(str, Enum):
16
18
  REGULAR = "regular" # this import is always a typing import
17
19
  CONDITIONAL = "conditional" # is a typing import when we're dealing with files that py2 will use, else regular
18
20
  TYPING = "typing" # never a typing import
19
21
 
22
+
20
23
  class ImportModel:
21
24
  def __init__(
22
25
  self,
@@ -36,11 +39,11 @@ class ImportModel:
36
39
  def __eq__(self, other):
37
40
  try:
38
41
  return (
39
- self.typing_section == other.typing_section and
40
- self.import_type == other.import_type and
41
- self.module_name == other.module_name and
42
- self.submodule_name == other.submodule_name and
43
- self.alias == other.alias
42
+ self.typing_section == other.typing_section
43
+ and self.import_type == other.import_type
44
+ and self.module_name == other.module_name
45
+ and self.submodule_name == other.submodule_name
46
+ and self.alias == other.alias
44
47
  )
45
48
  except AttributeError:
46
49
  return False
@@ -52,18 +55,32 @@ class ImportModel:
52
55
  retval += hash(getattr(self, attr))
53
56
  return retval
54
57
 
55
- class FileImport:
58
+
59
+ class TypeDefinition:
56
60
  def __init__(
57
61
  self,
58
- imports: List[ImportModel] = None
59
- ) -> None:
62
+ sync_definition: str,
63
+ async_definition: str,
64
+ version_imports: Mapping[Optional[Tuple[int, int]], ImportModel] = None,
65
+ ):
66
+ # version_imports: a map of "python version -> ImportModel".
67
+ # The python version is in form of (major, minor), for instance (3, 9) stands for py3.9.
68
+ # If the python version is None, it's a default ImportModel.
69
+ self.sync_definition = sync_definition
70
+ self.async_definition = async_definition
71
+ self.version_imports = version_imports
72
+
73
+
74
+ class FileImport:
75
+ def __init__(self, imports: List[ImportModel] = None) -> None:
60
76
  self.imports = imports or []
61
77
  # has sync and async type definitions
62
- self.type_definitions: Dict[str, Tuple[str, str]] = {}
78
+ self.type_definitions: Dict[str, TypeDefinition] = {}
63
79
 
64
80
  def _append_import(self, import_model: ImportModel) -> None:
65
81
  if not any(
66
- i for i in self.imports
82
+ i
83
+ for i in self.imports
67
84
  if all(
68
85
  getattr(i, attr) == getattr(import_model, attr)
69
86
  for attr in dir(i)
@@ -72,7 +89,9 @@ class FileImport:
72
89
  ):
73
90
  self.imports.append(import_model)
74
91
 
75
- def get_imports_from_section(self, typing_section: TypingSection) -> List[ImportModel]:
92
+ def get_imports_from_section(
93
+ self, typing_section: TypingSection
94
+ ) -> List[ImportModel]:
76
95
  return [i for i in self.imports if i.typing_section == typing_section]
77
96
 
78
97
  def add_submodule_import(
@@ -83,15 +102,16 @@ class FileImport:
83
102
  typing_section: TypingSection = TypingSection.REGULAR,
84
103
  alias: Optional[str] = None,
85
104
  ) -> None:
86
- """Add an import to this import block.
87
- """
88
- self._append_import(ImportModel(
89
- typing_section=typing_section,
90
- import_type=import_type,
91
- module_name=module_name,
92
- submodule_name=submodule_name,
93
- alias=alias,
94
- ))
105
+ """Add an import to this import block."""
106
+ self._append_import(
107
+ ImportModel(
108
+ typing_section=typing_section,
109
+ import_type=import_type,
110
+ module_name=module_name,
111
+ submodule_name=submodule_name,
112
+ alias=alias,
113
+ )
114
+ )
95
115
 
96
116
  def add_import(
97
117
  self,
@@ -101,16 +121,25 @@ class FileImport:
101
121
  alias: Optional[str] = None,
102
122
  ) -> None:
103
123
  # Implementation detail: a regular import is just a "from" with no from
104
- self._append_import(ImportModel(
105
- typing_section=typing_section,
106
- import_type=import_type,
107
- module_name=module_name,
108
- alias=alias,
109
- ))
124
+ self._append_import(
125
+ ImportModel(
126
+ typing_section=typing_section,
127
+ import_type=import_type,
128
+ module_name=module_name,
129
+ alias=alias,
130
+ )
131
+ )
110
132
 
111
- def define_mypy_type(self, type_name: str, type_value: str, async_type_value: Optional[str] = None):
112
- self.add_submodule_import("typing", "TypeVar", ImportType.STDLIB, TypingSection.CONDITIONAL)
113
- self.type_definitions[type_name] = (type_value, async_type_value or type_value)
133
+ def define_mypy_type(
134
+ self,
135
+ type_name: str,
136
+ type_value: str,
137
+ async_type_value: Optional[str] = None,
138
+ version_imports: Mapping[Optional[Tuple[int, int]], ImportModel] = None,
139
+ ):
140
+ self.type_definitions[type_name] = TypeDefinition(
141
+ type_value, async_type_value or type_value, version_imports
142
+ )
114
143
 
115
144
  def merge(self, file_import: "FileImport") -> None:
116
145
  """Merge the given file import format."""
@@ -118,23 +147,23 @@ class FileImport:
118
147
  self._append_import(i)
119
148
  self.type_definitions.update(file_import.type_definitions)
120
149
 
121
- def to_dict(self) -> Dict[
150
+ def to_dict(
151
+ self,
152
+ ) -> Dict[
122
153
  TypingSection,
123
- Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]]
154
+ Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]],
124
155
  ]:
125
156
  retval: Dict[
126
157
  TypingSection,
127
- Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]]
158
+ Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]],
128
159
  ] = dict()
129
160
  for i in self.imports:
130
161
  name_import: Optional[Union[str, Tuple[str, str]]] = None
131
162
  if i.submodule_name:
132
- name_import = (i.submodule_name, i.alias) if i.alias else i.submodule_name
133
- retval.setdefault(
134
- i.typing_section, dict()
135
- ).setdefault(
136
- i.import_type, dict()
137
- ).setdefault(
138
- i.module_name, set()
139
- ).add(name_import)
163
+ name_import = (
164
+ (i.submodule_name, i.alias) if i.alias else i.submodule_name
165
+ )
166
+ retval.setdefault(i.typing_section, dict()).setdefault(
167
+ i.import_type, dict()
168
+ ).setdefault(i.module_name, set()).add(name_import)
140
169
  return retval
@@ -3,23 +3,26 @@
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 Any, Dict, Optional, Union
6
+ from typing import Any, Dict, Optional, Union, TYPE_CHECKING
7
7
  from .base_schema import BaseSchema
8
8
  from .imports import FileImport, ImportType, TypingSection
9
9
 
10
+ if TYPE_CHECKING:
11
+ from .code_model import CodeModel
12
+
10
13
 
11
14
  class ListSchema(BaseSchema):
12
15
  def __init__(
13
16
  self,
14
- namespace: str,
15
17
  yaml_data: Dict[str, Any],
18
+ code_model: "CodeModel",
16
19
  element_type: BaseSchema,
17
20
  *,
18
21
  max_items: Optional[int] = None,
19
22
  min_items: Optional[int] = None,
20
23
  unique_items: Optional[int] = None,
21
24
  ) -> None:
22
- super(ListSchema, self).__init__(namespace=namespace, yaml_data=yaml_data)
25
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
23
26
  self.element_type = element_type
24
27
  self.max_items = max_items
25
28
  self.min_items = min_items
@@ -32,7 +35,9 @@ class ListSchema(BaseSchema):
32
35
  def type_annotation(self, *, is_operation_file: bool = False) -> str:
33
36
  if self.element_type.type_annotation() == "ET.Element":
34
37
  # this means we're version tolerant XML, we just return the XML element
35
- return self.element_type.type_annotation(is_operation_file=is_operation_file)
38
+ return self.element_type.type_annotation(
39
+ is_operation_file=is_operation_file
40
+ )
36
41
  return f"List[{self.element_type.type_annotation(is_operation_file=is_operation_file)}]"
37
42
 
38
43
  @property
@@ -63,14 +68,14 @@ class ListSchema(BaseSchema):
63
68
 
64
69
  @property
65
70
  def has_xml_serialization_ctxt(self) -> bool:
66
- return super().has_xml_serialization_ctxt or self.element_type.has_xml_serialization_ctxt
71
+ return (
72
+ super().has_xml_serialization_ctxt
73
+ or self.element_type.has_xml_serialization_ctxt
74
+ )
67
75
 
68
76
  def get_json_template_representation(self, **kwargs: Any) -> Any:
69
77
  return [self.element_type.get_json_template_representation(**kwargs)]
70
78
 
71
- def get_files_and_data_template_representation(self, **kwargs: Any) -> Any:
72
- return [self.element_type.get_files_and_data_template_representation(**kwargs)]
73
-
74
79
  def xml_serialization_ctxt(self) -> Optional[str]:
75
80
  attrs_list = []
76
81
  base_xml_map = super().xml_serialization_ctxt()
@@ -93,17 +98,19 @@ class ListSchema(BaseSchema):
93
98
  return ", ".join(attrs_list)
94
99
 
95
100
  @classmethod
96
- def from_yaml(cls, namespace: str, yaml_data: Dict[str, Any], **kwargs) -> "ListSchema":
101
+ def from_yaml(
102
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
103
+ ) -> "ListSchema":
97
104
  # TODO: for items, if the type is a primitive is it listed in type instead of $ref?
98
105
  element_schema = yaml_data["elementType"]
99
106
 
100
107
  from . import build_schema # pylint: disable=import-outside-toplevel
101
108
 
102
- element_type = build_schema(yaml_data=element_schema, **kwargs)
109
+ element_type = build_schema(yaml_data=element_schema, code_model=code_model)
103
110
 
104
111
  return cls(
105
- namespace=namespace,
106
112
  yaml_data=yaml_data,
113
+ code_model=code_model,
107
114
  element_type=element_type,
108
115
  max_items=yaml_data.get("maxItems"),
109
116
  min_items=yaml_data.get("minItems"),
@@ -112,8 +119,13 @@ class ListSchema(BaseSchema):
112
119
 
113
120
  def imports(self) -> FileImport:
114
121
  file_import = FileImport()
115
- if not self.element_type.type_annotation(is_operation_file=True) == "ET.Element":
116
- file_import.add_submodule_import("typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL)
122
+ if (
123
+ not self.element_type.type_annotation(is_operation_file=True)
124
+ == "ET.Element"
125
+ ):
126
+ file_import.add_submodule_import(
127
+ "typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
128
+ )
117
129
  file_import.merge(self.element_type.imports())
118
130
  return file_import
119
131