@autorest/python 5.17.0 → 6.0.0-rc.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/ChangeLog.md +63 -1
- package/README.md +9 -0
- package/autorest/codegen/__init__.py +24 -30
- package/autorest/codegen/models/base_builder.py +17 -6
- package/autorest/codegen/models/base_type.py +6 -0
- package/autorest/codegen/models/client.py +9 -6
- package/autorest/codegen/models/code_model.py +20 -14
- package/autorest/codegen/models/dictionary_type.py +16 -1
- package/autorest/codegen/models/imports.py +57 -2
- package/autorest/codegen/models/list_type.py +16 -1
- package/autorest/codegen/models/lro_operation.py +4 -6
- package/autorest/codegen/models/lro_paging_operation.py +3 -9
- package/autorest/codegen/models/model_type.py +34 -16
- package/autorest/codegen/models/operation.py +47 -79
- package/autorest/codegen/models/operation_group.py +10 -9
- package/autorest/codegen/models/paging_operation.py +4 -6
- package/autorest/codegen/models/parameter.py +3 -7
- package/autorest/codegen/models/parameter_list.py +26 -35
- package/autorest/codegen/models/property.py +14 -0
- package/autorest/codegen/models/request_builder.py +32 -43
- package/autorest/codegen/serializers/__init__.py +12 -50
- package/autorest/codegen/serializers/builder_serializer.py +136 -49
- package/autorest/codegen/serializers/client_serializer.py +23 -32
- package/autorest/codegen/serializers/general_serializer.py +12 -12
- package/autorest/codegen/serializers/import_serializer.py +11 -22
- package/autorest/codegen/serializers/metadata_serializer.py +0 -2
- package/autorest/codegen/serializers/{model_base_serializer.py → model_serializer.py} +58 -44
- package/autorest/codegen/serializers/operation_groups_serializer.py +3 -7
- package/autorest/codegen/serializers/operations_init_serializer.py +2 -23
- package/autorest/codegen/serializers/patch_serializer.py +1 -3
- package/autorest/codegen/serializers/request_builders_serializer.py +2 -5
- package/autorest/codegen/serializers/utils.py +3 -4
- package/autorest/codegen/templates/client.py.jinja2 +6 -3
- package/autorest/codegen/templates/config.py.jinja2 +2 -2
- package/autorest/codegen/templates/metadata.json.jinja2 +4 -4
- package/autorest/codegen/templates/model.py.jinja2 +1 -1
- package/autorest/codegen/templates/model_init.py.jinja2 +5 -12
- package/autorest/codegen/templates/operation_group.py.jinja2 +16 -3
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -8
- package/autorest/codegen/templates/operation_tools.jinja2 +3 -1
- package/autorest/codegen/templates/patch.py.jinja2 +1 -2
- package/autorest/codegen/templates/request_builder.py.jinja2 +0 -7
- package/autorest/codegen/templates/request_builders.py.jinja2 +1 -4
- package/autorest/codegen/templates/rest_init.py.jinja2 +3 -8
- package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
- package/autorest/codegen/templates/setup.py.jinja2 +4 -0
- package/autorest/codegen/templates/vendor.py.jinja2 +10 -0
- package/autorest/m4reformatter/__init__.py +82 -58
- package/autorest/multiapi/models/client.py +12 -2
- package/autorest/multiapi/serializers/__init__.py +17 -8
- package/autorest/multiapi/serializers/import_serializer.py +4 -8
- package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
- package/autorest/preprocess/__init__.py +1 -0
- package/package.json +2 -2
- package/autorest/codegen/serializers/model_generic_serializer.py +0 -32
- package/autorest/codegen/serializers/model_python3_serializer.py +0 -72
|
@@ -82,7 +82,11 @@ setup(
|
|
|
82
82
|
include_package_data=True,
|
|
83
83
|
{% endif %}
|
|
84
84
|
install_requires=[
|
|
85
|
+
{% if code_model.is_legacy %}
|
|
85
86
|
"{{ dependency_msrest }}",
|
|
87
|
+
{% else %}
|
|
88
|
+
"isodate>=0.6.1",
|
|
89
|
+
{% endif %}
|
|
86
90
|
{% if azure_arm %}
|
|
87
91
|
"{{ dependency_azure_mgmt_core }}",
|
|
88
92
|
{% else %}
|
|
@@ -34,3 +34,13 @@ class MixinABC(ABC):
|
|
|
34
34
|
_serialize: "Serializer"
|
|
35
35
|
_deserialize: "Deserializer"
|
|
36
36
|
{% endif %}
|
|
37
|
+
{% if code_model.has_abstract_operations %}
|
|
38
|
+
|
|
39
|
+
def raise_if_not_implemented(cls, abstract_methods):
|
|
40
|
+
not_implemented = [f for f in abstract_methods if not callable(getattr(cls, f, None))]
|
|
41
|
+
if not_implemented:
|
|
42
|
+
raise NotImplementedError("The following methods on operation group '{}' are not implemented: '{}'."
|
|
43
|
+
" Please refer to https://aka.ms/azsdk/python/dpcodegen/python/customize to learn how to customize.".format(
|
|
44
|
+
cls.__name__, '\', \''.join(not_implemented))
|
|
45
|
+
)
|
|
46
|
+
{% endif %}
|
|
@@ -134,7 +134,7 @@ def update_property(
|
|
|
134
134
|
|
|
135
135
|
def update_discriminated_subtypes(yaml_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
136
136
|
return {
|
|
137
|
-
obj["discriminatorValue"]: obj
|
|
137
|
+
obj["discriminatorValue"]: update_type(obj)
|
|
138
138
|
for obj in yaml_data.get("discriminator", {}).get("immediate", {}).values()
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -431,39 +431,6 @@ def update_client_url(yaml_data: Dict[str, Any]) -> str:
|
|
|
431
431
|
]["uri"]
|
|
432
432
|
|
|
433
433
|
|
|
434
|
-
def update_content_type_parameter(
|
|
435
|
-
yaml_data: Dict[str, Any],
|
|
436
|
-
body_parameter: Optional[Dict[str, Any]],
|
|
437
|
-
request_media_types: List[str],
|
|
438
|
-
*,
|
|
439
|
-
in_overload: bool = False,
|
|
440
|
-
in_overriden: bool = False,
|
|
441
|
-
) -> Dict[str, Any]:
|
|
442
|
-
# override content type type to string
|
|
443
|
-
if not body_parameter:
|
|
444
|
-
return yaml_data
|
|
445
|
-
param = copy.deepcopy(yaml_data)
|
|
446
|
-
param["schema"] = KNOWN_TYPES["string"] # override to string type
|
|
447
|
-
param["required"] = False
|
|
448
|
-
description = param["language"]["default"]["description"]
|
|
449
|
-
if description and description[-1] != ".":
|
|
450
|
-
description += "."
|
|
451
|
-
if not (in_overriden or in_overload):
|
|
452
|
-
param["inDocstring"] = False
|
|
453
|
-
elif in_overload:
|
|
454
|
-
description += (
|
|
455
|
-
" Content type parameter for "
|
|
456
|
-
f"{get_body_type_for_description(body_parameter)} body."
|
|
457
|
-
)
|
|
458
|
-
elif not in_overload:
|
|
459
|
-
content_types = "'" + "', '".join(request_media_types) + "'"
|
|
460
|
-
description += f" Known values are: {content_types}."
|
|
461
|
-
if not in_overload and not in_overriden:
|
|
462
|
-
param["clientDefaultValue"] = body_parameter["defaultContentType"]
|
|
463
|
-
param["language"]["default"]["description"] = description
|
|
464
|
-
return param
|
|
465
|
-
|
|
466
|
-
|
|
467
434
|
class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-methods
|
|
468
435
|
"""Add Python naming information."""
|
|
469
436
|
|
|
@@ -471,11 +438,23 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
471
438
|
def azure_arm(self) -> bool:
|
|
472
439
|
return bool(self._autorestapi.get_boolean_value("azure-arm"))
|
|
473
440
|
|
|
441
|
+
@property
|
|
442
|
+
def version_tolerant(self) -> bool:
|
|
443
|
+
return bool(self._autorestapi.get_boolean_value("version-tolerant"))
|
|
444
|
+
|
|
445
|
+
@property
|
|
446
|
+
def low_level_client(self) -> bool:
|
|
447
|
+
return bool(self._autorestapi.get_boolean_value("low-level-client"))
|
|
448
|
+
|
|
449
|
+
@property
|
|
450
|
+
def legacy(self) -> bool:
|
|
451
|
+
return not (self.version_tolerant or self.low_level_client)
|
|
452
|
+
|
|
474
453
|
@property
|
|
475
454
|
def default_optional_constants_to_none(self) -> bool:
|
|
476
455
|
return bool(
|
|
477
456
|
self._autorestapi.get_boolean_value("default-optional-constants-to-none")
|
|
478
|
-
or self.
|
|
457
|
+
or self.version_tolerant
|
|
479
458
|
)
|
|
480
459
|
|
|
481
460
|
def update_overloads(
|
|
@@ -515,6 +494,13 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
515
494
|
in_overriden = (
|
|
516
495
|
body_parameter["type"]["type"] == "combined" if body_parameter else False
|
|
517
496
|
)
|
|
497
|
+
abstract = False
|
|
498
|
+
if body_parameter and (
|
|
499
|
+
body_parameter.get("entries")
|
|
500
|
+
or len(body_parameter["type"].get("types", [])) > 2
|
|
501
|
+
):
|
|
502
|
+
# this means it's formdata or urlencoded, or there are more than 2 types of body
|
|
503
|
+
abstract = True
|
|
518
504
|
return {
|
|
519
505
|
"name": yaml_data["language"]["default"]["name"],
|
|
520
506
|
"description": yaml_data["language"]["default"]["description"],
|
|
@@ -541,6 +527,7 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
541
527
|
"discriminator": "operation",
|
|
542
528
|
"isOverload": is_overload,
|
|
543
529
|
"apiVersions": _get_api_versions(yaml_data.get("apiVersions", [])),
|
|
530
|
+
"abstract": abstract,
|
|
544
531
|
}
|
|
545
532
|
|
|
546
533
|
def get_operation_creator(
|
|
@@ -689,6 +676,9 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
689
676
|
body_param["defaultContentType"] = _get_default_content_type(
|
|
690
677
|
body_param["contentTypes"]
|
|
691
678
|
)
|
|
679
|
+
# python supports IO input with all kinds of content_types
|
|
680
|
+
if body_type["type"] == "binary":
|
|
681
|
+
body_param["contentTypes"] = content_types or list(yaml_data.keys())
|
|
692
682
|
if body_param["type"]["type"] == "constant":
|
|
693
683
|
if not body_param["optional"] or (
|
|
694
684
|
body_param["optional"] and not self.default_optional_constants_to_none
|
|
@@ -771,11 +761,53 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
771
761
|
param["inFlattenedBody"] = True
|
|
772
762
|
return param
|
|
773
763
|
|
|
764
|
+
def _update_content_type_parameter(
|
|
765
|
+
self,
|
|
766
|
+
yaml_data: Dict[str, Any],
|
|
767
|
+
body_parameter: Optional[Dict[str, Any]],
|
|
768
|
+
request_media_types: List[str],
|
|
769
|
+
*,
|
|
770
|
+
in_overload: bool = False,
|
|
771
|
+
in_overriden: bool = False,
|
|
772
|
+
) -> Dict[str, Any]:
|
|
773
|
+
# override content type type to string
|
|
774
|
+
if not body_parameter:
|
|
775
|
+
return yaml_data
|
|
776
|
+
param = copy.deepcopy(yaml_data)
|
|
777
|
+
param["schema"] = KNOWN_TYPES["string"] # override to string type
|
|
778
|
+
if (
|
|
779
|
+
body_parameter["type"]["type"] == "binary"
|
|
780
|
+
and not body_parameter["defaultContentType"]
|
|
781
|
+
and not self.legacy
|
|
782
|
+
):
|
|
783
|
+
param["required"] = True
|
|
784
|
+
else:
|
|
785
|
+
param["required"] = False
|
|
786
|
+
description = param["language"]["default"]["description"]
|
|
787
|
+
if description and description[-1] != ".":
|
|
788
|
+
description += "."
|
|
789
|
+
if not (in_overriden or in_overload):
|
|
790
|
+
param["inDocstring"] = False
|
|
791
|
+
elif in_overload:
|
|
792
|
+
description += (
|
|
793
|
+
" Content type parameter for "
|
|
794
|
+
f"{get_body_type_for_description(body_parameter)} body."
|
|
795
|
+
)
|
|
796
|
+
if not in_overload or (
|
|
797
|
+
body_parameter["type"]["type"] == "binary" and len(request_media_types) > 1
|
|
798
|
+
):
|
|
799
|
+
content_types = "'" + "', '".join(request_media_types) + "'"
|
|
800
|
+
description += f" Known values are: {content_types}."
|
|
801
|
+
if not in_overload and not in_overriden:
|
|
802
|
+
param["clientDefaultValue"] = body_parameter["defaultContentType"]
|
|
803
|
+
param["language"]["default"]["description"] = description
|
|
804
|
+
return param
|
|
805
|
+
|
|
774
806
|
def _update_parameters_helper(
|
|
775
807
|
self,
|
|
776
808
|
parameters: List[Dict[str, Any]],
|
|
777
809
|
body_parameter: Optional[Dict[str, Any]],
|
|
778
|
-
|
|
810
|
+
seen_client_names: Set[str],
|
|
779
811
|
groupers: Dict[str, Dict[str, Any]],
|
|
780
812
|
request_media_types: List[str],
|
|
781
813
|
*,
|
|
@@ -785,15 +817,17 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
785
817
|
retval: List[Dict[str, Any]] = []
|
|
786
818
|
has_flattened_body = body_parameter and body_parameter.get("flattened")
|
|
787
819
|
for param in parameters:
|
|
788
|
-
|
|
820
|
+
client_name = param["language"]["default"]["name"]
|
|
789
821
|
if param["language"]["default"]["name"] == "$host" or (
|
|
790
|
-
|
|
822
|
+
client_name in seen_client_names
|
|
791
823
|
):
|
|
792
824
|
continue
|
|
825
|
+
seen_client_names.add(client_name)
|
|
793
826
|
if param.get("origin") == "modelerfour:synthesized/api-version":
|
|
794
827
|
param["inDocstring"] = False
|
|
795
|
-
|
|
796
|
-
|
|
828
|
+
if self.legacy:
|
|
829
|
+
param["implementation"] = "Method"
|
|
830
|
+
param["checkClientInput"] = True
|
|
797
831
|
if has_flattened_body and param.get("targetProperty"):
|
|
798
832
|
retval.append(self.update_flattened_parameter(param, body_parameter))
|
|
799
833
|
continue
|
|
@@ -806,8 +840,8 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
806
840
|
continue
|
|
807
841
|
if is_body(param):
|
|
808
842
|
continue
|
|
809
|
-
if
|
|
810
|
-
param =
|
|
843
|
+
if param["language"]["default"].get("serializedName") == "Content-Type":
|
|
844
|
+
param = self._update_content_type_parameter(
|
|
811
845
|
param,
|
|
812
846
|
body_parameter,
|
|
813
847
|
request_media_types,
|
|
@@ -818,7 +852,6 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
818
852
|
param, in_overload=in_overload, in_overriden=in_overriden
|
|
819
853
|
)
|
|
820
854
|
retval.append(updated_param)
|
|
821
|
-
seen_rest_api_names.add(updated_param["restApiName"])
|
|
822
855
|
return retval
|
|
823
856
|
|
|
824
857
|
def update_parameters(
|
|
@@ -830,7 +863,7 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
830
863
|
in_overriden: bool = False,
|
|
831
864
|
) -> List[Dict[str, Any]]:
|
|
832
865
|
retval: List[Dict[str, Any]] = []
|
|
833
|
-
|
|
866
|
+
seen_client_names: Set[str] = set()
|
|
834
867
|
groupers: Dict[str, Dict[str, Any]] = {}
|
|
835
868
|
# first update top level parameters
|
|
836
869
|
request_media_types = yaml_data.get("requestMediaTypes", [])
|
|
@@ -838,7 +871,7 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
838
871
|
self._update_parameters_helper(
|
|
839
872
|
yaml_data["parameters"],
|
|
840
873
|
body_parameter,
|
|
841
|
-
|
|
874
|
+
seen_client_names,
|
|
842
875
|
groupers,
|
|
843
876
|
request_media_types,
|
|
844
877
|
in_overload=in_overload,
|
|
@@ -857,7 +890,7 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
857
890
|
self._update_parameters_helper(
|
|
858
891
|
request.get("parameters", []),
|
|
859
892
|
body_parameter,
|
|
860
|
-
|
|
893
|
+
seen_client_names,
|
|
861
894
|
groupers,
|
|
862
895
|
request_media_types,
|
|
863
896
|
in_overload=in_overload,
|
|
@@ -921,15 +954,8 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
921
954
|
name = global_parameter["language"]["default"]["name"]
|
|
922
955
|
if name == "$host":
|
|
923
956
|
# I am the non-parameterized endpoint. Modify name based off of flag
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
)
|
|
927
|
-
low_level_client = self._autorestapi.get_boolean_value(
|
|
928
|
-
"low-level-client", False
|
|
929
|
-
)
|
|
930
|
-
client_name = (
|
|
931
|
-
"endpoint" if (version_tolerant or low_level_client) else "base_url"
|
|
932
|
-
)
|
|
957
|
+
|
|
958
|
+
client_name = "base_url" if self.legacy else "endpoint"
|
|
933
959
|
global_parameter["language"]["default"]["description"] = "Service URL."
|
|
934
960
|
global_params.append(
|
|
935
961
|
self.update_parameter(
|
|
@@ -1054,9 +1080,7 @@ class M4Reformatter(YamlUpdatePlugin): # pylint: disable=too-many-public-method
|
|
|
1054
1080
|
"skipUrlEncoding": True,
|
|
1055
1081
|
"inOverload": False,
|
|
1056
1082
|
}
|
|
1057
|
-
if self.
|
|
1058
|
-
"version-tolerant"
|
|
1059
|
-
) or self._autorestapi.get_boolean_value("low-level-client"):
|
|
1083
|
+
if self.version_tolerant or self.low_level_client:
|
|
1060
1084
|
parameters.append(credential)
|
|
1061
1085
|
else:
|
|
1062
1086
|
parameters.insert(0, credential)
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import sys
|
|
7
7
|
import json
|
|
8
|
+
import re
|
|
8
9
|
from typing import Any, Dict, List
|
|
9
10
|
from pathlib import Path
|
|
10
|
-
from .imports import FileImport
|
|
11
|
+
from .imports import FileImport, TypingSection, ImportType
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def _extract_version(metadata_json: Dict[str, Any], version_path: Path) -> str:
|
|
@@ -43,9 +44,18 @@ class Client:
|
|
|
43
44
|
|
|
44
45
|
def imports(self, async_mode: bool) -> FileImport:
|
|
45
46
|
imports_to_load = "async_imports" if async_mode else "sync_imports"
|
|
46
|
-
|
|
47
|
+
file_import = FileImport(
|
|
47
48
|
json.loads(self.default_version_metadata["client"][imports_to_load])
|
|
48
49
|
)
|
|
50
|
+
local_imports = file_import.imports.get(TypingSection.REGULAR, {}).get(
|
|
51
|
+
ImportType.LOCAL, {}
|
|
52
|
+
)
|
|
53
|
+
for key in local_imports:
|
|
54
|
+
if re.search("^\\.*_serialization$", key):
|
|
55
|
+
relative_path = ".." if async_mode else "."
|
|
56
|
+
local_imports[f"{relative_path}_serialization"] = local_imports.pop(key)
|
|
57
|
+
break
|
|
58
|
+
return file_import
|
|
49
59
|
|
|
50
60
|
@property
|
|
51
61
|
def parameterized_host_template_to_api_version(self) -> Dict[str, List[str]]:
|
|
@@ -57,18 +57,14 @@ class MultiAPISerializer(object):
|
|
|
57
57
|
)
|
|
58
58
|
|
|
59
59
|
# serialize service client file
|
|
60
|
-
imports = FileImportSerializer(
|
|
61
|
-
code_model.client.imports(async_mode), is_python3_file=async_mode
|
|
62
|
-
)
|
|
60
|
+
imports = FileImportSerializer(code_model.client.imports(async_mode))
|
|
63
61
|
self._autorestapi.write_file(
|
|
64
62
|
_get_file_path(code_model.client.filename, async_mode),
|
|
65
63
|
_render_template("client", imports=imports),
|
|
66
64
|
)
|
|
67
65
|
|
|
68
66
|
# serialize config file
|
|
69
|
-
imports = FileImportSerializer(
|
|
70
|
-
code_model.config.imports(async_mode), is_python3_file=async_mode
|
|
71
|
-
)
|
|
67
|
+
imports = FileImportSerializer(code_model.config.imports(async_mode))
|
|
72
68
|
self._autorestapi.write_file(
|
|
73
69
|
_get_file_path("_configuration", async_mode),
|
|
74
70
|
_render_template("config", imports=imports),
|
|
@@ -77,8 +73,7 @@ class MultiAPISerializer(object):
|
|
|
77
73
|
# serialize mixins
|
|
78
74
|
if code_model.operation_mixin_group.mixin_operations:
|
|
79
75
|
imports = FileImportSerializer(
|
|
80
|
-
code_model.operation_mixin_group.imports(async_mode)
|
|
81
|
-
is_python3_file=async_mode,
|
|
76
|
+
code_model.operation_mixin_group.imports(async_mode)
|
|
82
77
|
)
|
|
83
78
|
self._autorestapi.write_file(
|
|
84
79
|
_get_file_path("_operations_mixin", async_mode),
|
|
@@ -115,3 +110,17 @@ class MultiAPISerializer(object):
|
|
|
115
110
|
)
|
|
116
111
|
|
|
117
112
|
self._autorestapi.write_file(Path("py.typed"), "# Marker file for PEP 561.")
|
|
113
|
+
|
|
114
|
+
if not code_model.client.client_side_validation:
|
|
115
|
+
codegen_env = Environment(
|
|
116
|
+
loader=PackageLoader("autorest.codegen", "templates"),
|
|
117
|
+
keep_trailing_newline=True,
|
|
118
|
+
line_statement_prefix="##",
|
|
119
|
+
line_comment_prefix="###",
|
|
120
|
+
trim_blocks=True,
|
|
121
|
+
lstrip_blocks=True,
|
|
122
|
+
)
|
|
123
|
+
self._autorestapi.write_file(
|
|
124
|
+
Path("_serialization.py"),
|
|
125
|
+
codegen_env.get_template("serialization.py.jinja2").render(),
|
|
126
|
+
)
|
|
@@ -54,9 +54,8 @@ def _get_import_clauses(
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
class FileImportSerializer:
|
|
57
|
-
def __init__(self, file_import: FileImport
|
|
57
|
+
def __init__(self, file_import: FileImport) -> None:
|
|
58
58
|
self._file_import = file_import
|
|
59
|
-
self.is_python3_file = is_python3_file
|
|
60
59
|
|
|
61
60
|
def _switch_typing_section_key(self, new_key: TypingSection):
|
|
62
61
|
switched_dictionary = {}
|
|
@@ -84,10 +83,7 @@ class FileImportSerializer:
|
|
|
84
83
|
return file_import_copy.imports.get(baseline_typing_section, {})
|
|
85
84
|
|
|
86
85
|
def _add_type_checking_import(self):
|
|
87
|
-
if self._file_import.imports.get(TypingSection.TYPING)
|
|
88
|
-
not self.is_python3_file
|
|
89
|
-
and self._file_import.imports.get(TypingSection.CONDITIONAL)
|
|
90
|
-
):
|
|
86
|
+
if self._file_import.imports.get(TypingSection.TYPING):
|
|
91
87
|
self._file_import.add_submodule_import(
|
|
92
88
|
"typing", "TYPE_CHECKING", ImportType.STDLIB
|
|
93
89
|
)
|
|
@@ -97,7 +93,7 @@ class FileImportSerializer:
|
|
|
97
93
|
regular_imports = ""
|
|
98
94
|
regular_imports_dict = self._get_imports_dict(
|
|
99
95
|
baseline_typing_section=TypingSection.REGULAR,
|
|
100
|
-
add_conditional_typing=
|
|
96
|
+
add_conditional_typing=True,
|
|
101
97
|
)
|
|
102
98
|
|
|
103
99
|
if regular_imports_dict:
|
|
@@ -108,7 +104,7 @@ class FileImportSerializer:
|
|
|
108
104
|
typing_imports = ""
|
|
109
105
|
typing_imports_dict = self._get_imports_dict(
|
|
110
106
|
baseline_typing_section=TypingSection.TYPING,
|
|
111
|
-
add_conditional_typing=
|
|
107
|
+
add_conditional_typing=False,
|
|
112
108
|
)
|
|
113
109
|
if typing_imports_dict:
|
|
114
110
|
typing_imports += "\n\nif TYPE_CHECKING:\n # pylint: disable=unused-import,ungrouped-imports\n "
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# Changes may cause incorrect behavior and will be lost if the code is
|
|
9
9
|
# regenerated.
|
|
10
10
|
# --------------------------------------------------------------------------
|
|
11
|
-
from
|
|
11
|
+
from {{ ".." if async_mode else "." }}_serialization import Serializer, Deserializer
|
|
12
12
|
{% if imports %}
|
|
13
13
|
{{ imports }}
|
|
14
14
|
{% endif %}
|
|
@@ -62,6 +62,7 @@ def update_types(yaml_data: List[Dict[str, Any]]) -> None:
|
|
|
62
62
|
add_redefined_builtin_info(property["clientName"], property)
|
|
63
63
|
if type.get("name"):
|
|
64
64
|
type["description"] = update_description(type["description"], type["name"])
|
|
65
|
+
type["snakeCaseName"] = to_snake_case(type["name"])
|
|
65
66
|
|
|
66
67
|
|
|
67
68
|
def update_client(yaml_data: Dict[str, Any]) -> None:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autorest/python",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-rc.1",
|
|
4
4
|
"description": "The Python extension for generators in AutoRest.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepare": "node run-python3.js prepare.py",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@autorest/system-requirements": "~1.0.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@microsoft.azure/autorest.testserver": "^3.3.
|
|
30
|
+
"@microsoft.azure/autorest.testserver": "^3.3.29"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"autorest/**/*.py",
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# -------------------------------------------------------------------------
|
|
2
|
-
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
-
# license information.
|
|
5
|
-
# --------------------------------------------------------------------------
|
|
6
|
-
from typing import List
|
|
7
|
-
from jinja2 import Environment
|
|
8
|
-
from .model_base_serializer import ModelBaseSerializer
|
|
9
|
-
from ..models import ModelType, CodeModel, Property
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ModelGenericSerializer(ModelBaseSerializer):
|
|
13
|
-
def __init__(self, code_model: CodeModel, env: Environment) -> None:
|
|
14
|
-
super().__init__(code_model=code_model, env=env, is_python3_file=False)
|
|
15
|
-
|
|
16
|
-
def init_line(self, model: ModelType) -> List[str]:
|
|
17
|
-
return []
|
|
18
|
-
|
|
19
|
-
def properties_to_pass_to_super(self, model: ModelType) -> str:
|
|
20
|
-
return "**kwargs"
|
|
21
|
-
|
|
22
|
-
def required_property_no_default_init(self, prop: Property) -> str:
|
|
23
|
-
return f"self.{prop.client_name} = kwargs['{prop.client_name}']"
|
|
24
|
-
|
|
25
|
-
def optional_property_init(self, prop: Property) -> str:
|
|
26
|
-
return f"self.{prop.client_name} = kwargs.get('{prop.client_name}', {prop.client_default_value_declaration})"
|
|
27
|
-
|
|
28
|
-
def initialize_standard_arg(self, prop: Property) -> str:
|
|
29
|
-
return self.initialize_standard_property(prop)
|
|
30
|
-
|
|
31
|
-
def super_call_template(self, model: ModelType) -> str:
|
|
32
|
-
return "super(" + model.name + ", self).__init__({})"
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# -------------------------------------------------------------------------
|
|
2
|
-
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
|
-
# license information.
|
|
5
|
-
# --------------------------------------------------------------------------
|
|
6
|
-
from typing import List
|
|
7
|
-
from jinja2 import Environment
|
|
8
|
-
from .model_base_serializer import ModelBaseSerializer
|
|
9
|
-
from ..models import ModelType, CodeModel, Property
|
|
10
|
-
from ..models.imports import FileImport
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class ModelPython3Serializer(ModelBaseSerializer):
|
|
14
|
-
def __init__(self, code_model: CodeModel, env: Environment) -> None:
|
|
15
|
-
super().__init__(code_model=code_model, env=env, is_python3_file=True)
|
|
16
|
-
|
|
17
|
-
def init_line(self, model: ModelType) -> List[str]:
|
|
18
|
-
init_properties_declaration = []
|
|
19
|
-
init_line_parameters = [
|
|
20
|
-
p
|
|
21
|
-
for p in model.properties
|
|
22
|
-
if not p.readonly and not p.is_discriminator and not p.constant
|
|
23
|
-
]
|
|
24
|
-
init_line_parameters.sort(key=lambda x: x.optional)
|
|
25
|
-
if init_line_parameters:
|
|
26
|
-
init_properties_declaration.append("*,")
|
|
27
|
-
for param in init_line_parameters:
|
|
28
|
-
init_properties_declaration.append(self.initialize_standard_property(param))
|
|
29
|
-
|
|
30
|
-
return init_properties_declaration
|
|
31
|
-
|
|
32
|
-
def properties_to_pass_to_super(self, model: ModelType) -> str:
|
|
33
|
-
properties_to_pass_to_super = []
|
|
34
|
-
for parent in model.parents:
|
|
35
|
-
for prop in model.properties:
|
|
36
|
-
if (
|
|
37
|
-
prop in parent.properties
|
|
38
|
-
and not prop.is_discriminator
|
|
39
|
-
and not prop.constant
|
|
40
|
-
and not prop.readonly
|
|
41
|
-
):
|
|
42
|
-
properties_to_pass_to_super.append(
|
|
43
|
-
f"{prop.client_name}={prop.client_name}"
|
|
44
|
-
)
|
|
45
|
-
properties_to_pass_to_super.append("**kwargs")
|
|
46
|
-
return ", ".join(properties_to_pass_to_super)
|
|
47
|
-
|
|
48
|
-
def required_property_no_default_init(self, prop: Property) -> str:
|
|
49
|
-
return f"{prop.client_name}: {prop.type_annotation()},{prop.pylint_disable}"
|
|
50
|
-
|
|
51
|
-
def optional_property_init(self, prop: Property) -> str:
|
|
52
|
-
return (
|
|
53
|
-
f"{prop.client_name}: {prop.type_annotation()} = "
|
|
54
|
-
f"{prop.client_default_value_declaration},{prop.pylint_disable}"
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
def initialize_standard_arg(self, prop: Property) -> str:
|
|
58
|
-
return f"self.{prop.client_name} = {prop.client_name}"
|
|
59
|
-
|
|
60
|
-
def super_call_template(self, model: ModelType) -> str:
|
|
61
|
-
return "super().__init__({})"
|
|
62
|
-
|
|
63
|
-
def imports(self) -> FileImport:
|
|
64
|
-
file_import = super(ModelPython3Serializer, self).imports()
|
|
65
|
-
for model in self.code_model.model_types:
|
|
66
|
-
init_line_parameters = [
|
|
67
|
-
p for p in model.properties if not p.readonly and not p.is_discriminator
|
|
68
|
-
]
|
|
69
|
-
for param in init_line_parameters:
|
|
70
|
-
file_import.merge(param.imports())
|
|
71
|
-
|
|
72
|
-
return file_import
|