@autorest/python 6.7.7 → 6.8.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/autorest/codegen/__init__.py +12 -5
- package/autorest/codegen/_utils.py +4 -0
- package/autorest/codegen/models/dictionary_type.py +2 -2
- package/autorest/codegen/models/list_type.py +2 -2
- package/autorest/codegen/models/parameter.py +13 -0
- package/autorest/codegen/models/parameter_list.py +5 -14
- package/autorest/codegen/models/primitive_types.py +7 -7
- package/autorest/codegen/models/request_builder_parameter.py +4 -0
- package/autorest/codegen/serializers/__init__.py +2 -1
- package/autorest/codegen/serializers/builder_serializer.py +21 -6
- package/autorest/codegen/serializers/model_serializer.py +2 -2
- package/autorest/codegen/templates/model_base.py.jinja2 +6 -7
- package/autorest/m4reformatter/__init__.py +2 -2
- package/autorest/preprocess/__init__.py +0 -15
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ from .. import Plugin, PluginAutorest
|
|
|
13
13
|
from .._utils import parse_args
|
|
14
14
|
from .models.code_model import CodeModel
|
|
15
15
|
from .serializers import JinjaSerializer, JinjaSerializerAutorest
|
|
16
|
-
from ._utils import DEFAULT_HEADER_TEXT
|
|
16
|
+
from ._utils import DEFAULT_HEADER_TEXT, VALID_PACKAGE_MODE, TYPESPEC_PACKAGE_MODE
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def _default_pprint(package_name: str) -> str:
|
|
@@ -55,11 +55,17 @@ def _validate_code_model_options(options: Dict[str, Any]) -> None:
|
|
|
55
55
|
|
|
56
56
|
if options["package_mode"]:
|
|
57
57
|
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
(
|
|
59
|
+
options["package_mode"] not in TYPESPEC_PACKAGE_MODE
|
|
60
|
+
and options["from_typespec"]
|
|
61
|
+
)
|
|
62
|
+
or (
|
|
63
|
+
options["package_mode"] not in VALID_PACKAGE_MODE
|
|
64
|
+
and not options["from_typespec"]
|
|
65
|
+
)
|
|
66
|
+
) and not Path(options["package_mode"]).exists():
|
|
61
67
|
raise ValueError(
|
|
62
|
-
"--package-mode can only be '
|
|
68
|
+
f"--package-mode can only be {' or '.join(TYPESPEC_PACKAGE_MODE)} or directory which contains template files" # pylint: disable=line-too-long
|
|
63
69
|
)
|
|
64
70
|
|
|
65
71
|
if options["multiapi"] and options["version_tolerant"]:
|
|
@@ -170,6 +176,7 @@ class CodeGenerator(Plugin):
|
|
|
170
176
|
),
|
|
171
177
|
"generate_sample": self.options.get("generate-sample", False),
|
|
172
178
|
"default_api_version": self.options.get("default-api-version"),
|
|
179
|
+
"from_typespec": self.options.get("from-typespec", False),
|
|
173
180
|
}
|
|
174
181
|
|
|
175
182
|
if options["builders_visibility"] is None:
|
|
@@ -10,3 +10,7 @@ DEFAULT_HEADER_TEXT = (
|
|
|
10
10
|
"Code generated by Microsoft (R) Python Code Generator.\n"
|
|
11
11
|
"Changes may cause incorrect behavior and will be lost if the code is regenerated."
|
|
12
12
|
)
|
|
13
|
+
|
|
14
|
+
SWAGGER_PACKAGE_MODE = ["mgmtplane", "dataplane"] # for backward compatibility
|
|
15
|
+
TYPESPEC_PACKAGE_MODE = ["azure-mgmt", "azure-dataplane", "generic"]
|
|
16
|
+
VALID_PACKAGE_MODE = SWAGGER_PACKAGE_MODE + TYPESPEC_PACKAGE_MODE
|
|
@@ -31,8 +31,8 @@ class DictionaryType(BaseType):
|
|
|
31
31
|
self.element_type = element_type
|
|
32
32
|
|
|
33
33
|
@property
|
|
34
|
-
def
|
|
35
|
-
return self.element_type.
|
|
34
|
+
def encode(self) -> Optional[str]:
|
|
35
|
+
return self.element_type.encode if hasattr(self.element_type, "encode") else None # type: ignore
|
|
36
36
|
|
|
37
37
|
@property
|
|
38
38
|
def serialization_type(self) -> str:
|
|
@@ -26,8 +26,8 @@ class ListType(BaseType):
|
|
|
26
26
|
self.unique_items: bool = yaml_data.get("uniqueItems", False)
|
|
27
27
|
|
|
28
28
|
@property
|
|
29
|
-
def
|
|
30
|
-
return self.element_type.
|
|
29
|
+
def encode(self) -> Optional[str]:
|
|
30
|
+
return self.element_type.encode if hasattr(self.element_type, "encode") else None # type: ignore
|
|
31
31
|
|
|
32
32
|
@property
|
|
33
33
|
def serialization_type(self) -> str:
|
|
@@ -92,6 +92,10 @@ class _ParameterBase(
|
|
|
92
92
|
)
|
|
93
93
|
self.hide_in_method: bool = self.yaml_data.get("hideInMethod", False)
|
|
94
94
|
|
|
95
|
+
@property
|
|
96
|
+
def hide_in_operation_signature(self) -> bool:
|
|
97
|
+
return False
|
|
98
|
+
|
|
95
99
|
@property
|
|
96
100
|
def constant(self) -> bool:
|
|
97
101
|
"""Returns whether a parameter is a constant or not.
|
|
@@ -341,6 +345,15 @@ class Parameter(_ParameterBase):
|
|
|
341
345
|
self.delimiter: Optional[ParameterDelimeter] = self.yaml_data.get("delimiter")
|
|
342
346
|
self._default_to_unset_sentinel: bool = False
|
|
343
347
|
|
|
348
|
+
@property
|
|
349
|
+
def hide_in_operation_signature(self) -> bool:
|
|
350
|
+
if (
|
|
351
|
+
self.code_model.options["version_tolerant"]
|
|
352
|
+
and self.client_name == "maxpagesize"
|
|
353
|
+
):
|
|
354
|
+
return True
|
|
355
|
+
return False
|
|
356
|
+
|
|
344
357
|
@property
|
|
345
358
|
def in_method_signature(self) -> bool:
|
|
346
359
|
return not (self.wire_name == "Accept" or self.grouped_by or self.flattened)
|
|
@@ -248,11 +248,12 @@ class _ParameterListBase(
|
|
|
248
248
|
|
|
249
249
|
def method_signature_keyword_only(self, async_mode: bool) -> List[str]:
|
|
250
250
|
"""Signature for keyword only parameters"""
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
251
|
+
result = [
|
|
252
|
+
parameter.method_signature(async_mode)
|
|
253
|
+
for parameter in self.keyword_only
|
|
254
|
+
if not parameter.hide_in_operation_signature
|
|
255
255
|
]
|
|
256
|
+
return ["*,"] + result if result else []
|
|
256
257
|
|
|
257
258
|
@property
|
|
258
259
|
def method_signature_kwargs(self) -> List[str]:
|
|
@@ -409,16 +410,6 @@ class RequestBuilderParameterList(_RequestBuilderParameterList):
|
|
|
409
410
|
class OverloadedRequestBuilderParameterList(_RequestBuilderParameterList):
|
|
410
411
|
"""Parameter list for OverloadedRequestBuilder"""
|
|
411
412
|
|
|
412
|
-
def method_signature_keyword_only(self, async_mode: bool) -> List[str]:
|
|
413
|
-
"""Signature for keyword only parameters"""
|
|
414
|
-
if not self.keyword_only:
|
|
415
|
-
return []
|
|
416
|
-
return ["*,"] + [
|
|
417
|
-
parameter.method_signature(async_mode)
|
|
418
|
-
for parameter in self.keyword_only
|
|
419
|
-
if parameter.location != ParameterLocation.BODY
|
|
420
|
-
]
|
|
421
|
-
|
|
422
413
|
|
|
423
414
|
class _ClientGlobalParameterList( # pylint: disable=abstract-method
|
|
424
415
|
_ParameterListBase[ParameterType, BodyParameter]
|
|
@@ -355,10 +355,10 @@ class StringType(PrimitiveType):
|
|
|
355
355
|
class DatetimeType(PrimitiveType):
|
|
356
356
|
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
357
357
|
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
358
|
-
self.
|
|
358
|
+
self.encode = (
|
|
359
359
|
"rfc3339"
|
|
360
|
-
if yaml_data.get("
|
|
361
|
-
or yaml_data.get("
|
|
360
|
+
if yaml_data.get("encode", "date-time") == "date-time"
|
|
361
|
+
or yaml_data.get("encode", "date-time") == "rfc3339"
|
|
362
362
|
else "rfc7231"
|
|
363
363
|
)
|
|
364
364
|
|
|
@@ -368,7 +368,7 @@ class DatetimeType(PrimitiveType):
|
|
|
368
368
|
"rfc3339": "iso-8601",
|
|
369
369
|
"rfc7231": "rfc-1123",
|
|
370
370
|
}
|
|
371
|
-
return formats_to_attribute_type[self.
|
|
371
|
+
return formats_to_attribute_type[self.encode]
|
|
372
372
|
|
|
373
373
|
def docstring_type(self, **kwargs: Any) -> str:
|
|
374
374
|
return "~" + self.type_annotation()
|
|
@@ -455,7 +455,7 @@ class TimeType(PrimitiveType):
|
|
|
455
455
|
|
|
456
456
|
class UnixTimeType(PrimitiveType):
|
|
457
457
|
@property
|
|
458
|
-
def
|
|
458
|
+
def encode(self) -> str:
|
|
459
459
|
return "unix-timestamp"
|
|
460
460
|
|
|
461
461
|
@property
|
|
@@ -592,11 +592,11 @@ class DurationType(PrimitiveType):
|
|
|
592
592
|
class ByteArraySchema(PrimitiveType):
|
|
593
593
|
def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
|
|
594
594
|
super().__init__(yaml_data=yaml_data, code_model=code_model)
|
|
595
|
-
self.
|
|
595
|
+
self.encode = yaml_data.get("encode", "base64")
|
|
596
596
|
|
|
597
597
|
@property
|
|
598
598
|
def serialization_type(self) -> str:
|
|
599
|
-
if self.
|
|
599
|
+
if self.encode == "base64url":
|
|
600
600
|
return "base64"
|
|
601
601
|
return "bytearray"
|
|
602
602
|
|
|
@@ -110,6 +110,10 @@ class RequestBuilderParameter(Parameter):
|
|
|
110
110
|
# we don't want hidden parameters for grouped by in request builders
|
|
111
111
|
self.client_name = self.client_name[1:]
|
|
112
112
|
|
|
113
|
+
@property
|
|
114
|
+
def hide_in_operation_signature(self) -> bool:
|
|
115
|
+
return False
|
|
116
|
+
|
|
113
117
|
@property
|
|
114
118
|
def in_method_signature(self) -> bool:
|
|
115
119
|
if self.grouped_by and not self.in_flattened_body:
|
|
@@ -29,6 +29,7 @@ from .patch_serializer import PatchSerializer
|
|
|
29
29
|
from .sample_serializer import SampleSerializer
|
|
30
30
|
from .types_serializer import TypesSerializer
|
|
31
31
|
from ..._utils import to_snake_case
|
|
32
|
+
from .._utils import VALID_PACKAGE_MODE
|
|
32
33
|
from .utils import (
|
|
33
34
|
extract_sample_name,
|
|
34
35
|
get_namespace_from_package_name,
|
|
@@ -216,7 +217,7 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
|
|
|
216
217
|
|
|
217
218
|
def _serialize_and_write_package_files(self, namespace_path: Path) -> None:
|
|
218
219
|
root_of_sdk = self._package_root_folder(namespace_path)
|
|
219
|
-
if self.code_model.options["package_mode"] in
|
|
220
|
+
if self.code_model.options["package_mode"] in VALID_PACKAGE_MODE:
|
|
220
221
|
env = Environment(
|
|
221
222
|
loader=PackageLoader(
|
|
222
223
|
"autorest.codegen", "templates/packaging_templates"
|
|
@@ -32,6 +32,7 @@ from ..models import (
|
|
|
32
32
|
RequestBuilderType,
|
|
33
33
|
CombinedType,
|
|
34
34
|
ParameterListType,
|
|
35
|
+
ByteArraySchema,
|
|
35
36
|
)
|
|
36
37
|
from .parameter_serializer import ParameterSerializer, PopKwargType
|
|
37
38
|
from ..models.parameter_list import ParameterType
|
|
@@ -332,7 +333,7 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
|
|
|
332
333
|
def param_description(self, builder: BuilderType) -> List[str]:
|
|
333
334
|
description_list: List[str] = []
|
|
334
335
|
for param in builder.parameters.method:
|
|
335
|
-
if not param.in_docstring:
|
|
336
|
+
if not param.in_docstring or param.hide_in_operation_signature:
|
|
336
337
|
continue
|
|
337
338
|
description_list.extend(
|
|
338
339
|
f":{param.description_keyword} {param.client_name}: {param.description}".replace(
|
|
@@ -700,6 +701,9 @@ class _OperationSerializer(
|
|
|
700
701
|
check_client_input=not self.code_model.options["multiapi"],
|
|
701
702
|
operation_name=f"('{builder.name}')" if builder.group_name == "" else "",
|
|
702
703
|
)
|
|
704
|
+
for p in builder.parameters.parameters:
|
|
705
|
+
if p.hide_in_operation_signature:
|
|
706
|
+
kwargs.append(f'{p.client_name} = kwargs.pop("{p.client_name}", None)')
|
|
703
707
|
cls_annotation = builder.cls_type_annotation(async_mode=self.async_mode)
|
|
704
708
|
pylint_disable = ""
|
|
705
709
|
if any(x.startswith("_") for x in cls_annotation.split(".")):
|
|
@@ -749,10 +753,17 @@ class _OperationSerializer(
|
|
|
749
753
|
f"'{body_param.type.serialization_type}'{is_xml_cmd}{serialization_ctxt_cmd})"
|
|
750
754
|
)
|
|
751
755
|
elif self.code_model.options["models_mode"] == "dpg":
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
+
if hasattr(body_param.type, "encode") and body_param.type.encode: # type: ignore
|
|
757
|
+
create_body_call = (
|
|
758
|
+
f"_{body_kwarg_name} = json.dumps({body_param.client_name}, "
|
|
759
|
+
"cls=AzureJSONEncoder, exclude_readonly=True, "
|
|
760
|
+
f"format='{body_param.type.encode}') # type: ignore" # type: ignore
|
|
761
|
+
)
|
|
762
|
+
else:
|
|
763
|
+
create_body_call = (
|
|
764
|
+
f"_{body_kwarg_name} = json.dumps({body_param.client_name}, "
|
|
765
|
+
"cls=AzureJSONEncoder, exclude_readonly=True) # type: ignore"
|
|
766
|
+
)
|
|
756
767
|
else:
|
|
757
768
|
create_body_call = f"_{body_kwarg_name} = {body_param.client_name}"
|
|
758
769
|
if body_param.optional:
|
|
@@ -774,7 +785,11 @@ class _OperationSerializer(
|
|
|
774
785
|
if hasattr(body_param, "entries"):
|
|
775
786
|
return _serialize_multipart_body(builder)
|
|
776
787
|
body_kwarg_name = builder.request_builder.parameters.body_parameter.client_name
|
|
777
|
-
|
|
788
|
+
body_param_type = body_param.type
|
|
789
|
+
if isinstance(body_param_type, BinaryType) or (
|
|
790
|
+
isinstance(body_param.type, ByteArraySchema)
|
|
791
|
+
and body_param.default_content_type != "application/json"
|
|
792
|
+
):
|
|
778
793
|
retval.append(f"_{body_kwarg_name} = {body_param.client_name}")
|
|
779
794
|
if (
|
|
780
795
|
not body_param.default_content_type
|
|
@@ -260,8 +260,8 @@ class DpgModelSerializer(_ModelSerializer):
|
|
|
260
260
|
args.append(f"visibility=[{v_list}]")
|
|
261
261
|
if prop.client_default_value is not None:
|
|
262
262
|
args.append(f"default={prop.client_default_value_declaration}")
|
|
263
|
-
if hasattr(prop.type, "
|
|
264
|
-
args.append(f'format="{prop.type.
|
|
263
|
+
if hasattr(prop.type, "encode") and prop.type.encode: # type: ignore
|
|
264
|
+
args.append(f'format="{prop.type.encode}"') # type: ignore
|
|
265
265
|
|
|
266
266
|
field = "rest_discriminator" if prop.is_discriminator else "rest_field"
|
|
267
267
|
type_ignore = (
|
|
@@ -128,9 +128,10 @@ def _is_readonly(p):
|
|
|
128
128
|
class AzureJSONEncoder(JSONEncoder):
|
|
129
129
|
"""A JSON encoder that's capable of serializing datetime objects and bytes."""
|
|
130
130
|
|
|
131
|
-
def __init__(self, *args, exclude_readonly: bool = False, **kwargs):
|
|
131
|
+
def __init__(self, *args, exclude_readonly: bool = False, format: typing.Optional[str] = None, **kwargs):
|
|
132
132
|
super().__init__(*args, **kwargs)
|
|
133
133
|
self.exclude_readonly = exclude_readonly
|
|
134
|
+
self.format = format
|
|
134
135
|
|
|
135
136
|
def default(self, o): # pylint: disable=too-many-return-statements
|
|
136
137
|
if _is_model(o):
|
|
@@ -138,18 +139,16 @@ class AzureJSONEncoder(JSONEncoder):
|
|
|
138
139
|
readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)]
|
|
139
140
|
return {k: v for k, v in o.items() if k not in readonly_props}
|
|
140
141
|
return dict(o.items())
|
|
141
|
-
if isinstance(o, (bytes, bytearray)):
|
|
142
|
-
return base64.b64encode(o).decode()
|
|
143
|
-
if isinstance(o, _Null):
|
|
144
|
-
return None
|
|
145
142
|
try:
|
|
146
143
|
return super(AzureJSONEncoder, self).default(o)
|
|
147
144
|
except TypeError:
|
|
145
|
+
if isinstance(o, _Null):
|
|
146
|
+
return None
|
|
148
147
|
if isinstance(o, (bytes, bytearray)):
|
|
149
|
-
return _serialize_bytes(o)
|
|
148
|
+
return _serialize_bytes(o, self.format)
|
|
150
149
|
try:
|
|
151
150
|
# First try datetime.datetime
|
|
152
|
-
return _serialize_datetime(o)
|
|
151
|
+
return _serialize_datetime(o, self.format)
|
|
153
152
|
except AttributeError:
|
|
154
153
|
pass
|
|
155
154
|
# Last, try datetime.timedelta
|
|
@@ -232,11 +232,11 @@ def update_primitive( # pylint: disable=too-many-return-statements
|
|
|
232
232
|
return KNOWN_TYPES["binary"]
|
|
233
233
|
if type_group == "date-time":
|
|
234
234
|
base = _update_type_base("datetime", yaml_data)
|
|
235
|
-
base["
|
|
235
|
+
base["encode"] = yaml_data["format"]
|
|
236
236
|
return base
|
|
237
237
|
if type_group == "byte-array":
|
|
238
238
|
base = _update_type_base("bytes", yaml_data)
|
|
239
|
-
base["
|
|
239
|
+
base["encode"] = yaml_data["format"]
|
|
240
240
|
return base
|
|
241
241
|
return _update_type_base(type_group, yaml_data)
|
|
242
242
|
|
|
@@ -137,16 +137,6 @@ def add_overloads_for_body_param(yaml_data: Dict[str, Any]) -> None:
|
|
|
137
137
|
content_type_param["optional"] = True
|
|
138
138
|
|
|
139
139
|
|
|
140
|
-
def _remove_paging_maxpagesize(yaml_data: Dict[str, Any]) -> None:
|
|
141
|
-
# we don't expose maxpagesize for version tolerant generation
|
|
142
|
-
# users should be passing this into `by_page`
|
|
143
|
-
yaml_data["parameters"] = [
|
|
144
|
-
p
|
|
145
|
-
for p in yaml_data.get("parameters", [])
|
|
146
|
-
if p["wireName"].lower() not in ["maxpagesize", "$maxpagesize"]
|
|
147
|
-
]
|
|
148
|
-
|
|
149
|
-
|
|
150
140
|
def update_description(
|
|
151
141
|
description: Optional[str], default_description: str = ""
|
|
152
142
|
) -> str:
|
|
@@ -494,13 +484,8 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
494
484
|
yaml_data["pagerSync"] = "azure.core.paging.ItemPaged"
|
|
495
485
|
if not yaml_data.get("pagerAsync"):
|
|
496
486
|
yaml_data["pagerAsync"] = "azure.core.async_paging.AsyncItemPaged"
|
|
497
|
-
if self.version_tolerant:
|
|
498
|
-
# if we're in version tolerant, hide the paging model
|
|
499
|
-
_remove_paging_maxpagesize(yaml_data)
|
|
500
487
|
item_type = item_type or yaml_data["itemType"]["elementType"]
|
|
501
488
|
if yaml_data.get("nextOperation"):
|
|
502
|
-
if self.version_tolerant:
|
|
503
|
-
_remove_paging_maxpagesize(yaml_data["nextOperation"])
|
|
504
489
|
yaml_data["nextOperation"]["groupName"] = self.pad_reserved_words(
|
|
505
490
|
yaml_data["nextOperation"]["groupName"], PadType.OPERATION_GROUP
|
|
506
491
|
)
|