@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
@@ -24,13 +24,22 @@ from ..models import (
24
24
  from .builder_serializer import get_operation_serializer
25
25
 
26
26
 
27
- def _correct_credential_parameter(global_parameters: ParameterList, async_mode: bool) -> None:
28
- credential_param = [gp for gp in global_parameters.parameters if isinstance(gp.schema, TokenCredentialSchema)][0]
27
+ def _correct_credential_parameter(
28
+ global_parameters: ParameterList, async_mode: bool
29
+ ) -> None:
30
+ credential_param = [
31
+ gp
32
+ for gp in global_parameters.parameters
33
+ if isinstance(gp.schema, TokenCredentialSchema)
34
+ ][0]
29
35
  credential_param.schema = TokenCredentialSchema(async_mode=async_mode)
30
36
 
31
37
 
32
38
  def _json_serialize_imports(
33
- imports: Dict[TypingSection, Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]]]
39
+ imports: Dict[
40
+ TypingSection,
41
+ Dict[ImportType, Dict[str, Set[Optional[Union[str, Tuple[str, str]]]]]],
42
+ ]
34
43
  ):
35
44
  if not imports:
36
45
  return None
@@ -55,14 +64,18 @@ def _json_serialize_imports(
55
64
  return json.dumps(json_serialize_imports)
56
65
 
57
66
 
58
- def _mixin_imports(mixin_operation_group: Optional[OperationGroup]) -> Tuple[Optional[str], Optional[str]]:
67
+ def _mixin_imports(
68
+ mixin_operation_group: Optional[OperationGroup],
69
+ ) -> Tuple[Optional[str], Optional[str]]:
59
70
  if not mixin_operation_group:
60
71
  return None, None
61
72
 
62
73
  sync_mixin_imports = mixin_operation_group.imports_for_multiapi(async_mode=False)
63
74
  async_mixin_imports = mixin_operation_group.imports_for_multiapi(async_mode=True)
64
75
 
65
- return _json_serialize_imports(sync_mixin_imports.to_dict()), _json_serialize_imports(async_mixin_imports.to_dict())
76
+ return _json_serialize_imports(
77
+ sync_mixin_imports.to_dict()
78
+ ), _json_serialize_imports(async_mixin_imports.to_dict())
66
79
 
67
80
 
68
81
  class MetadataSerializer:
@@ -80,7 +93,9 @@ class MetadataSerializer:
80
93
  total_api_version_list.sort()
81
94
 
82
95
  # switching ' to " so json can decode the dict we end up writing to file
83
- total_api_version_list = [str(api_version).replace("'", '"') for api_version in total_api_version_list]
96
+ total_api_version_list = [
97
+ str(api_version).replace("'", '"') for api_version in total_api_version_list
98
+ ]
84
99
  if len(total_api_version_list) == 1:
85
100
  chosen_version = total_api_version_list[0]
86
101
  elif len(total_api_version_list) > 1:
@@ -97,26 +112,43 @@ class MetadataSerializer:
97
112
  return global_parameters
98
113
 
99
114
  def _service_client_imports(
100
- self, global_parameters: ParameterList, mixin_operation_group: Optional[OperationGroup], async_mode: bool
115
+ self,
116
+ global_parameters: ParameterList,
117
+ mixin_operation_group: Optional[OperationGroup],
118
+ async_mode: bool,
101
119
  ) -> str:
102
120
  file_import = FileImport()
103
121
  for gp in global_parameters:
104
122
  file_import.merge(gp.imports())
105
- file_import.add_submodule_import("azure.profiles", "KnownProfiles", import_type=ImportType.AZURECORE)
106
- file_import.add_submodule_import("azure.profiles", "ProfileDefinition", import_type=ImportType.AZURECORE)
107
123
  file_import.add_submodule_import(
108
- "azure.profiles.multiapiclient", "MultiApiClientMixin", import_type=ImportType.AZURECORE
124
+ "azure.profiles", "KnownProfiles", import_type=ImportType.AZURECORE
109
125
  )
110
126
  file_import.add_submodule_import(
111
- "._configuration", f"{self.code_model.class_name}Configuration", ImportType.LOCAL
127
+ "azure.profiles", "ProfileDefinition", import_type=ImportType.AZURECORE
128
+ )
129
+ file_import.add_submodule_import(
130
+ "azure.profiles.multiapiclient",
131
+ "MultiApiClientMixin",
132
+ import_type=ImportType.AZURECORE,
133
+ )
134
+ file_import.add_submodule_import(
135
+ "._configuration",
136
+ f"{self.code_model.class_name}Configuration",
137
+ ImportType.LOCAL,
112
138
  )
113
139
  # api_version and potentially endpoint require Optional typing
114
- file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL)
140
+ file_import.add_submodule_import(
141
+ "typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
142
+ )
115
143
  if mixin_operation_group:
