@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.
- package/ChangeLog.md +67 -0
- package/autorest/__init__.py +1 -2
- package/autorest/black/__init__.py +12 -5
- package/autorest/codegen/__init__.py +239 -105
- package/autorest/codegen/models/__init__.py +29 -18
- package/autorest/codegen/models/base_builder.py +48 -11
- package/autorest/codegen/models/base_model.py +6 -4
- package/autorest/codegen/models/base_schema.py +21 -24
- package/autorest/codegen/models/client.py +70 -20
- package/autorest/codegen/models/code_model.py +144 -129
- package/autorest/codegen/models/constant_schema.py +32 -16
- package/autorest/codegen/models/credential_model.py +55 -0
- package/autorest/codegen/models/credential_schema.py +21 -16
- package/autorest/codegen/models/credential_schema_policy.py +11 -15
- package/autorest/codegen/models/dictionary_schema.py +27 -24
- package/autorest/codegen/models/enum_schema.py +41 -62
- package/autorest/codegen/models/imports.py +72 -41
- package/autorest/codegen/models/list_schema.py +40 -18
- package/autorest/codegen/models/lro_operation.py +61 -25
- package/autorest/codegen/models/lro_paging_operation.py +5 -6
- package/autorest/codegen/models/object_schema.py +113 -59
- package/autorest/codegen/models/operation.py +251 -111
- package/autorest/codegen/models/operation_group.py +67 -32
- package/autorest/codegen/models/paging_operation.py +48 -21
- package/autorest/codegen/models/parameter.py +182 -90
- package/autorest/codegen/models/parameter_list.py +184 -163
- package/autorest/codegen/models/primitive_schemas.py +89 -70
- package/autorest/codegen/models/property.py +49 -31
- package/autorest/codegen/models/request_builder.py +67 -32
- package/autorest/codegen/models/request_builder_parameter.py +54 -23
- package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
- package/autorest/codegen/models/schema_request.py +16 -6
- package/autorest/codegen/models/schema_response.py +35 -17
- package/autorest/codegen/models/utils.py +24 -1
- package/autorest/codegen/serializers/__init__.py +273 -89
- package/autorest/codegen/serializers/builder_serializer.py +711 -333
- package/autorest/codegen/serializers/client_serializer.py +114 -43
- package/autorest/codegen/serializers/general_serializer.py +84 -25
- package/autorest/codegen/serializers/import_serializer.py +93 -31
- package/autorest/codegen/serializers/metadata_serializer.py +73 -24
- package/autorest/codegen/serializers/model_base_serializer.py +42 -14
- package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
- package/autorest/codegen/serializers/model_init_serializer.py +5 -1
- package/autorest/codegen/serializers/model_python3_serializer.py +9 -8
- package/autorest/codegen/serializers/operation_groups_serializer.py +20 -8
- package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
- package/autorest/codegen/serializers/patch_serializer.py +14 -2
- package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
- package/autorest/codegen/serializers/utils.py +60 -21
- package/autorest/codegen/templates/CHANGELOG.md.jinja2 +6 -0
- package/autorest/codegen/templates/LICENSE.jinja2 +21 -0
- package/autorest/codegen/templates/MANIFEST.in.jinja2 +7 -0
- package/autorest/codegen/templates/README.md.jinja2 +105 -0
- package/autorest/codegen/templates/config.py.jinja2 +4 -4
- package/autorest/codegen/templates/dev_requirements.txt.jinja2 +10 -0
- package/autorest/codegen/templates/enum.py.jinja2 +1 -1
- package/autorest/codegen/templates/enum_container.py.jinja2 +0 -1
- package/autorest/codegen/templates/init.py.jinja2 +9 -6
- package/autorest/codegen/templates/keywords.jinja2 +14 -1
- package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
- package/autorest/codegen/templates/metadata.json.jinja2 +10 -9
- package/autorest/codegen/templates/model.py.jinja2 +1 -6
- package/autorest/codegen/templates/model_init.py.jinja2 +7 -4
- package/autorest/codegen/templates/operation.py.jinja2 +8 -11
- package/autorest/codegen/templates/operation_group.py.jinja2 +15 -18
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
- package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
- package/autorest/codegen/templates/patch.py.jinja2 +18 -29
- package/autorest/codegen/templates/request_builder.py.jinja2 +19 -14
- package/autorest/codegen/templates/setup.py.jinja2 +79 -20
- package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
- package/autorest/jsonrpc/__init__.py +7 -12
- package/autorest/jsonrpc/localapi.py +4 -3
- package/autorest/jsonrpc/server.py +13 -6
- package/autorest/jsonrpc/stdstream.py +13 -6
- package/autorest/m2r/__init__.py +5 -8
- package/autorest/multiapi/__init__.py +24 -14
- package/autorest/multiapi/models/client.py +21 -11
- package/autorest/multiapi/models/code_model.py +23 -10
- package/autorest/multiapi/models/config.py +4 -1
- package/autorest/multiapi/models/constant_global_parameter.py +1 -0
- package/autorest/multiapi/models/global_parameter.py +2 -1
- package/autorest/multiapi/models/global_parameters.py +14 -8
- package/autorest/multiapi/models/imports.py +35 -18
- package/autorest/multiapi/models/mixin_operation.py +5 -5
- package/autorest/multiapi/models/operation_group.py +2 -1
- package/autorest/multiapi/models/operation_mixin_group.py +21 -10
- package/autorest/multiapi/serializers/__init__.py +18 -23
- package/autorest/multiapi/serializers/import_serializer.py +47 -15
- package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
- package/autorest/multiapi/utils.py +3 -3
- package/autorest/namer/__init__.py +2 -4
- package/autorest/namer/name_converter.py +200 -103
- package/autorest/namer/python_mappings.py +10 -22
- package/package.json +3 -3
- package/run-python3.js +2 -3
- package/venvtools.py +1 -1
- package/autorest/codegen/models/rest.py +0 -42
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import logging
|
|
7
7
|
from enum import Enum
|
|
8
8
|
|
|
9
|
-
from typing import Dict, Optional, List, Any, Union, Tuple, cast
|
|
9
|
+
from typing import Dict, Optional, List, Any, Union, Tuple, cast, TYPE_CHECKING
|
|
10
10
|
|
|
11
11
|
from .imports import FileImport, ImportType, TypingSection
|
|
12
12
|
from .base_model import BaseModel
|
|
@@ -15,6 +15,10 @@ from .constant_schema import ConstantSchema
|
|
|
15
15
|
from .object_schema import ObjectSchema
|
|
16
16
|
from .property import Property
|
|
17
17
|
from .primitive_schemas import IOSchema
|
|
18
|
+
from .utils import get_schema
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from .code_model import CodeModel
|
|
18
22
|
|
|
19
23
|
|
|
20
24
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -22,6 +26,13 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
22
26
|
_HIDDEN_KWARGS = ["content_type"]
|
|
23
27
|
|
|
24
28
|
|
|
29
|
+
class ParameterMethodLocation(str, Enum):
|
|
30
|
+
POSITIONAL = "positional"
|
|
31
|
+
KEYWORD_ONLY = "keyword_only"
|
|
32
|
+
KWARG = "kwarg"
|
|
33
|
+
HIDDEN_KWARG = "hidden_kwarg"
|
|
34
|
+
|
|
35
|
+
|
|
25
36
|
class ParameterLocation(Enum):
|
|
26
37
|
Path = "path"
|
|
27
38
|
Body = "body"
|
|
@@ -46,11 +57,21 @@ class ParameterStyle(Enum):
|
|
|
46
57
|
multipart = "multipart"
|
|
47
58
|
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
def get_target_property_name(code_model: "CodeModel", target_property_id: int) -> str:
|
|
61
|
+
for obj in code_model.schemas.values():
|
|
62
|
+
for prop in obj.properties:
|
|
63
|
+
if prop.id == target_property_id:
|
|
64
|
+
return prop.name
|
|
65
|
+
raise KeyError("Didn't find the target property")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Parameter(
|
|
69
|
+
BaseModel
|
|
70
|
+
): # pylint: disable=too-many-instance-attributes, too-many-public-methods
|
|
50
71
|
def __init__(
|
|
51
72
|
self,
|
|
52
|
-
code_model,
|
|
53
73
|
yaml_data: Dict[str, Any],
|
|
74
|
+
code_model: "CodeModel",
|
|
54
75
|
schema: BaseSchema,
|
|
55
76
|
rest_api_name: str,
|
|
56
77
|
serialized_name: str,
|
|
@@ -60,7 +81,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
60
81
|
location: ParameterLocation,
|
|
61
82
|
skip_url_encoding: bool,
|
|
62
83
|
constraints: List[Any],
|
|
63
|
-
target_property_name: Optional[
|
|
84
|
+
target_property_name: Optional[
|
|
85
|
+
Union[int, str]
|
|
86
|
+
] = None, # first uses id as placeholder
|
|
64
87
|
style: Optional[ParameterStyle] = None,
|
|
65
88
|
explode: Optional[bool] = False,
|
|
66
89
|
*,
|
|
@@ -68,10 +91,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
68
91
|
grouped_by: Optional["Parameter"] = None,
|
|
69
92
|
original_parameter: Optional["Parameter"] = None,
|
|
70
93
|
client_default_value: Optional[Any] = None,
|
|
71
|
-
keyword_only: Optional[bool] = None,
|
|
72
94
|
content_types: Optional[List[str]] = None,
|
|
73
95
|
) -> None:
|
|
74
|
-
super().__init__(yaml_data)
|
|
96
|
+
super().__init__(yaml_data, code_model)
|
|
75
97
|
self.code_model = code_model
|
|
76
98
|
self.schema = schema
|
|
77
99
|
self.rest_api_name = rest_api_name
|
|
@@ -92,14 +114,17 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
92
114
|
self.has_multiple_content_types: bool = False
|
|
93
115
|
self.multiple_content_types_type_annot: Optional[str] = None
|
|
94
116
|
self.multiple_content_types_docstring_type: Optional[str] = None
|
|
95
|
-
self.
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
self.is_multipart = (
|
|
118
|
+
yaml_data.get("language", {}).get("python", {}).get("multipart", False)
|
|
119
|
+
)
|
|
120
|
+
self.is_data_input = (
|
|
121
|
+
yaml_data.get("isPartialBody", False) and not self.is_multipart
|
|
122
|
+
)
|
|
98
123
|
self.content_types = content_types or []
|
|
99
124
|
self.body_kwargs: List[Parameter] = []
|
|
100
125
|
self.is_body_kwarg = False
|
|
101
126
|
self.need_import = True
|
|
102
|
-
self.
|
|
127
|
+
self._method_location: Optional[ParameterMethodLocation] = None
|
|
103
128
|
|
|
104
129
|
def __hash__(self) -> int:
|
|
105
130
|
return hash(self.serialized_name)
|
|
@@ -115,9 +140,11 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
115
140
|
if isinstance(self.schema, ConstantSchema) and not self.constant:
|
|
116
141
|
if description:
|
|
117
142
|
description += " "
|
|
118
|
-
description += f"
|
|
143
|
+
description += f"Known values are {self.schema.get_declaration(self.schema.value)} or {None}."
|
|
119
144
|
if self.has_default_value and not any(
|
|
120
|
-
l
|
|
145
|
+
l
|
|
146
|
+
for l in ["default value is", "default is"]
|
|
147
|
+
if l in description.lower()
|
|
121
148
|
):
|
|
122
149
|
description += f" Default value is {self.default_value_declaration}."
|
|
123
150
|
if self.constant:
|
|
@@ -160,12 +187,12 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
160
187
|
return self.schema.get_declaration(self.schema.value)
|
|
161
188
|
raise ValueError(
|
|
162
189
|
"Trying to get constant declaration for a schema that is not ConstantSchema"
|
|
163
|
-
|
|
190
|
+
)
|
|
164
191
|
raise ValueError("Trying to get a declaration for a schema that doesn't exist")
|
|
165
192
|
|
|
166
193
|
@property
|
|
167
194
|
def serialization_formats(self) -> List[str]:
|
|
168
|
-
return self.yaml_data.get(
|
|
195
|
+
return self.yaml_data.get("serializationFormats", [])
|
|
169
196
|
|
|
170
197
|
@property
|
|
171
198
|
def xml_serialization_ctxt(self) -> str:
|
|
@@ -175,6 +202,10 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
175
202
|
def is_body(self) -> bool:
|
|
176
203
|
return self.location == ParameterLocation.Body
|
|
177
204
|
|
|
205
|
+
@property
|
|
206
|
+
def inputtable_by_user(self) -> bool:
|
|
207
|
+
return self.rest_api_name != "Accept"
|
|
208
|
+
|
|
178
209
|
@property
|
|
179
210
|
def pre_semicolon_content_types(self) -> List[str]:
|
|
180
211
|
"""Splits on semicolon of media types and returns the first half.
|
|
@@ -184,9 +215,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
184
215
|
|
|
185
216
|
@property
|
|
186
217
|
def in_method_signature(self) -> bool:
|
|
187
|
-
return not(
|
|
188
|
-
# don't put
|
|
189
|
-
self.
|
|
218
|
+
return not (
|
|
219
|
+
# if not inputtable, don't put in signature
|
|
220
|
+
not self.inputtable_by_user
|
|
190
221
|
# If i'm not in the method code, no point in being in signature
|
|
191
222
|
or not self.in_method_code
|
|
192
223
|
# If I'm grouped, my grouper will be on signature, not me
|
|
@@ -201,15 +232,20 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
201
232
|
raise ValueError("Should only be calling if your parameter is grouped")
|
|
202
233
|
try:
|
|
203
234
|
return next(
|
|
204
|
-
p
|
|
205
|
-
|
|
235
|
+
p
|
|
236
|
+
for p in cast(ObjectSchema, self.grouped_by.schema).properties
|
|
237
|
+
if any(
|
|
238
|
+
op for op in p.yaml_data["originalParameter"] if id(op) == self.id
|
|
239
|
+
)
|
|
206
240
|
)
|
|
207
241
|
except StopIteration:
|
|
208
|
-
raise ValueError(
|
|
242
|
+
raise ValueError(
|
|
243
|
+
"There is not a corresponding grouped property for your parameter."
|
|
244
|
+
)
|
|
209
245
|
|
|
210
246
|
@property
|
|
211
247
|
def in_method_code(self) -> bool:
|
|
212
|
-
return self.rest_api_name !=
|
|
248
|
+
return self.rest_api_name != "$host"
|
|
213
249
|
|
|
214
250
|
@property
|
|
215
251
|
def implementation(self) -> str:
|
|
@@ -225,15 +261,21 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
225
261
|
) and isinstance(self.schema, IOSchema)
|
|
226
262
|
|
|
227
263
|
def _default_value(self) -> Tuple[Optional[Any], str, str]:
|
|
228
|
-
type_annot =
|
|
264
|
+
type_annot = (
|
|
265
|
+
self.multiple_content_types_type_annot
|
|
266
|
+
or self.schema.type_annotation(is_operation_file=True)
|
|
267
|
+
)
|
|
229
268
|
if self._is_io_json:
|
|
230
|
-
type_annot = f"Union[{type_annot},
|
|
231
|
-
|
|
232
|
-
if not self.required and type_annot not in any_types and not self._is_io_json:
|
|
269
|
+
type_annot = f"Union[{type_annot}, Any]"
|
|
270
|
+
if not self.required and type_annot != "Any" and not self._is_io_json:
|
|
233
271
|
type_annot = f"Optional[{type_annot}]"
|
|
234
272
|
|
|
235
273
|
if self.client_default_value is not None:
|
|
236
|
-
return
|
|
274
|
+
return (
|
|
275
|
+
self.client_default_value,
|
|
276
|
+
self.schema.get_declaration(self.client_default_value),
|
|
277
|
+
type_annot,
|
|
278
|
+
)
|
|
237
279
|
|
|
238
280
|
if self.multiple_content_types_type_annot:
|
|
239
281
|
# means this parameter has multiple media types. We force default value to be None.
|
|
@@ -241,9 +283,11 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
241
283
|
default_value_declaration = "None"
|
|
242
284
|
else:
|
|
243
285
|
if isinstance(self.schema, ConstantSchema):
|
|
244
|
-
if (
|
|
245
|
-
self.
|
|
246
|
-
|
|
286
|
+
if (
|
|
287
|
+
self.required
|
|
288
|
+
or self.is_content_type
|
|
289
|
+
or not self.code_model.options["default_optional_constants_to_none"]
|
|
290
|
+
):
|
|
247
291
|
default_value = self.schema.get_declaration(self.schema.value)
|
|
248
292
|
else:
|
|
249
293
|
default_value = None
|
|
@@ -254,18 +298,36 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
254
298
|
if default_value is not None and self.required:
|
|
255
299
|
_LOGGER.warning(
|
|
256
300
|
"Parameter '%s' is required and has a default value, this combination is not recommended",
|
|
257
|
-
self.rest_api_name
|
|
301
|
+
self.rest_api_name,
|
|
258
302
|
)
|
|
259
303
|
|
|
260
304
|
return default_value, default_value_declaration, type_annot
|
|
261
305
|
|
|
262
306
|
@property
|
|
263
307
|
def description_keyword(self) -> str:
|
|
264
|
-
return
|
|
308
|
+
return (
|
|
309
|
+
"keyword"
|
|
310
|
+
if self.method_location
|
|
311
|
+
in (
|
|
312
|
+
ParameterMethodLocation.KWARG,
|
|
313
|
+
ParameterMethodLocation.HIDDEN_KWARG,
|
|
314
|
+
ParameterMethodLocation.KEYWORD_ONLY,
|
|
315
|
+
)
|
|
316
|
+
else "param"
|
|
317
|
+
)
|
|
265
318
|
|
|
266
319
|
@property
|
|
267
320
|
def docstring_type_keyword(self) -> str:
|
|
268
|
-
return
|
|
321
|
+
return (
|
|
322
|
+
"paramtype"
|
|
323
|
+
if self.method_location
|
|
324
|
+
in (
|
|
325
|
+
ParameterMethodLocation.KWARG,
|
|
326
|
+
ParameterMethodLocation.HIDDEN_KWARG,
|
|
327
|
+
ParameterMethodLocation.KEYWORD_ONLY,
|
|
328
|
+
)
|
|
329
|
+
else "type"
|
|
330
|
+
)
|
|
269
331
|
|
|
270
332
|
@property
|
|
271
333
|
def default_value(self) -> Optional[Any]:
|
|
@@ -277,8 +339,9 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
277
339
|
def default_value_declaration(self) -> Optional[Any]:
|
|
278
340
|
return self._default_value()[1]
|
|
279
341
|
|
|
280
|
-
|
|
281
|
-
|
|
342
|
+
def type_annotation(
|
|
343
|
+
self, *, is_operation_file: bool = False # pylint: disable=unused-argument
|
|
344
|
+
) -> str:
|
|
282
345
|
return self._default_value()[2]
|
|
283
346
|
|
|
284
347
|
@property
|
|
@@ -287,9 +350,11 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
287
350
|
|
|
288
351
|
@property
|
|
289
352
|
def docstring_type(self) -> str:
|
|
290
|
-
retval =
|
|
353
|
+
retval = (
|
|
354
|
+
self.multiple_content_types_docstring_type or self.schema.docstring_type
|
|
355
|
+
)
|
|
291
356
|
if self._is_io_json:
|
|
292
|
-
retval += " or
|
|
357
|
+
retval += " or Any"
|
|
293
358
|
return retval
|
|
294
359
|
|
|
295
360
|
@property
|
|
@@ -297,13 +362,14 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
297
362
|
return self.default_value is not None or not self.required
|
|
298
363
|
|
|
299
364
|
def method_signature(self, is_python3_file: bool) -> str:
|
|
365
|
+
type_annot = self.type_annotation(is_operation_file=True)
|
|
300
366
|
if is_python3_file:
|
|
301
367
|
if self.has_default_value:
|
|
302
|
-
return f"{self.serialized_name}: {
|
|
303
|
-
return f"{self.serialized_name}: {
|
|
368
|
+
return f"{self.serialized_name}: {type_annot} = {self.default_value_declaration},"
|
|
369
|
+
return f"{self.serialized_name}: {type_annot},"
|
|
304
370
|
if self.has_default_value:
|
|
305
|
-
return f"{self.serialized_name}={self.default_value_declaration}, # type: {
|
|
306
|
-
return f"{self.serialized_name}, # type: {
|
|
371
|
+
return f"{self.serialized_name}={self.default_value_declaration}, # type: {type_annot}"
|
|
372
|
+
return f"{self.serialized_name}, # type: {type_annot}"
|
|
307
373
|
|
|
308
374
|
@property
|
|
309
375
|
def full_serialized_name(self) -> str:
|
|
@@ -312,91 +378,117 @@ class Parameter(BaseModel): # pylint: disable=too-many-instance-attributes, too
|
|
|
312
378
|
origin_name = f"self._config.{self.serialized_name}"
|
|
313
379
|
return origin_name
|
|
314
380
|
|
|
315
|
-
@property
|
|
316
|
-
def is_keyword_only(self) -> bool:
|
|
317
|
-
# this means in async mode, I am documented like def hello(positional_1, *, me!)
|
|
318
|
-
return self._keyword_only or False
|
|
319
|
-
|
|
320
|
-
@is_keyword_only.setter
|
|
321
|
-
def is_keyword_only(self, val: bool) -> None:
|
|
322
|
-
self._keyword_only = val
|
|
323
|
-
self.is_kwarg = False
|
|
324
|
-
|
|
325
|
-
@property
|
|
326
|
-
def is_hidden(self) -> bool:
|
|
327
|
-
return self.serialized_name in _HIDDEN_KWARGS and self.is_kwarg or (
|
|
328
|
-
self.yaml_data["implementation"] == "Client" and self.constant
|
|
329
|
-
)
|
|
330
|
-
|
|
331
381
|
@property
|
|
332
382
|
def is_content_type(self) -> bool:
|
|
333
|
-
return
|
|
383
|
+
return (
|
|
384
|
+
self.rest_api_name == "Content-Type"
|
|
385
|
+
and self.location == ParameterLocation.Header
|
|
386
|
+
)
|
|
334
387
|
|
|
335
388
|
@property
|
|
336
|
-
def
|
|
337
|
-
|
|
389
|
+
def method_location(self) -> ParameterMethodLocation:
|
|
390
|
+
if self._method_location:
|
|
391
|
+
return self._method_location
|
|
392
|
+
if self.serialized_name in _HIDDEN_KWARGS or (
|
|
393
|
+
self._implementation == "Client" and self.constant
|
|
394
|
+
):
|
|
395
|
+
return ParameterMethodLocation.HIDDEN_KWARG
|
|
396
|
+
if self.constant and self.inputtable_by_user:
|
|
397
|
+
return ParameterMethodLocation.KWARG
|
|
398
|
+
return ParameterMethodLocation.POSITIONAL
|
|
399
|
+
|
|
400
|
+
@method_location.setter
|
|
401
|
+
def method_location(self, val: ParameterMethodLocation) -> None:
|
|
402
|
+
self._method_location = val
|
|
338
403
|
|
|
339
404
|
@classmethod
|
|
340
405
|
def from_yaml(
|
|
341
406
|
cls,
|
|
342
407
|
yaml_data: Dict[str, Any],
|
|
408
|
+
code_model: "CodeModel",
|
|
343
409
|
*,
|
|
344
|
-
|
|
345
|
-
content_types: Optional[List[str]] = None
|
|
410
|
+
content_types: Optional[List[str]] = None,
|
|
346
411
|
) -> "Parameter":
|
|
347
|
-
http_protocol = yaml_data["protocol"].get(
|
|
412
|
+
http_protocol = yaml_data["protocol"].get(
|
|
413
|
+
"http", {"in": ParameterLocation.Other}
|
|
414
|
+
)
|
|
415
|
+
serialized_name = yaml_data["language"]["python"]["name"]
|
|
416
|
+
schema = get_schema(code_model, yaml_data.get("schema"), serialized_name)
|
|
417
|
+
target_property = yaml_data.get("targetProperty")
|
|
418
|
+
target_property_name = (
|
|
419
|
+
get_target_property_name(code_model, id(target_property))
|
|
420
|
+
if target_property
|
|
421
|
+
else None
|
|
422
|
+
)
|
|
423
|
+
|
|
348
424
|
return cls(
|
|
349
|
-
code_model=code_model,
|
|
350
425
|
yaml_data=yaml_data,
|
|
351
|
-
|
|
426
|
+
code_model=code_model,
|
|
427
|
+
schema=schema, # FIXME replace by operation model
|
|
352
428
|
# See also https://github.com/Azure/autorest.modelerfour/issues/80
|
|
353
429
|
rest_api_name=yaml_data["language"]["default"].get(
|
|
354
430
|
"serializedName", yaml_data["language"]["default"]["name"]
|
|
355
431
|
),
|
|
356
|
-
serialized_name=
|
|
432
|
+
serialized_name=serialized_name,
|
|
357
433
|
description=yaml_data["language"]["python"]["description"],
|
|
358
434
|
implementation=yaml_data["implementation"],
|
|
359
435
|
required=yaml_data.get("required", False),
|
|
360
436
|
location=ParameterLocation(http_protocol["in"]),
|
|
361
|
-
skip_url_encoding=yaml_data.get("extensions", {}).get(
|
|
437
|
+
skip_url_encoding=yaml_data.get("extensions", {}).get(
|
|
438
|
+
"x-ms-skip-url-encoding", False
|
|
439
|
+
),
|
|
362
440
|
constraints=[], # FIXME constraints
|
|
363
|
-
target_property_name=
|
|
364
|
-
style=ParameterStyle(http_protocol["style"])
|
|
441
|
+
target_property_name=target_property_name,
|
|
442
|
+
style=ParameterStyle(http_protocol["style"])
|
|
443
|
+
if "style" in http_protocol
|
|
444
|
+
else None,
|
|
365
445
|
explode=http_protocol.get("explode", False),
|
|
366
446
|
grouped_by=yaml_data.get("groupedBy", None),
|
|
367
447
|
original_parameter=yaml_data.get("originalParameter", None),
|
|
368
448
|
flattened=yaml_data.get("flattened", False),
|
|
369
449
|
client_default_value=yaml_data.get("clientDefaultValue"),
|
|
370
|
-
content_types=content_types
|
|
450
|
+
content_types=content_types,
|
|
371
451
|
)
|
|
372
452
|
|
|
373
453
|
def imports(self) -> FileImport:
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
454
|
+
if self.need_import:
|
|
455
|
+
file_import = self.schema.imports()
|
|
456
|
+
if not self.required:
|
|
457
|
+
file_import.add_submodule_import(
|
|
458
|
+
"typing", "Optional", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
459
|
+
)
|
|
460
|
+
if self.has_multiple_content_types or self._is_io_json:
|
|
461
|
+
file_import.add_submodule_import(
|
|
462
|
+
"typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL
|
|
463
|
+
)
|
|
379
464
|
|
|
380
|
-
|
|
465
|
+
return file_import
|
|
466
|
+
return FileImport()
|
|
381
467
|
|
|
382
|
-
class ParameterOnlyPathAndBodyPositional(Parameter):
|
|
383
468
|
|
|
469
|
+
class ParameterOnlyPathAndBodyPositional(Parameter):
|
|
384
470
|
@property
|
|
385
|
-
def
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
self.
|
|
394
|
-
|
|
471
|
+
def method_location(self) -> ParameterMethodLocation:
|
|
472
|
+
super_method_location = super().method_location
|
|
473
|
+
if super_method_location in (
|
|
474
|
+
ParameterMethodLocation.KWARG,
|
|
475
|
+
ParameterMethodLocation.HIDDEN_KWARG,
|
|
476
|
+
):
|
|
477
|
+
return super_method_location
|
|
478
|
+
if self._method_location:
|
|
479
|
+
return self._method_location
|
|
480
|
+
if self.location not in (
|
|
481
|
+
ParameterLocation.Path,
|
|
482
|
+
ParameterLocation.Uri,
|
|
483
|
+
ParameterLocation.Body,
|
|
484
|
+
):
|
|
485
|
+
return ParameterMethodLocation.KEYWORD_ONLY
|
|
486
|
+
return super_method_location
|
|
487
|
+
|
|
488
|
+
@method_location.setter
|
|
489
|
+
def method_location(self, val: ParameterMethodLocation) -> None:
|
|
490
|
+
self._method_location = val
|
|
395
491
|
|
|
396
|
-
@is_keyword_only.setter
|
|
397
|
-
def is_keyword_only(self, val: bool) -> None:
|
|
398
|
-
self._keyword_only = val
|
|
399
|
-
self.is_kwarg = False
|
|
400
492
|
|
|
401
493
|
def get_parameter(code_model):
|
|
402
494
|
if code_model.options["only_path_and_body_params_positional"]:
|