@autorest/python 6.1.11 → 6.2.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/_utils.py +2 -1
- package/autorest/codegen/__init__.py +23 -81
- package/autorest/codegen/models/__init__.py +5 -3
- package/autorest/codegen/models/{base_type.py → base.py} +24 -3
- package/autorest/codegen/models/base_builder.py +9 -5
- package/autorest/codegen/models/client.py +183 -13
- package/autorest/codegen/models/code_model.py +154 -141
- package/autorest/codegen/models/combined_type.py +5 -2
- package/autorest/codegen/models/constant_type.py +38 -4
- package/autorest/codegen/models/credential_types.py +1 -1
- package/autorest/codegen/models/dictionary_type.py +1 -1
- package/autorest/codegen/models/enum_type.py +5 -3
- package/autorest/codegen/models/imports.py +78 -29
- package/autorest/codegen/models/list_type.py +1 -1
- package/autorest/codegen/models/lro_operation.py +5 -1
- package/autorest/codegen/models/model_type.py +1 -2
- package/autorest/codegen/models/operation.py +34 -10
- package/autorest/codegen/models/operation_group.py +16 -5
- package/autorest/codegen/models/paging_operation.py +5 -4
- package/autorest/codegen/models/parameter.py +19 -6
- package/autorest/codegen/models/primitive_types.py +1 -2
- package/autorest/codegen/models/property.py +4 -4
- package/autorest/codegen/models/request_builder.py +17 -6
- package/autorest/codegen/models/request_builder_parameter.py +5 -2
- package/autorest/codegen/models/response.py +6 -3
- package/autorest/codegen/serializers/__init__.py +207 -135
- package/autorest/codegen/serializers/builder_serializer.py +2 -4
- package/autorest/codegen/serializers/client_serializer.py +41 -45
- package/autorest/codegen/serializers/general_serializer.py +80 -37
- package/autorest/codegen/serializers/import_serializer.py +30 -36
- package/autorest/codegen/serializers/metadata_serializer.py +36 -14
- package/autorest/codegen/serializers/model_serializer.py +34 -19
- package/autorest/codegen/serializers/operation_groups_serializer.py +22 -6
- package/autorest/codegen/serializers/operations_init_serializer.py +10 -4
- package/autorest/codegen/serializers/sample_serializer.py +144 -0
- package/autorest/codegen/templates/client.py.jinja2 +7 -15
- package/autorest/codegen/templates/client_container.py.jinja2 +12 -0
- package/autorest/codegen/templates/config.py.jinja2 +13 -26
- package/autorest/codegen/templates/config_container.py.jinja2 +16 -0
- package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
- package/autorest/codegen/templates/init.py.jinja2 +9 -3
- package/autorest/codegen/templates/lro_operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/metadata.json.jinja2 +13 -14
- package/autorest/codegen/templates/model_dpg.py.jinja2 +4 -4
- package/autorest/codegen/templates/model_init.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation.py.jinja2 +1 -1
- package/autorest/codegen/templates/operation_group.py.jinja2 +2 -2
- package/autorest/codegen/templates/operation_groups_container.py.jinja2 +5 -5
- package/autorest/codegen/templates/operation_tools.jinja2 +2 -2
- package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -4
- package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2} +0 -0
- package/autorest/codegen/templates/{LICENSE.jinja2 → packaging_templates/LICENSE.jinja2} +0 -0
- package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2} +0 -0
- package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2} +0 -0
- package/autorest/codegen/templates/{dev_requirements.txt.jinja2 → packaging_templates/dev_requirements.txt.jinja2} +0 -0
- package/autorest/codegen/templates/{setup.py.jinja2 → packaging_templates/setup.py.jinja2} +12 -9
- package/autorest/codegen/templates/request_builders.py.jinja2 +2 -2
- package/autorest/codegen/templates/sample.py.jinja2 +44 -0
- package/autorest/codegen/templates/vendor.py.jinja2 +4 -2
- package/autorest/m4reformatter/__init__.py +18 -4
- package/autorest/multiapi/models/imports.py +89 -18
- package/autorest/multiapi/serializers/import_serializer.py +88 -7
- package/autorest/multiapi/utils.py +6 -0
- package/autorest/preprocess/__init__.py +20 -8
- package/package.json +1 -1
- package/run_cadl.py +0 -1
- package/autorest/cadlflags/__init__.py +0 -130
- package/autorest/codegen/models/base_model.py +0 -28
|
@@ -16,7 +16,7 @@ class {{ operation_group.class_name }}{{ base_class }}:{{ disable }}
|
|
|
16
16
|
**DO NOT** instantiate this class directly.
|
|
17
17
|
|
|
18
18
|
Instead, you should access the following operations through
|
|
19
|
-
:class:`{{ "~" + code_model.namespace + (".aio." if async_mode else ".") +
|
|
19
|
+
:class:`{{ "~" + code_model.namespace + (".aio." if async_mode else ".") + operation_group.client.name }}`'s
|
|
20
20
|
:attr:`{{ operation_group.property_name }}` attribute.
|
|
21
21
|
"""
|
|
22
22
|
|
|
@@ -50,4 +50,4 @@ class {{ operation_group.class_name }}{{ base_class }}:{{ disable }}
|
|
|
50
50
|
{% macro someop() %}{% include "operation.py.jinja2" %}{% endmacro %}
|
|
51
51
|
{% endif %}
|
|
52
52
|
{{ someop()|indent }}
|
|
53
|
-
{% endfor %}
|
|
53
|
+
{% endfor %}
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
{{ imports }}
|
|
8
8
|
|
|
9
9
|
{% if code_model.options["builders_visibility"] == "embedded" and not async_mode %}
|
|
10
|
-
{{ op_tools.declare_serializer(code_model
|
|
11
|
-
{% for operation_group in operation_groups %}
|
|
12
|
-
|
|
10
|
+
{{ op_tools.declare_serializer(code_model) }}
|
|
11
|
+
{% for operation_group in operation_groups %}
|
|
12
|
+
{% for request_builder in get_request_builders(operation_group) %}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
{% include "request_builder.py.jinja2" %}
|
|
15
|
+
{% endfor %}
|
|
15
16
|
{% endfor %}
|
|
16
|
-
{% endfor %}
|
|
17
17
|
{% endif %}
|
|
18
18
|
{% for operation_group in operation_groups %}
|
|
19
19
|
{% include "operation_group.py.jinja2" %}
|
|
@@ -50,8 +50,8 @@ Example:
|
|
|
50
50
|
{% endif %}
|
|
51
51
|
{% endfor %}{% endmacro %}
|
|
52
52
|
|
|
53
|
-
{% macro declare_serializer(code_model
|
|
54
|
-
{% if
|
|
53
|
+
{% macro declare_serializer(code_model) %}
|
|
54
|
+
{% if code_model.has_non_abstract_operations %}
|
|
55
55
|
_SERIALIZER = Serializer()
|
|
56
56
|
{% if not code_model.options["client_side_validation"] %}
|
|
57
57
|
_SERIALIZER.client_side_validation = False
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
{{ op_tools.serialize(operation_group_imports()) }}
|
|
8
8
|
{{ keywords.patch_imports() }}
|
|
9
|
-
{% if operation_groups %}
|
|
10
9
|
__all__ = [
|
|
11
|
-
{% for
|
|
10
|
+
{% for client in clients %}
|
|
11
|
+
{% for operation_group in client.operation_groups %}
|
|
12
12
|
'{{ operation_group.class_name }}',
|
|
13
|
+
{% endfor %}
|
|
13
14
|
{% endfor %}
|
|
14
15
|
]
|
|
15
|
-
{% endif %}
|
|
16
16
|
{{ keywords.extend_all }}
|
|
17
|
-
_patch_sdk()
|
|
17
|
+
_patch_sdk()
|
package/autorest/codegen/templates/{CHANGELOG.md.jinja2 → packaging_templates/CHANGELOG.md.jinja2}
RENAMED
|
File without changes
|
|
File without changes
|
package/autorest/codegen/templates/{MANIFEST.in.jinja2 → packaging_templates/MANIFEST.in.jinja2}
RENAMED
|
File without changes
|
package/autorest/codegen/templates/{README.md.jinja2 → packaging_templates/README.md.jinja2}
RENAMED
|
File without changes
|
|
File without changes
|
|
@@ -7,9 +7,9 @@ import re
|
|
|
7
7
|
{% endif -%}
|
|
8
8
|
from setuptools import setup, find_packages
|
|
9
9
|
|
|
10
|
-
{% set
|
|
10
|
+
{% set package_name = package_name or code_model.clients[0].name %}
|
|
11
11
|
|
|
12
|
-
PACKAGE_NAME = "{{
|
|
12
|
+
PACKAGE_NAME = "{{ package_name|lower }}"
|
|
13
13
|
{% if package_mode -%}
|
|
14
14
|
PACKAGE_PPRINT_NAME = "{{ package_pprint_name }}"
|
|
15
15
|
|
|
@@ -28,9 +28,9 @@ if not version:
|
|
|
28
28
|
{% set author_email = "azpysdkhelp@microsoft.com" %}
|
|
29
29
|
{% set url = "https://github.com/Azure/azure-sdk-for-python/tree/main/sdk" %}
|
|
30
30
|
{% else %}
|
|
31
|
-
version = "{{
|
|
32
|
-
{% set description = "%s"|format(
|
|
33
|
-
{% set long_description = code_model.
|
|
31
|
+
version = "{{ package_version }}"
|
|
32
|
+
{% set description = "%s"|format(package_name) %}
|
|
33
|
+
{% set long_description = code_model.description %}
|
|
34
34
|
{% set author_email = "" %}
|
|
35
35
|
{% set url = "" %}
|
|
36
36
|
{% endif -%}
|
|
@@ -82,21 +82,24 @@ setup(
|
|
|
82
82
|
{% endif %}
|
|
83
83
|
install_requires=[
|
|
84
84
|
{% if code_model.is_legacy %}
|
|
85
|
-
"
|
|
85
|
+
"msrest>=0.7.1",
|
|
86
86
|
{% else %}
|
|
87
87
|
"isodate<1.0.0,>=0.6.1",
|
|
88
88
|
{% endif %}
|
|
89
89
|
{% if azure_arm %}
|
|
90
|
-
"
|
|
90
|
+
"azure-mgmt-core<2.0.0,>=1.3.2",
|
|
91
91
|
{% else %}
|
|
92
|
-
"
|
|
92
|
+
"azure-core<2.0.0,>=1.24.0",
|
|
93
|
+
{% endif %}
|
|
94
|
+
{% if code_model.need_typing_extensions %}
|
|
95
|
+
"typing_extensions>=4.3.0; python_version<'3.8.0'",
|
|
93
96
|
{% endif %}
|
|
94
97
|
],
|
|
95
98
|
{% if package_mode %}
|
|
96
99
|
python_requires=">=3.7",
|
|
97
100
|
{% else %}
|
|
98
101
|
long_description="""\
|
|
99
|
-
{{ code_model.
|
|
102
|
+
{{ code_model.description }}
|
|
100
103
|
"""
|
|
101
104
|
{% endif %}
|
|
102
105
|
)
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
{{ code_model.options['license_header'] }}
|
|
4
4
|
{{ imports }}
|
|
5
5
|
|
|
6
|
-
{{ op_tools.declare_serializer(code_model
|
|
6
|
+
{{ op_tools.declare_serializer(code_model) }}
|
|
7
7
|
{% for request_builder in request_builders %}
|
|
8
8
|
|
|
9
9
|
{% include "request_builder.py.jinja2" %}
|
|
10
|
-
{% endfor %}
|
|
10
|
+
{% endfor %}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
{% set aad_token = "DefaultAzureCredential" %}
|
|
3
|
+
{% set azure_key = "AzureKeyCredential" %}
|
|
4
|
+
{{ code_model.options['license_header'] }}
|
|
5
|
+
|
|
6
|
+
{{ imports }}
|
|
7
|
+
"""
|
|
8
|
+
# PREREQUISITES
|
|
9
|
+
{% if "credential" in client_params and aad_token in client_params["credential"] %}
|
|
10
|
+
pip install azure-identity
|
|
11
|
+
{% endif %}
|
|
12
|
+
pip install {{ (code_model.options["package_name"] or code_model.clients[0].name)|lower }}
|
|
13
|
+
# USAGE
|
|
14
|
+
python {{ file_name }}
|
|
15
|
+
{% if "credential" in client_params and aad_token in client_params["credential"] %}
|
|
16
|
+
|
|
17
|
+
Before run the sample, please set the values of the client ID, tenant ID and client secret
|
|
18
|
+
of the AAD application as environment variables: AZURE_CLIENT_ID, AZURE_TENANT_ID,
|
|
19
|
+
AZURE_CLIENT_SECRET. For more info about how to get the value, please see:
|
|
20
|
+
https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal
|
|
21
|
+
{% elif "credential" in client_params and azure_key in client_params["credential"] %}
|
|
22
|
+
|
|
23
|
+
Before run the sample, please set environment variables AZURE_KEY with real value
|
|
24
|
+
which can access your service
|
|
25
|
+
{% endif %}
|
|
26
|
+
"""
|
|
27
|
+
def main():
|
|
28
|
+
client = {{ code_model.clients[0].name }}(
|
|
29
|
+
{% for key,value in client_params.items() %}
|
|
30
|
+
{{ key }}={{ value }},
|
|
31
|
+
{% endfor %}
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
response = client{{ operation_group_name }}{{ operation_name }}(
|
|
35
|
+
{% for key, value in operation_params.items() %}
|
|
36
|
+
{{ key }}={{ value|indent(8) }},
|
|
37
|
+
{% endfor %}
|
|
38
|
+
){{ operation_result }}
|
|
39
|
+
|
|
40
|
+
{% if origin_file %}
|
|
41
|
+
# x-ms-original-file: {{ origin_file }}
|
|
42
|
+
{% endif %}
|
|
43
|
+
if __name__ == "__main__":
|
|
44
|
+
main()
|
|
@@ -26,13 +26,15 @@ def _format_url_section(template, **kwargs):
|
|
|
26
26
|
template = "/".join(components)
|
|
27
27
|
{% endif %}
|
|
28
28
|
{% if code_model.need_mixin_abc %}
|
|
29
|
+
{% for client in code_model.clients | selectattr("has_mixin") %}
|
|
29
30
|
|
|
30
|
-
class MixinABC(ABC):
|
|
31
|
+
class {{ client.name }}MixinABC(ABC):
|
|
31
32
|
"""DO NOT use this class. It is for internal typing use only."""
|
|
32
33
|
_client: "{{ keywords.async_class }}PipelineClient"
|
|
33
|
-
_config: {{
|
|
34
|
+
_config: {{ client.name }}Configuration
|
|
34
35
|
_serialize: "Serializer"
|
|
35
36
|
_deserialize: "Deserializer"
|
|
37
|
+
{% endfor %}
|
|
36
38
|
{% endif %}
|
|
37
39
|
{% if code_model.has_abstract_operations %}
|
|
38
40
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
# --------------------------------------------------------------------------
|
|
7
7
|
"""The modelerfour reformatter autorest plugin.
|
|
8
8
|
"""
|
|
9
|
+
import re
|
|
9
10
|
import copy
|
|
10
11
|
import logging
|
|
11
12
|
from typing import Callable, Dict, Any, Iterable, List, Optional, Set
|
|
@@ -421,6 +422,10 @@ def update_client_url(yaml_data: Dict[str, Any]) -> str:
|
|
|
421
422
|
]["uri"]
|
|
422
423
|
|
|
423
424
|
|
|
425
|
+
def to_lower_camel_case(name: str) -> str:
|
|
426
|
+
return re.sub(r"_([a-z])", lambda x: x.group(1).upper(), name)
|
|
427
|
+
|
|
428
|
+
|
|
424
429
|
class M4Reformatter(
|
|
425
430
|
YamlUpdatePluginAutorest
|
|
426
431
|
): # pylint: disable=too-many-public-methods
|
|
@@ -554,6 +559,7 @@ class M4Reformatter(
|
|
|
554
559
|
operation["overloads"] = self.update_overloads(
|
|
555
560
|
group_name, yaml_data, body_parameter, content_types=content_types
|
|
556
561
|
)
|
|
562
|
+
operation["samples"] = yaml_data.get("extensions", {}).get("x-ms-examples", {})
|
|
557
563
|
return operation
|
|
558
564
|
|
|
559
565
|
def add_paging_information(
|
|
@@ -665,6 +671,9 @@ class M4Reformatter(
|
|
|
665
671
|
body_param["clientDefaultValue"] = body_type["value"]
|
|
666
672
|
body_param["flattened"] = flattened
|
|
667
673
|
body_param["isPartialBody"] = is_partial_body
|
|
674
|
+
body_param["restApiName"] = body_param["restApiName"] or to_lower_camel_case(
|
|
675
|
+
body_param["clientName"]
|
|
676
|
+
)
|
|
668
677
|
return body_param
|
|
669
678
|
|
|
670
679
|
def update_multipart_body_parameter(
|
|
@@ -1081,12 +1090,14 @@ class M4Reformatter(
|
|
|
1081
1090
|
"url": update_client_url(yaml_data)
|
|
1082
1091
|
if yaml_data.get("globalParameters")
|
|
1083
1092
|
else "",
|
|
1084
|
-
"namespace": self._autorestapi.get_value("namespace")
|
|
1085
|
-
or to_snake_case(yaml_data["info"]["title"].replace(" ", "")),
|
|
1086
1093
|
}
|
|
1087
1094
|
|
|
1088
1095
|
def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
|
|
1089
1096
|
"""Convert in place the YAML str."""
|
|
1097
|
+
# there can only be one namespace and client from swagger
|
|
1098
|
+
namespace = self._autorestapi.get_value("namespace") or to_snake_case(
|
|
1099
|
+
yaml_data["info"]["title"].replace(" ", "")
|
|
1100
|
+
)
|
|
1090
1101
|
# First we update the types, so we can access for when we're creating parameters etc.
|
|
1091
1102
|
for type_group, types in yaml_data["schemas"].items():
|
|
1092
1103
|
for t in types:
|
|
@@ -1097,8 +1108,10 @@ class M4Reformatter(
|
|
|
1097
1108
|
# we don't generate cloud error
|
|
1098
1109
|
continue
|
|
1099
1110
|
update_type(t)
|
|
1100
|
-
yaml_data["
|
|
1101
|
-
yaml_data["
|
|
1111
|
+
yaml_data["namespace"] = namespace
|
|
1112
|
+
yaml_data["subnamespaceToClients"] = {}
|
|
1113
|
+
yaml_data["clients"] = [self.update_client(yaml_data)]
|
|
1114
|
+
yaml_data["clients"][0]["operationGroups"] = [
|
|
1102
1115
|
self.update_operation_group(og) for og in yaml_data["operationGroups"]
|
|
1103
1116
|
]
|
|
1104
1117
|
yaml_data["types"] = list(ORIGINAL_ID_TO_UPDATED_TYPE.values()) + list(
|
|
@@ -1109,6 +1122,7 @@ class M4Reformatter(
|
|
|
1109
1122
|
del yaml_data["info"]
|
|
1110
1123
|
del yaml_data["language"]
|
|
1111
1124
|
del yaml_data["protocol"]
|
|
1125
|
+
del yaml_data["operationGroups"]
|
|
1112
1126
|
if yaml_data.get("schemas"):
|
|
1113
1127
|
del yaml_data["schemas"]
|
|
1114
1128
|
if yaml_data.get("security"):
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from enum import Enum
|
|
7
7
|
from typing import Dict, Optional, Set, Union, Tuple
|
|
8
|
+
from ..utils import convert_list_to_tuple
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class ImportType(str, Enum):
|
|
@@ -12,6 +13,7 @@ class ImportType(str, Enum):
|
|
|
12
13
|
THIRDPARTY = "thirdparty"
|
|
13
14
|
AZURECORE = "azurecore"
|
|
14
15
|
LOCAL = "local"
|
|
16
|
+
BYVERSION = "by_version"
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class TypingSection(str, Enum):
|
|
@@ -25,7 +27,28 @@ class FileImport:
|
|
|
25
27
|
self,
|
|
26
28
|
imports: Dict[
|
|
27
29
|
TypingSection,
|
|
28
|
-
Dict[
|
|
30
|
+
Dict[
|
|
31
|
+
ImportType,
|
|
32
|
+
Dict[
|
|
33
|
+
str,
|
|
34
|
+
Set[
|
|
35
|
+
Optional[
|
|
36
|
+
Union[
|
|
37
|
+
str,
|
|
38
|
+
Tuple[
|
|
39
|
+
str,
|
|
40
|
+
str,
|
|
41
|
+
],
|
|
42
|
+
Tuple[
|
|
43
|
+
str,
|
|
44
|
+
str,
|
|
45
|
+
Tuple[Tuple[Tuple[int, int], str, Optional[str]]],
|
|
46
|
+
],
|
|
47
|
+
]
|
|
48
|
+
]
|
|
49
|
+
],
|
|
50
|
+
],
|
|
51
|
+
],
|
|
29
52
|
] = None,
|
|
30
53
|
) -> None:
|
|
31
54
|
# Basic implementation
|
|
@@ -35,7 +58,28 @@ class FileImport:
|
|
|
35
58
|
# Fourth level set: None if this import is a "import", the name to import if it's a "from"
|
|
36
59
|
self._imports: Dict[
|
|
37
60
|
TypingSection,
|
|
38
|
-
Dict[
|
|
61
|
+
Dict[
|
|
62
|
+
ImportType,
|
|
63
|
+
Dict[
|
|
64
|
+
str,
|
|
65
|
+
Set[
|
|
66
|
+
Optional[
|
|
67
|
+
Union[
|
|
68
|
+
str,
|
|
69
|
+
Tuple[
|
|
70
|
+
str,
|
|
71
|
+
str,
|
|
72
|
+
],
|
|
73
|
+
Tuple[
|
|
74
|
+
str,
|
|
75
|
+
str,
|
|
76
|
+
Tuple[Tuple[Tuple[int, int], str, Optional[str]]],
|
|
77
|
+
],
|
|
78
|
+
]
|
|
79
|
+
]
|
|
80
|
+
],
|
|
81
|
+
],
|
|
82
|
+
],
|
|
39
83
|
] = (
|
|
40
84
|
imports or dict()
|
|
41
85
|
)
|
|
@@ -44,14 +88,29 @@ class FileImport:
|
|
|
44
88
|
self,
|
|
45
89
|
from_section: str,
|
|
46
90
|
import_type: ImportType,
|
|
47
|
-
name_import: Optional[
|
|
91
|
+
name_import: Optional[
|
|
92
|
+
Union[
|
|
93
|
+
str,
|
|
94
|
+
Tuple[
|
|
95
|
+
str,
|
|
96
|
+
str,
|
|
97
|
+
],
|
|
98
|
+
Tuple[str, str, Tuple[Tuple[Tuple[int, int], str, Optional[str]]]],
|
|
99
|
+
]
|
|
100
|
+
] = None,
|
|
48
101
|
typing_section: TypingSection = TypingSection.REGULAR,
|
|
49
102
|
) -> None:
|
|
50
|
-
name_input: Optional[
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
103
|
+
name_input: Optional[
|
|
104
|
+
Union[
|
|
105
|
+
str,
|
|
106
|
+
Tuple[
|
|
107
|
+
str,
|
|
108
|
+
str,
|
|
109
|
+
],
|
|
110
|
+
Tuple[str, str, Tuple[Tuple[Tuple[int, int], str, Optional[str]]]],
|
|
111
|
+
]
|
|
112
|
+
] = None
|
|
113
|
+
name_input = convert_list_to_tuple(name_import)
|
|
55
114
|
self._imports.setdefault(typing_section, dict()).setdefault(
|
|
56
115
|
import_type, dict()
|
|
57
116
|
).setdefault(from_section, set()).add(name_input)
|
|
@@ -66,21 +125,33 @@ class FileImport:
|
|
|
66
125
|
"""Add an import to this import block."""
|
|
67
126
|
self._add_import(from_section, import_type, name_import, typing_section)
|
|
68
127
|
|
|
69
|
-
def add_import(
|
|
70
|
-
self,
|
|
71
|
-
name_import: str,
|
|
72
|
-
import_type: ImportType,
|
|
73
|
-
typing_section: TypingSection = TypingSection.REGULAR,
|
|
74
|
-
) -> None:
|
|
75
|
-
# Implementation detail: a regular import is just a "from" with no from
|
|
76
|
-
self._add_import(name_import, import_type, None, typing_section)
|
|
77
|
-
|
|
78
128
|
@property
|
|
79
129
|
def imports(
|
|
80
130
|
self,
|
|
81
131
|
) -> Dict[
|
|
82
132
|
TypingSection,
|
|
83
|
-
Dict[
|
|
133
|
+
Dict[
|
|
134
|
+
ImportType,
|
|
135
|
+
Dict[
|
|
136
|
+
str,
|
|
137
|
+
Set[
|
|
138
|
+
Optional[
|
|
139
|
+
Union[
|
|
140
|
+
str,
|
|
141
|
+
Tuple[
|
|
142
|
+
str,
|
|
143
|
+
str,
|
|
144
|
+
],
|
|
145
|
+
Tuple[
|
|
146
|
+
str,
|
|
147
|
+
str,
|
|
148
|
+
Tuple[Tuple[Tuple[int, int], str, Optional[str]]],
|
|
149
|
+
],
|
|
150
|
+
]
|
|
151
|
+
]
|
|
152
|
+
],
|
|
153
|
+
],
|
|
154
|
+
],
|
|
84
155
|
]:
|
|
85
156
|
return self._imports
|
|
86
157
|
|
|
@@ -4,17 +4,43 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
from copy import deepcopy
|
|
7
|
-
from typing import Dict, Set, Optional, List
|
|
7
|
+
from typing import Dict, Set, Optional, List, Tuple, Union
|
|
8
8
|
from ..models import ImportType, FileImport, TypingSection
|
|
9
|
+
from ..utils import convert_list_to_tuple
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def _serialize_package(
|
|
12
|
-
package_name: str,
|
|
13
|
+
package_name: str,
|
|
14
|
+
module_list: Set[
|
|
15
|
+
Optional[
|
|
16
|
+
Union[
|
|
17
|
+
str,
|
|
18
|
+
Tuple[
|
|
19
|
+
str,
|
|
20
|
+
str,
|
|
21
|
+
],
|
|
22
|
+
Tuple[
|
|
23
|
+
str,
|
|
24
|
+
Optional[str],
|
|
25
|
+
Tuple[Tuple[Tuple[int, int], str, Optional[str]]],
|
|
26
|
+
],
|
|
27
|
+
]
|
|
28
|
+
]
|
|
29
|
+
],
|
|
30
|
+
delimiter: str,
|
|
13
31
|
) -> str:
|
|
14
32
|
buffer = []
|
|
15
|
-
|
|
33
|
+
|
|
34
|
+
versioned_modules = set()
|
|
35
|
+
normal_modules = set()
|
|
36
|
+
for m in module_list:
|
|
37
|
+
if m and isinstance(m, (tuple, list)) and len(m) > 2:
|
|
38
|
+
versioned_modules.add(convert_list_to_tuple(m))
|
|
39
|
+
else:
|
|
40
|
+
normal_modules.add(m)
|
|
41
|
+
if None in normal_modules:
|
|
16
42
|
buffer.append(f"import {package_name}")
|
|
17
|
-
if
|
|
43
|
+
if normal_modules != {None} and len(normal_modules) > 0:
|
|
18
44
|
buffer.append(
|
|
19
45
|
"from {} import {}".format(
|
|
20
46
|
package_name,
|
|
@@ -22,18 +48,51 @@ def _serialize_package(
|
|
|
22
48
|
sorted(
|
|
23
49
|
[
|
|
24
50
|
mod if isinstance(mod, str) else f"{mod[0]} as {mod[1]}"
|
|
25
|
-
for mod in
|
|
51
|
+
for mod in normal_modules
|
|
26
52
|
if mod is not None
|
|
27
53
|
]
|
|
28
54
|
)
|
|
29
55
|
),
|
|
30
56
|
)
|
|
31
57
|
)
|
|
58
|
+
for submodule_name, alias, version_modules in versioned_modules: # type: ignore
|
|
59
|
+
for n, (version, module_name, comment) in enumerate(version_modules):
|
|
60
|
+
buffer.append(
|
|
61
|
+
"{} sys.version_info >= {}:".format("if" if n == 0 else "elif", version)
|
|
62
|
+
)
|
|
63
|
+
buffer.append(
|
|
64
|
+
f" from {module_name} import {submodule_name}{f' as {alias}' if alias else ''}"
|
|
65
|
+
f"{f' # {comment}' if comment else ''}"
|
|
66
|
+
)
|
|
67
|
+
buffer.append("else:")
|
|
68
|
+
buffer.append(
|
|
69
|
+
f" from {package_name} import {submodule_name}{f' as {alias}' if alias else ''}"
|
|
70
|
+
" # type: ignore # pylint: disable=ungrouped-imports"
|
|
71
|
+
)
|
|
32
72
|
return delimiter.join(buffer)
|
|
33
73
|
|
|
34
74
|
|
|
35
75
|
def _serialize_type(
|
|
36
|
-
import_type_dict: Dict[
|
|
76
|
+
import_type_dict: Dict[
|
|
77
|
+
str,
|
|
78
|
+
Set[
|
|
79
|
+
Optional[
|
|
80
|
+
Union[
|
|
81
|
+
str,
|
|
82
|
+
Tuple[
|
|
83
|
+
str,
|
|
84
|
+
str,
|
|
85
|
+
],
|
|
86
|
+
Tuple[
|
|
87
|
+
str,
|
|
88
|
+
Optional[str],
|
|
89
|
+
Tuple[Tuple[Tuple[int, int], str, Optional[str]]],
|
|
90
|
+
],
|
|
91
|
+
]
|
|
92
|
+
]
|
|
93
|
+
],
|
|
94
|
+
],
|
|
95
|
+
delimiter: str,
|
|
37
96
|
) -> str:
|
|
38
97
|
"""Serialize a given import type."""
|
|
39
98
|
import_list = []
|
|
@@ -44,7 +103,29 @@ def _serialize_type(
|
|
|
44
103
|
|
|
45
104
|
|
|
46
105
|
def _get_import_clauses(
|
|
47
|
-
imports: Dict[
|
|
106
|
+
imports: Dict[
|
|
107
|
+
ImportType,
|
|
108
|
+
Dict[
|
|
109
|
+
str,
|
|
110
|
+
Set[
|
|
111
|
+
Optional[
|
|
112
|
+
Union[
|
|
113
|
+
str,
|
|
114
|
+
Tuple[
|
|
115
|
+
str,
|
|
116
|
+
str,
|
|
117
|
+
],
|
|
118
|
+
Tuple[
|
|
119
|
+
str,
|
|
120
|
+
Optional[str],
|
|
121
|
+
Tuple[Tuple[Tuple[int, int], str, Optional[str]]],
|
|
122
|
+
],
|
|
123
|
+
]
|
|
124
|
+
]
|
|
125
|
+
],
|
|
126
|
+
],
|
|
127
|
+
],
|
|
128
|
+
delimiter: str,
|
|
48
129
|
) -> List[str]:
|
|
49
130
|
import_clause = []
|
|
50
131
|
for import_type in ImportType:
|
|
@@ -47,3 +47,9 @@ def _get_default_api_version_from_list(
|
|
|
47
47
|
|
|
48
48
|
# If not preview mode, and there is preview, take the latest known stable
|
|
49
49
|
return sorted(not_preview_versions)[-1]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def convert_list_to_tuple(l):
|
|
53
|
+
if not isinstance(l, list):
|
|
54
|
+
return l
|
|
55
|
+
return tuple(convert_list_to_tuple(x) for x in l) if isinstance(l, list) else l
|
|
@@ -133,7 +133,7 @@ def update_operation_group_class_name(
|
|
|
133
133
|
yaml_data: Dict[str, Any], class_name: str
|
|
134
134
|
) -> str:
|
|
135
135
|
if class_name == "":
|
|
136
|
-
return yaml_data["
|
|
136
|
+
return yaml_data["name"] + "OperationsMixin"
|
|
137
137
|
if class_name == "Operations":
|
|
138
138
|
return "Operations"
|
|
139
139
|
return class_name + "Operations"
|
|
@@ -175,9 +175,13 @@ def update_client(yaml_data: Dict[str, Any]) -> None:
|
|
|
175
175
|
yaml_data["description"] = update_description(
|
|
176
176
|
yaml_data["description"], default_description=yaml_data["name"]
|
|
177
177
|
)
|
|
178
|
-
yaml_data["
|
|
178
|
+
yaml_data["legacyFilename"] = to_snake_case(yaml_data["name"].replace(" ", "_"))
|
|
179
179
|
for parameter in yaml_data["parameters"]:
|
|
180
180
|
update_parameter(parameter)
|
|
181
|
+
prop_name = yaml_data["name"]
|
|
182
|
+
if prop_name.endswith("Client"):
|
|
183
|
+
prop_name = prop_name[: len(prop_name) - len("Client")]
|
|
184
|
+
yaml_data["builderPadName"] = to_snake_case(prop_name)
|
|
181
185
|
|
|
182
186
|
|
|
183
187
|
def update_paging_response(yaml_data: Dict[str, Any]) -> None:
|
|
@@ -330,9 +334,12 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
330
334
|
for overload in yaml_data.get("overloads", []):
|
|
331
335
|
self.update_paging_operation(code_model, overload, is_overload=True)
|
|
332
336
|
|
|
333
|
-
def update_operation_groups(
|
|
334
|
-
|
|
337
|
+
def update_operation_groups(
|
|
338
|
+
self, code_model: Dict[str, Any], client: Dict[str, Any]
|
|
339
|
+
) -> None:
|
|
340
|
+
operation_groups_yaml_data = client["operationGroups"]
|
|
335
341
|
for operation_group in operation_groups_yaml_data:
|
|
342
|
+
operation_group["clientName"] = client["name"]
|
|
336
343
|
operation_group["propertyName"] = pad_reserved_words(
|
|
337
344
|
operation_group["propertyName"], PadType.OPERATION_GROUP
|
|
338
345
|
)
|
|
@@ -340,16 +347,21 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
|
|
|
340
347
|
operation_group["propertyName"]
|
|
341
348
|
)
|
|
342
349
|
operation_group["className"] = update_operation_group_class_name(
|
|
343
|
-
|
|
350
|
+
client, operation_group["className"]
|
|
344
351
|
)
|
|
345
352
|
for operation in operation_group["operations"]:
|
|
346
|
-
self.get_operation_updater(operation)(
|
|
353
|
+
self.get_operation_updater(operation)(code_model, operation)
|
|
347
354
|
|
|
348
355
|
def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
|
|
349
356
|
"""Convert in place the YAML str."""
|
|
350
|
-
update_client(yaml_data["client"])
|
|
351
|
-
self.update_operation_groups(yaml_data)
|
|
352
357
|
update_types(yaml_data["types"])
|
|
358
|
+
for client in yaml_data["clients"]:
|
|
359
|
+
update_client(client)
|
|
360
|
+
self.update_operation_groups(yaml_data, client)
|
|
361
|
+
for clients in yaml_data["subnamespaceToClients"].values():
|
|
362
|
+
for client in clients:
|
|
363
|
+
update_client(client)
|
|
364
|
+
self.update_operation_groups(yaml_data, client)
|
|
353
365
|
|
|
354
366
|
|
|
355
367
|
class PreProcessPluginAutorest(YamlUpdatePluginAutorest, PreProcessPlugin):
|
package/package.json
CHANGED
package/run_cadl.py
CHANGED
|
@@ -38,6 +38,5 @@ if __name__ == "__main__":
|
|
|
38
38
|
# run m2r
|
|
39
39
|
python_run(venv_context, "autorest.m2r.__init__", command=sys.argv[1:])
|
|
40
40
|
python_run(venv_context, "autorest.preprocess.__init__", command=sys.argv[1:])
|
|
41
|
-
python_run(venv_context, "autorest.cadlflags.__init__", command=sys.argv[1:])
|
|
42
41
|
python_run(venv_context, "autorest.codegen.__init__", command=sys.argv[1:])
|
|
43
42
|
python_run(venv_context, "autorest.black.__init__", command=sys.argv[1:])
|