116
144
  file_import.add_submodule_import(
117
- "._operations_mixin", f"{self.code_model.class_name}OperationsMixin", ImportType.LOCAL
145
+ "._operations_mixin",
146
+ f"{self.code_model.class_name}OperationsMixin",
147
+ ImportType.LOCAL,
118
148
  )
119
- file_import.merge(self.code_model.service_client.imports_for_multiapi(async_mode=async_mode))
149
+ file_import.merge(
150
+ self.code_model.service_client.imports_for_multiapi(async_mode=async_mode)
151
+ )
120
152
  return _json_serialize_imports(file_import.to_dict())
121
153
 
122
154
  def serialize(self) -> str:
@@ -134,7 +166,9 @@ class MetadataSerializer:
134
166
  ),
135
167
  None,
136
168
  )
137
- mixin_operations = mixin_operation_group.operations if mixin_operation_group else []
169
+ mixin_operations = (
170
+ mixin_operation_group.operations if mixin_operation_group else []
171
+ )
138
172
  sync_mixin_imports, async_mixin_imports = _mixin_imports(mixin_operation_group)
139
173
 
140
174
  chosen_version, total_api_version_list = self._choose_api_version()
@@ -143,9 +177,9 @@ class MetadataSerializer:
143
177
  # In this case, we need two copies of the credential global parameter
144
178
  # for typing purposes.
145
179
  async_global_parameters = self.code_model.global_parameters
