@autorest/python 6.6.0 → 6.7.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.
- package/autorest/codegen/models/__init__.py +2 -0
- package/autorest/codegen/models/client.py +4 -7
- package/autorest/codegen/models/code_model.py +7 -9
- package/autorest/codegen/models/dictionary_type.py +4 -0
- package/autorest/codegen/models/list_type.py +4 -0
- package/autorest/codegen/models/lro_operation.py +12 -0
- package/autorest/codegen/models/model_type.py +4 -1
- package/autorest/codegen/models/operation.py +35 -9
- package/autorest/codegen/models/parameter.py +1 -7
- package/autorest/codegen/models/parameter_list.py +1 -1
- package/autorest/codegen/models/primitive_types.py +37 -9
- package/autorest/codegen/models/property.py +1 -0
- package/autorest/codegen/models/request_builder.py +0 -4
- package/autorest/codegen/serializers/__init__.py +1 -0
- package/autorest/codegen/serializers/builder_serializer.py +31 -42
- package/autorest/codegen/serializers/client_serializer.py +8 -2
- package/autorest/codegen/serializers/general_serializer.py +7 -4
- package/autorest/codegen/serializers/model_serializer.py +13 -2
- package/autorest/codegen/serializers/parameter_serializer.py +59 -4
- package/autorest/codegen/templates/model_base.py.jinja2 +246 -172
- package/autorest/codegen/templates/packaging_templates/setup.py.jinja2 +1 -1
- package/autorest/codegen/templates/request_builder.py.jinja2 +1 -1
- package/autorest/codegen/templates/serialization.py.jinja2 +22 -8
- package/autorest/codegen/templates/vendor.py.jinja2 +29 -15
- package/autorest/preprocess/__init__.py +63 -0
- package/package.json +2 -2
|
@@ -664,8 +664,9 @@ class Serializer(object):
|
|
|
664
664
|
_serialized.update(_new_attr) # type: ignore
|
|
665
665
|
_new_attr = _new_attr[k] # type: ignore
|
|
666
666
|
_serialized = _serialized[k]
|
|
667
|
-
except ValueError:
|
|
668
|
-
|
|
667
|
+
except ValueError as err:
|
|
668
|
+
if isinstance(err, SerializationError):
|
|
669
|
+
raise
|
|
669
670
|
|
|
670
671
|
except (AttributeError, KeyError, TypeError) as err:
|
|
671
672
|
msg = "Attribute {} in object {} cannot be serialized.\n{}".format(attr_name, class_name, str(target_obj))
|
|
@@ -743,6 +744,8 @@ class Serializer(object):
|
|
|
743
744
|
|
|
744
745
|
:param data: The data to be serialized.
|
|
745
746
|
:param str data_type: The type to be serialized from.
|
|
747
|
+
:keyword bool skip_quote: Whether to skip quote the serialized result.
|
|
748
|
+
Defaults to False.
|
|
746
749
|
:rtype: str
|
|
747
750
|
:raises: TypeError if serialization fails.
|
|
748
751
|
:raises: ValueError if data is None
|
|
@@ -751,10 +754,8 @@ class Serializer(object):
|
|
|
751
754
|
# Treat the list aside, since we don't want to encode the div separator
|
|
752
755
|
if data_type.startswith("["):
|
|
753
756
|
internal_data_type = data_type[1:-1]
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
data = [quote(str(d), safe="") for d in data]
|
|
757
|
-
return str(self.serialize_iter(data, internal_data_type, **kwargs))
|
|
757
|
+
do_quote = not kwargs.get('skip_quote', False)
|
|
758
|
+
return str(self.serialize_iter(data, internal_data_type, do_quote=do_quote, **kwargs))
|
|
758
759
|
|
|
759
760
|
# Not a list, regular serialization
|
|
760
761
|
output = self.serialize_data(data, data_type, **kwargs)
|
|
@@ -893,6 +894,8 @@ class Serializer(object):
|
|
|
893
894
|
not be None or empty.
|
|
894
895
|
:param str div: If set, this str will be used to combine the elements
|
|
895
896
|
in the iterable into a combined string. Default is 'None'.
|
|
897
|
+
:keyword bool do_quote: Whether to quote the serialized result of each iterable element.
|
|
898
|
+
Defaults to False.
|
|
896
899
|
:rtype: list, str
|
|
897
900
|
"""
|
|
898
901
|
if isinstance(data, str):
|
|
@@ -905,9 +908,18 @@ class Serializer(object):
|
|
|
905
908
|
for d in data:
|
|
906
909
|
try:
|
|
907
910
|
serialized.append(self.serialize_data(d, iter_type, **kwargs))
|
|
908
|
-
except ValueError:
|
|
911
|
+
except ValueError as err:
|
|
912
|
+
if isinstance(err, SerializationError):
|
|
913
|
+
raise
|
|
909
914
|
serialized.append(None)
|
|
910
915
|
|
|
916
|
+
if kwargs.get('do_quote', False):
|
|
917
|
+
serialized = [
|
|
918
|
+
'' if s is None else quote(str(s), safe='')
|
|
919
|
+
for s
|
|
920
|
+
in serialized
|
|
921
|
+
]
|
|
922
|
+
|
|
911
923
|
if div:
|
|
912
924
|
serialized = ["" if s is None else str(s) for s in serialized]
|
|
913
925
|
serialized = div.join(serialized)
|
|
@@ -952,7 +964,9 @@ class Serializer(object):
|
|
|
952
964
|
for key, value in attr.items():
|
|
953
965
|
try:
|
|
954
966
|
serialized[self.serialize_unicode(key)] = self.serialize_data(value, dict_type, **kwargs)
|
|
955
|
-
except ValueError:
|
|
967
|
+
except ValueError as err:
|
|
968
|
+
if isinstance(err, SerializationError):
|
|
969
|
+
raise
|
|
956
970
|
serialized[self.serialize_unicode(key)] = None
|
|
957
971
|
|
|
958
972
|
if "xml" in serialization_ctxt:
|
|
@@ -11,21 +11,6 @@ def _convert_request(request, files=None):
|
|
|
11
11
|
request.set_formdata_body(files)
|
|
12
12
|
return request
|
|
13
13
|
{% endif %}
|
|
14
|
-
{% if code_model.need_format_url and not async_mode %}
|
|
15
|
-
|
|
16
|
-
def _format_url_section(template, **kwargs):
|
|
17
|
-
components = template.split("/")
|
|
18
|
-
while components:
|
|
19
|
-
try:
|
|
20
|
-
return template.format(**kwargs)
|
|
21
|
-
except KeyError as key:
|
|
22
|
-
# Need the cast, as for some reasons "split" is typed as list[str | Any]
|
|
23
|
-
formatted_components = cast(List[str], template.split("/"))
|
|
24
|
-
components = [
|
|
25
|
-
c for c in formatted_components if "{{{}}}".format(key.args[0]) not in c
|
|
26
|
-
]
|
|
27
|
-
template = "/".join(components)
|
|
28
|
-
{% endif %}
|
|
29
14
|
{% if code_model.need_mixin_abc %}
|
|
30
15
|
{% for client in clients | selectattr("has_mixin") %}
|
|
31
16
|
|
|
@@ -47,3 +32,32 @@ def raise_if_not_implemented(cls, abstract_methods):
|
|
|
47
32
|
cls.__name__, '\', \''.join(not_implemented))
|
|
48
33
|
)
|
|
49
34
|
{% endif %}
|
|
35
|
+
|
|
36
|
+
{% if code_model.has_etag %}
|
|
37
|
+
def quote_etag(etag: Optional[str]) -> Optional[str]:
|
|
38
|
+
if not etag or etag == "*":
|
|
39
|
+
return etag
|
|
40
|
+
if etag.startswith('"') and etag.endswith('"'):
|
|
41
|
+
return etag
|
|
42
|
+
if etag.startswith("'") and etag.endswith("'"):
|
|
43
|
+
return etag
|
|
44
|
+
return '"' + etag + '"'
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def prep_if_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]:
|
|
48
|
+
if match_condition == MatchConditions.IfNotModified:
|
|
49
|
+
if_match = quote_etag(etag) if etag else None
|
|
50
|
+
return if_match
|
|
51
|
+
if match_condition == MatchConditions.IfPresent:
|
|
52
|
+
return "*"
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def prep_if_none_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]:
|
|
57
|
+
if match_condition == MatchConditions.IfModified:
|
|
58
|
+
if_none_match = quote_etag(etag) if etag else None
|
|
59
|
+
return if_none_match
|
|
60
|
+
if match_condition == MatchConditions.IfMissing:
|
|
61
|
+
return "*"
|
|
62
|
+
return None
|
|
63
|
+
{% endif %}
|
|
@@ -176,6 +176,37 @@ def update_paging_response(yaml_data: Dict[str, Any]) -> None:
|
|
|
176
176
|
)
|
|
177
177
|
|
|
178
178
|
|
|
179
|
+
HEADERS_HIDE_IN_METHOD = (
|
|
180
|
+
"repeatability-request-id",
|
|
181
|
+
"repeatability-first-sent",
|
|
182
|
+
"x-ms-client-request-id",
|
|
183
|
+
"client-request-id",
|
|
184
|
+
"return-client-request-id",
|
|
185
|
+
)
|
|
186
|
+
HEADERS_CONVERT_IN_METHOD = {
|
|
187
|
+
"if-match": {
|
|
188
|
+
"clientName": "etag",
|
|
189
|
+
"wireName": "etag",
|
|
190
|
+
"description": "check if resource is changed. Set None to skip checking etag.",
|
|
191
|
+
},
|
|
192
|
+
"if-none-match": {
|
|
193
|
+
"clientName": "match_condition",
|
|
194
|
+
"wireName": "match-condition",
|
|
195
|
+
"description": "The match condition to use upon the etag.",
|
|
196
|
+
"type": {
|
|
197
|
+
"type": "azurecore",
|
|
198
|
+
"name": "MatchConditions",
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def headers_convert(yaml_data: Dict[str, Any], replace_data: Any) -> None:
|
|
205
|
+
if isinstance(replace_data, dict):
|
|
206
|
+
for k, v in replace_data.items():
|
|
207
|
+
yaml_data[k] = v
|
|
208
|
+
|
|
209
|
+
|
|
179
210
|
class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
180
211
|
"""Add Python naming information."""
|
|
181
212
|
|
|
@@ -242,6 +273,11 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
242
273
|
)
|
|
243
274
|
type["values"].extend(values_to_add)
|
|
244
275
|
|
|
276
|
+
# add type for reference
|
|
277
|
+
for v in HEADERS_CONVERT_IN_METHOD.values():
|
|
278
|
+
if isinstance(v, dict) and "type" in v:
|
|
279
|
+
yaml_data.append(v["type"])
|
|
280
|
+
|
|
245
281
|
def update_client(self, yaml_data: Dict[str, Any]) -> None:
|
|
246
282
|
yaml_data["description"] = update_description(
|
|
247
283
|
yaml_data["description"], default_description=yaml_data["name"]
|
|
@@ -253,6 +289,21 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
253
289
|
if prop_name.endswith("Client"):
|
|
254
290
|
prop_name = prop_name[: len(prop_name) - len("Client")]
|
|
255
291
|
yaml_data["builderPadName"] = to_snake_case(prop_name)
|
|
292
|
+
for og in yaml_data["operationGroups"]:
|
|
293
|
+
for o in og["operations"]:
|
|
294
|
+
for p in o["parameters"]:
|
|
295
|
+
if (
|
|
296
|
+
p["location"] == "header"
|
|
297
|
+
and p["wireName"] == "client-request-id"
|
|
298
|
+
):
|
|
299
|
+
yaml_data["requestIdHeaderName"] = p["wireName"]
|
|
300
|
+
if (
|
|
301
|
+
self.version_tolerant
|
|
302
|
+
and p["location"] == "header"
|
|
303
|
+
and p["clientName"] in ("if_match", "if_none_match")
|
|
304
|
+
):
|
|
305
|
+
o["hasEtag"] = True
|
|
306
|
+
yaml_data["hasEtag"] = True
|
|
256
307
|
|
|
257
308
|
def get_operation_updater(
|
|
258
309
|
self, yaml_data: Dict[str, Any]
|
|
@@ -282,6 +333,18 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
282
333
|
.lower()
|
|
283
334
|
for prop, param_name in yaml_data["propertyToParameterName"].items()
|
|
284
335
|
}
|
|
336
|
+
wire_name_lower = (yaml_data.get("wireName") or "").lower()
|
|
337
|
+
if (
|
|
338
|
+
yaml_data["location"] == "header"
|
|
339
|
+
and wire_name_lower in HEADERS_HIDE_IN_METHOD
|
|
340
|
+
):
|
|
341
|
+
yaml_data["hideInMethod"] = True
|
|
342
|
+
if (
|
|
343
|
+
self.version_tolerant
|
|
344
|
+
and yaml_data["location"] == "header"
|
|
345
|
+
and wire_name_lower in HEADERS_CONVERT_IN_METHOD
|
|
346
|
+
):
|
|
347
|
+
headers_convert(yaml_data, HEADERS_CONVERT_IN_METHOD[wire_name_lower])
|
|
285
348
|
|
|
286
349
|
def update_operation(
|
|
287
350
|
self,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autorest/python",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.7.1",
|
|
4
4
|
"description": "The Python extension for generators in AutoRest.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@microsoft.azure/autorest.testserver": "^3.3.46",
|
|
26
|
-
"typescript": "
|
|
26
|
+
"typescript": "~5.1.3"
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"autorest/**/*.py",
|