146
- if (
147
- self.code_model.options['credential'] and
148
- isinstance(self.code_model.credential_schema_policy.credential, TokenCredentialSchema)
180
+ if self.code_model.options["credential"] and isinstance(
181
+ self.code_model.credential_model.credential_schema_policy.credential,
182
+ TokenCredentialSchema,
149
183
  ):
150
184
  # this ensures that the TokenCredentialSchema showing up in the list of code model's global parameters
151
185
  # is sync. This way we only have to make a copy for an async_credential
@@ -163,8 +197,13 @@ class MetadataSerializer:
163
197
 
164
198
  # setting to true, because for multiapi we always generate with a version file with version 0.1.0
165
199
  self.code_model.options["package_version"] = "0.1.0"
166
- if self.code_model.options["azure_arm"] and not self.code_model.service_client.parameters.host:
167
- self.code_model.service_client.parameters.add_host("https://management.azure.com")
200
+ if (
201
+ self.code_model.options["azure_arm"]
202
+ and not self.code_model.service_client.parameters.host
203
+ ):
204
+ self.code_model.service_client.parameters.add_host(
205
+ "https://management.azure.com"
206
+ )
168
207
  return template.render(
169
208
  chosen_version=chosen_version,
170
209
  total_api_version_list=total_api_version_list,
@@ -181,15 +220,25 @@ class MetadataSerializer:
181
220
  sync_client_imports=sync_client_imports,
182
221
  async_client_imports=async_client_imports,
183
222
  sync_config_imports=_json_serialize_imports(
184
- config_imports(self.code_model, self.code_model.global_parameters, async_mode=False).to_dict()
223
+ config_imports(
224
+ self.code_model, self.code_model.global_parameters, async_mode=False
225
+ ).to_dict()
185
226
  ),
186
227
  async_config_imports=_json_serialize_imports(
187
- config_imports(self.code_model, async_global_parameters, async_mode=True).to_dict()
228
+ config_imports(
229
+ self.code_model, async_global_parameters, async_mode=True
230
+ ).to_dict()
188
231
  ),
189
232
  get_async_operation_serializer=functools.partial(
190
- get_operation_serializer, code_model=self.code_model, async_mode=True, is_python3_file=True
233
+ get_operation_serializer,
234
+ code_model=self.code_model,
235
+ async_mode=True,
236
+ is_python3_file=True,
191
237
  ),
192
238
  get_sync_operation_serializer=functools.partial(
193
- get_operation_serializer, code_model=self.code_model, async_mode=False, is_python3_file=False
239
+ get_operation_serializer,
240
+ code_model=self.code_model,
241
+ async_mode=False,
242
+ is_python3_file=False,
194
243
  ),
195
244
  )
@@ -10,21 +10,25 @@ from ..models import ObjectSchema, CodeModel, Property
10
10
  from ..models.imports import FileImport, ImportType
11
11
  from .import_serializer import FileImportSerializer
12
12
 
13
+
13
14
  def _documentation_string(
14
15
  prop: Property, description_keyword: str, docstring_type_keyword: str
15
16
  ) -> List[str]:
16
17
  retval: List[str] = []
17
18
  sphinx_prefix = f":{description_keyword} {prop.name}:"
18
19
  retval.append(
19
- f"{sphinx_prefix} {prop.description}" if prop.description
20
- else sphinx_prefix
20
+ f"{sphinx_prefix} {prop.description}" if prop.description else sphinx_prefix
21
+ )
22
+ retval.append(
23
+ f":{docstring_type_keyword} {prop.name}: {prop.schema.docstring_type}"
21
24
  )
22
- retval.append(f":{docstring_type_keyword} {prop.name}: {prop.schema.docstring_type}")
23
25
  return retval
24
26
 
25
27
 
26
28
  class ModelBaseSerializer:
27
- def __init__(self, code_model: CodeModel, env: Environment, is_python3_file: bool) -> None:
29
+ def __init__(
30
+ self, code_model: CodeModel, env: Environment, is_python3_file: bool
31
+ ) -> None:
28
32
  self.code_model = code_model
29
33
  self.env = env
30
34
  self.is_python3_file = is_python3_file
@@ -34,12 +38,15 @@ class ModelBaseSerializer:
34
38
  template = self.env.get_template("model_container.py.jinja2")
35
39
  return template.render(
36
40
  code_model=self.code_model,
37
- imports=FileImportSerializer(self.imports(), is_python3_file=self.is_python3_file),
41
+ imports=FileImportSerializer(
42
+ self.imports(), is_python3_file=self.is_python3_file
43
+ ),
38
44
  str=str,
39
45
  init_line=self.init_line,
40
46
  init_args=self.init_args,
41
47
  input_documentation_string=ModelBaseSerializer.input_documentation_string,
42
48
  variable_documentation_string=ModelBaseSerializer.variable_documentation_string,
49
+ declare_model=ModelBaseSerializer.declare_model,
43
50
  )
44
51
 
45
52
  def imports(self) -> FileImport:
@@ -52,16 +59,29 @@ class ModelBaseSerializer:
52
59
  @staticmethod
53
60
  def get_properties_to_initialize(model: ObjectSchema) -> List[Property]:
54
61
  if model.base_models:
55
- properties_to_initialize = list({
56
- p.name: p
57
- for bm in model.base_models
58
- for p in model.properties
59
- if p not in cast(ObjectSchema, bm).properties or p.is_discriminator or p.constant
60
- }.values())
62
+ properties_to_initialize = list(
63
+ {
64
+ p.name: p
65
+ for bm in model.base_models
66
+ for p in model.properties
67
+ if p not in cast(ObjectSchema, bm).properties
68
+ or p.is_discriminator
69
+ or p.constant
70
+ }.values()
71
+ )
61
72
  else:
62
73
  properties_to_initialize = model.properties
63
74
  return properties_to_initialize
64
75
 
76
+ @staticmethod
77
+ def declare_model(model: ObjectSchema) -> str:
78
+ basename = "msrest.serialization.Model"
79
+ if model.base_models:
80
+ basename = ", ".join(
81
+ [cast(ObjectSchema, m).name for m in model.base_models]
82
+ )
83
+ return f"class {model.name}({basename}):"
84
+
65
85
  @staticmethod
66
86
  def input_documentation_string(prop: Property) -> List[str]:
67
87
  # building the param line of the property doc
@@ -74,15 +94,23 @@ class ModelBaseSerializer:
74
94
  def init_args(self, model: ObjectSchema) -> List[str]:
75
95
  init_args = []
76
96
  properties_to_pass_to_super = self.properties_to_pass_to_super(model)
77
- init_args.append(f"super({model.name}, self).__init__({properties_to_pass_to_super})")
97
+ init_args.append(
98
+ f"super({model.name}, self).__init__({properties_to_pass_to_super})"
99
+ )
78
100
  for prop in ModelBaseSerializer.get_properties_to_initialize(model):
79
101
  if prop.is_discriminator:
80
- discriminator_value = f"'{model.discriminator_value}'" if model.discriminator_value else None
102
+ discriminator_value = (
103
+ f"'{model.discriminator_value}'"
104
+ if model.discriminator_value
105
+ else None
106
+ )
81
107
  if not discriminator_value:
82
108
  typing = "Optional[str]"
83
109
  else:
84
110
  typing = "str"
85
- init_args.append(f"self.{prop.name} = {discriminator_value} # type: {typing}")
111
+ init_args.append(
112
+ f"self.{prop.name} = {discriminator_value} # type: {typing}"
113
+ )
86
114
  elif prop.readonly:
87
115
  init_args.append(f"self.{prop.name} = None")
88
116
  elif not prop.constant:
@@ -10,11 +10,8 @@ from ..models import ObjectSchema, CodeModel, Property
10
10
 
11
11
 
12
12
  class ModelGenericSerializer(ModelBaseSerializer):
13
-
14
13
  def __init__(self, code_model: CodeModel, env: Environment) -> None:
15
- super(ModelGenericSerializer, self).__init__(
16
- code_model=code_model, env=env, is_python3_file=False
17
- )
14
+ super().__init__(code_model=code_model, env=env, is_python3_file=False)
18
15
 
19
16
  def init_line(self, model: ObjectSchema) -> List[str]:
20
17
  return []
@@ -15,7 +15,11 @@ class ModelInitSerializer:
15
15
  def serialize(self) -> str:
16
16
  schemas = [s.name for s in self.code_model.sorted_schemas]
17
17
  schemas.sort()
18
- enums = [e.name for e in self.code_model.enums.values()] if self.code_model.enums else None
18
+ enums = (
19
+ [e.name for e in self.code_model.enums.values()]
20
+ if self.code_model.enums
21
+ else None
22
+ )
19
23
 
20
24
  if enums:
21
25
  enums.sort()
@@ -11,16 +11,15 @@ from ..models.imports import FileImport
11
11
 
12
12
 
13
13
  class ModelPython3Serializer(ModelBaseSerializer):
14
-
15
14
  def __init__(self, code_model: CodeModel, env: Environment) -> None:
16
- super(ModelPython3Serializer, self).__init__(
17
- code_model=code_model, env=env, is_python3_file=True
18
- )
15
+ super().__init__(code_model=code_model, env=env, is_python3_file=True)
19
16
 
20
17
  def init_line(self, model: ObjectSchema) -> List[str]:
21
18
  init_properties_declaration = []
22
19
  init_line_parameters = [
23
- p for p in model.properties if not p.readonly and not p.is_discriminator and not p.constant
20
+ p
21
+ for p in model.properties
22
+ if not p.readonly and not p.is_discriminator and not p.constant
24
23
  ]
25
24
  init_line_parameters.sort(key=lambda x: x.required, reverse=True)
26
25
  if init_line_parameters:
@@ -46,11 +45,11 @@ class ModelPython3Serializer(ModelBaseSerializer):
46
45
  return ", ".join(properties_to_pass_to_super)
47
46
 
48
47
  def required_property_no_default_init(self, prop: Property) -> str:
49
- return f"{prop.name}: {prop.type_annotation}"
48
+ return f"{prop.name}: {prop.type_annotation()}"
50
49
 
51
50
  def optional_property_init(self, prop: Property) -> str:
52
51
  default = prop.default_value_declaration
53
- return f"{prop.name}: {prop.type_annotation} = {default}"
52
+ return f"{prop.name}: {prop.type_annotation()} = {default}"
54
53
 
55
54
  def initialize_standard_arg(self, prop: Property) -> str:
56
55
  return f"self.{prop.name} = {prop.name}"
@@ -58,7 +57,9 @@ class ModelPython3Serializer(ModelBaseSerializer):
58
57
  def imports(self) -> FileImport:
59
58
  file_import = super(ModelPython3Serializer, self).imports()
60
59
  for model in self.code_model.sorted_schemas:
61
- init_line_parameters = [p for p in model.properties if not p.readonly and not p.is_discriminator]
60
+ init_line_parameters = [
61
+ p for p in model.properties if not p.readonly and not p.is_discriminator
62
+ ]
62
63
  for param in init_line_parameters:
63
64
  file_import.merge(param.model_file_imports())
64
65
 
@@ -12,11 +12,12 @@ from ..models import (
12
12
  OperationGroup,
13
13
  FileImport,
14
14
  LROOperation,
15
- PagingOperation
15
+ PagingOperation,
16
16
  )
17
17
  from .import_serializer import FileImportSerializer
18
18
  from .builder_serializer import get_operation_serializer, get_request_builder_serializer
19
19
 
20
+
20
21
  class OperationGroupsSerializer:
21
22
  def __init__(
22
23
  self,
@@ -38,21 +39,31 @@ class OperationGroupsSerializer:
38
39
 
39
40
  def _is_paging(operation):
40
41
  return isinstance(operation, PagingOperation)
41
- operation_groups = [self.operation_group] if self.operation_group else self.code_model.operation_groups
42
+
43
+ operation_groups = (
44
+ [self.operation_group]
45
+ if self.operation_group
46
+ else self.code_model.operation_groups
47
+ )
42
48
  imports = FileImport()
43
49
  for operation_group in operation_groups:
44
- imports.merge(operation_group.imports(
45
- async_mode=self.async_mode,
46
- ))
50
+ imports.merge(
51
+ operation_group.imports(
52
+ async_mode=self.async_mode,
53
+ is_python3_file=self.is_python3_file,
54
+ )
55
+ )
47
56
 
48
- template = self.env.get_or_select_template("operation_groups_container.py.jinja2")
57
+ template = self.env.get_or_select_template(
58
+ "operation_groups_container.py.jinja2"
59
+ )
49
60
  return template.render(
50
61
  code_model=self.code_model,
51
62
  operation_groups=operation_groups,
52
63
  imports=FileImportSerializer(
53
64
  imports,
54
65
  is_python3_file=self.is_python3_file,
55
- async_mode=self.async_mode
66
+ async_mode=self.async_mode,
56
67
  ),
57
68
  async_mode=self.async_mode,
58
69
  is_python3_file=self.is_python3_file,
@@ -65,6 +76,7 @@ class OperationGroupsSerializer:
65
76
  is_python3_file=self.is_python3_file,
66
77
  ),
67
78
  request_builder_serializer=get_request_builder_serializer(
68
- self.code_model, self.is_python3_file,
79
+ self.code_model,
80
+ self.is_python3_file,
69
81
  ),
70
82
  )
@@ -11,15 +11,22 @@ from ..models import CodeModel
11
11
 
12
12
 
13
13
  class OperationsInitSerializer:
14
- def __init__(self, code_model: CodeModel, env: Environment, async_mode: bool) -> None:
14
+ def __init__(
15
+ self, code_model: CodeModel, env: Environment, async_mode: bool
16
+ ) -> None:
15
17
  self.code_model = code_model
16
18
  self.env = env
17
19
  self.async_mode = async_mode
18
20
 
19
21
  def _operation_group_imports_helper(self, filename_suffix: str = "") -> List[str]:
20
22
  def _get_filename(operation_group: OperationGroup) -> str:
21
- prefix = "_operations" if self.code_model.options["combine_operation_files"] else operation_group.filename
23
+ prefix = (
24
+ "_operations"
25
+ if self.code_model.options["combine_operation_files"]
26
+ else operation_group.filename
27
+ )
22
28
  return prefix + filename_suffix
29
+
23
30
  return [
24
31
  f"from .{_get_filename(og)} import {og.class_name}"
25
32
  for og in self.code_model.operation_groups
@@ -30,20 +37,25 @@ class OperationsInitSerializer:
30
37
  py3_only = self.code_model.options["python3_only"]
31
38
  if typed_py3_files and not py3_only and not self.async_mode:
32
39
  retval: List[str] = ["try:"]
33
- retval.extend([
34
- f" {line}"
35
- for line in self._operation_group_imports_helper(filename_suffix="_py3")
36
- ])
40
+ retval.extend(
41
+ [
42
+ f" {line}"
43
+ for line in self._operation_group_imports_helper(
44
+ filename_suffix="_py3"
45
+ )
46
+ ]
47
+ )
37
48
  retval.append("except (SyntaxError, ImportError):")
38
- retval.extend([
39
- f" {line}"
40
- for line in self._operation_group_imports_helper()
41
- ])
49
+ retval.extend(
50
+ [f" {line}" for line in self._operation_group_imports_helper()]
51
+ )
42
52
  return retval
43
53
  return self._operation_group_imports_helper()
44
54
 
45
55
  def serialize(self) -> str:
46
- operation_group_init_template = self.env.get_template("operations_folder_init.py.jinja2")
56
+ operation_group_init_template = self.env.get_template(
57
+ "operations_folder_init.py.jinja2"
58
+ )
47
59
 
48
60
  return operation_group_init_template.render(
49
61
  code_model=self.code_model,
@@ -4,12 +4,24 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from jinja2 import Environment
7
+ from .import_serializer import FileImportSerializer
8
+ from ..models import CodeModel, FileImport, ImportType, TypingSection
7
9
 
8
10
 
9
11
  class PatchSerializer:
10
- def __init__(self, env: Environment) -> None:
12
+ def __init__(self, env: Environment, code_model: CodeModel) -> None:
11
13
  self.env = env
14
+ self.code_model = code_model
12
15
 
13
16
  def serialize(self) -> str:
14
17
  template = self.env.get_template("patch.py.jinja2")
15
- return template.render()
18
+ imports = FileImport()
19
+ imports.add_submodule_import(
20
+ "typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
21
+ )
22
+ is_python3_file = self.code_model.options["python3_only"]
23
+ return template.render(
24
+ code_model=self.code_model,
25
+ imports=FileImportSerializer(imports, is_python3_file=is_python3_file),
26
+ is_python3_file=is_python3_file,
27
+ )
@@ -6,7 +6,7 @@
6
6
  from typing import List
7
7
  from jinja2 import Environment
8
8
 
9
- from ..models import RequestBuilder
9
+ from ..models import RequestBuilder, FileImport
10
10
  from .import_serializer import FileImportSerializer
11
11
  from ..models import CodeModel
12
12
  from .builder_serializer import (
@@ -15,43 +15,60 @@ from .builder_serializer import (
15
15
  )
16
16
 
17
17
 
18
- class RestSerializer:
19
- def __init__(self, code_model: CodeModel, env: Environment, request_builders: List[RequestBuilder]) -> None:
18
+ class RequestBuildersSerializer:
19
+ def __init__(
20
+ self,
21
+ code_model: CodeModel,
22
+ env: Environment,
23
+ request_builders: List[RequestBuilder],
24
+ ) -> None:
20
25
  self.code_model = code_model
21
26
  self.env = env
22
27
  self.request_builders = request_builders
23
28
  self.builder_group_name = request_builders[0].builder_group_name
24
29
 
30
+ @property
31
+ def imports(self) -> FileImport:
32
+ file_import = FileImport()
33
+ for request_builder in self.request_builders:
34
+ if request_builder.builder_group_name == self.builder_group_name:
35
+ file_import.merge(request_builder.imports())
36
+ return file_import
37
+
25
38
  def serialize_init(self) -> str:
26
39
  template = self.env.get_template("rest_init.py.jinja2")
27
- return template.render(code_model=self.code_model, request_builders=self.request_builders)
40
+ return template.render(
41
+ code_model=self.code_model, request_builders=self.request_builders
42
+ )
28
43
 
29
44
 
30
- class RestPython3Serializer(RestSerializer):
45
+ class RequestBuildersPython3Serializer(RequestBuildersSerializer):
31
46
  def serialize_request_builders(self) -> str:
32
47
  template = self.env.get_template("request_builders.py.jinja2")
33
48
 
34
49
  return template.render(
35
50
  code_model=self.code_model,
36
51
  request_builders=self.request_builders,
37
- imports=FileImportSerializer(self.code_model.rest.imports(
38
- self.builder_group_name
39
- ), is_python3_file=True),
52
+ imports=FileImportSerializer(
53
+ self.imports,
54
+ is_python3_file=True,
55
+ ),
40
56
  is_python3_file=True,
41
57
  request_builder_serializer=RequestBuilderPython3Serializer(self.code_model),
42
58
  )
43
59
 
44
60
 
45
- class RestGenericSerializer(RestSerializer):
61
+ class RequestBuildersGenericSerializer(RequestBuildersSerializer):
46
62
  def serialize_request_builders(self) -> str:
47
63
  template = self.env.get_template("request_builders.py.jinja2")
48
64
 
49
65
  return template.render(
50
66
  code_model=self.code_model,
51
67
  request_builders=self.request_builders,
52
- imports=FileImportSerializer(self.code_model.rest.imports(
53
- self.builder_group_name
54
- ), is_python3_file=False),
68
+ imports=FileImportSerializer(
69
+ self.imports,
70
+ is_python3_file=False,
71
+ ),
55
72
  is_python3_file=False,
56
73
  request_builder_serializer=RequestBuilderGenericSerializer(self.code_model),
57
74
  )