@autorest/python 5.14.0 → 5.17.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.
Files changed (120) hide show
  1. package/ChangeLog.md +91 -2
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +2 -3
  4. package/autorest/black/__init__.py +12 -5
  5. package/autorest/codegen/__init__.py +130 -179
  6. package/autorest/codegen/models/__init__.py +122 -78
  7. package/autorest/codegen/models/base_builder.py +70 -72
  8. package/autorest/codegen/models/base_model.py +7 -5
  9. package/autorest/codegen/models/{base_schema.py → base_type.py} +62 -49
  10. package/autorest/codegen/models/client.py +195 -36
  11. package/autorest/codegen/models/code_model.py +165 -299
  12. package/autorest/codegen/models/combined_type.py +107 -0
  13. package/autorest/codegen/models/constant_type.py +122 -0
  14. package/autorest/codegen/models/credential_types.py +224 -0
  15. package/autorest/codegen/models/dictionary_type.py +116 -0
  16. package/autorest/codegen/models/enum_type.py +195 -0
  17. package/autorest/codegen/models/imports.py +95 -41
  18. package/autorest/codegen/models/list_type.py +134 -0
  19. package/autorest/codegen/models/lro_operation.py +90 -133
  20. package/autorest/codegen/models/lro_paging_operation.py +28 -12
  21. package/autorest/codegen/models/model_type.py +239 -0
  22. package/autorest/codegen/models/operation.py +415 -241
  23. package/autorest/codegen/models/operation_group.py +82 -88
  24. package/autorest/codegen/models/paging_operation.py +101 -117
  25. package/autorest/codegen/models/parameter.py +307 -322
  26. package/autorest/codegen/models/parameter_list.py +366 -357
  27. package/autorest/codegen/models/primitive_types.py +544 -0
  28. package/autorest/codegen/models/property.py +122 -134
  29. package/autorest/codegen/models/request_builder.py +138 -86
  30. package/autorest/codegen/models/request_builder_parameter.py +122 -79
  31. package/autorest/codegen/models/response.py +325 -0
  32. package/autorest/codegen/models/utils.py +17 -1
  33. package/autorest/codegen/serializers/__init__.py +242 -118
  34. package/autorest/codegen/serializers/builder_serializer.py +863 -1027
  35. package/autorest/codegen/serializers/client_serializer.py +148 -82
  36. package/autorest/codegen/serializers/general_serializer.py +44 -47
  37. package/autorest/codegen/serializers/import_serializer.py +96 -31
  38. package/autorest/codegen/serializers/metadata_serializer.py +39 -79
  39. package/autorest/codegen/serializers/model_base_serializer.py +65 -29
  40. package/autorest/codegen/serializers/model_generic_serializer.py +9 -10
  41. package/autorest/codegen/serializers/model_init_serializer.py +4 -2
  42. package/autorest/codegen/serializers/model_python3_serializer.py +29 -22
  43. package/autorest/codegen/serializers/operation_groups_serializer.py +21 -18
  44. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  45. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  46. package/autorest/codegen/serializers/patch_serializer.py +14 -2
  47. package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
  48. package/autorest/codegen/serializers/utils.py +0 -103
  49. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  50. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +7 -7
  51. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  52. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  53. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -2
  54. package/autorest/codegen/templates/init.py.jinja2 +9 -6
  55. package/autorest/codegen/templates/keywords.jinja2 +14 -1
  56. package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
  57. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
  58. package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
  59. package/autorest/codegen/templates/model.py.jinja2 +23 -29
  60. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  61. package/autorest/codegen/templates/model_init.py.jinja2 +9 -8
  62. package/autorest/codegen/templates/operation.py.jinja2 +10 -15
  63. package/autorest/codegen/templates/operation_group.py.jinja2 +14 -13
  64. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -2
  65. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  66. package/autorest/codegen/templates/operations_folder_init.py.jinja2 +4 -0
  67. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  68. package/autorest/codegen/templates/patch.py.jinja2 +18 -29
  69. package/autorest/codegen/templates/request_builder.py.jinja2 +20 -13
  70. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  71. package/autorest/codegen/templates/vendor.py.jinja2 +12 -2
  72. package/autorest/jsonrpc/__init__.py +7 -12
  73. package/autorest/jsonrpc/localapi.py +4 -3
  74. package/autorest/jsonrpc/server.py +28 -9
  75. package/autorest/jsonrpc/stdstream.py +13 -6
  76. package/autorest/m2r/__init__.py +5 -8
  77. package/autorest/m4reformatter/__init__.py +1108 -0
  78. package/autorest/multiapi/__init__.py +24 -14
  79. package/autorest/multiapi/models/client.py +21 -11
  80. package/autorest/multiapi/models/code_model.py +23 -10
  81. package/autorest/multiapi/models/config.py +4 -1
  82. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  83. package/autorest/multiapi/models/global_parameter.py +2 -1
  84. package/autorest/multiapi/models/global_parameters.py +14 -8
  85. package/autorest/multiapi/models/imports.py +35 -18
  86. package/autorest/multiapi/models/mixin_operation.py +5 -5
  87. package/autorest/multiapi/models/operation_group.py +2 -1
  88. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  89. package/autorest/multiapi/serializers/__init__.py +20 -25
  90. package/autorest/multiapi/serializers/import_serializer.py +47 -15
  91. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  92. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  93. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  94. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  95. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  96. package/autorest/multiapi/utils.py +3 -3
  97. package/autorest/postprocess/__init__.py +202 -0
  98. package/autorest/postprocess/get_all.py +19 -0
  99. package/autorest/postprocess/venvtools.py +73 -0
  100. package/autorest/preprocess/__init__.py +209 -0
  101. package/autorest/preprocess/helpers.py +54 -0
  102. package/autorest/{namer → preprocess}/python_mappings.py +25 -32
  103. package/package.json +3 -3
  104. package/run-python3.js +2 -3
  105. package/venvtools.py +1 -1
  106. package/autorest/codegen/models/constant_schema.py +0 -97
  107. package/autorest/codegen/models/credential_schema.py +0 -90
  108. package/autorest/codegen/models/credential_schema_policy.py +0 -77
  109. package/autorest/codegen/models/dictionary_schema.py +0 -103
  110. package/autorest/codegen/models/enum_schema.py +0 -246
  111. package/autorest/codegen/models/list_schema.py +0 -113
  112. package/autorest/codegen/models/object_schema.py +0 -249
  113. package/autorest/codegen/models/primitive_schemas.py +0 -476
  114. package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
  115. package/autorest/codegen/models/rest.py +0 -42
  116. package/autorest/codegen/models/schema_request.py +0 -45
  117. package/autorest/codegen/models/schema_response.py +0 -123
  118. package/autorest/codegen/serializers/rest_serializer.py +0 -57
  119. package/autorest/namer/__init__.py +0 -25
  120. package/autorest/namer/name_converter.py +0 -412
@@ -3,102 +3,145 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
- from typing import Any, Dict, List, Optional
7
- from .parameter import ParameterOnlyPathAndBodyPositional, ParameterLocation, ParameterStyle
6
+ from typing import TYPE_CHECKING, Any, Dict, Union
7
+ from .parameter import (
8
+ ParameterLocation,
9
+ ParameterMethodLocation,
10
+ Parameter,
11
+ BodyParameter,
12
+ _MultipartBodyParameter,
13
+ )
14
+ from .base_type import BaseType
15
+ from .primitive_types import BinaryType, StringType
16
+ from .combined_type import CombinedType
8
17
 
9
- def _make_public(name):
10
- if name[0] == "_":
11
- return name[1:]
12
- return name
18
+ if TYPE_CHECKING:
19
+ from .code_model import CodeModel
13
20
 
14
- class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
21
+
22
+ class RequestBuilderBodyParameter(BodyParameter):
23
+ """BOdy parmaeter for RequestBuilders"""
24
+
25
+ def __init__(self, *args, **kwargs) -> None:
26
+ super().__init__(*args, **kwargs)
27
+ if isinstance(self.type, (BinaryType, StringType)) or any(
28
+ "xml" in ct for ct in self.content_types
29
+ ):
30
+ self.client_name = "content"
31
+ else:
32
+ self.client_name = "json"
33
+
34
+ def type_annotation(self, **kwargs: Any) -> str:
35
+ if self.type.is_xml:
36
+ return "Any" # xml type technically not in type signature for HttpRequest content param
37
+ return super().type_annotation(**kwargs)
15
38
 
16
39
  @property
17
40
  def in_method_signature(self) -> bool:
18
- return not(
19
- # don't put accept in method signature
20
- self.rest_api_name == "Accept"
21
- # If i'm not in the method code, no point in being in signature
22
- or not self.in_method_code
23
- # If I'm a flattened property of a body, don't want me, want the body param
24
- or self.target_property_name
25
- or not self.in_method_code
26
- )
41
+ return super().in_method_signature and not self.is_partial_body
27
42
 
28
43
  @property
29
- def name_in_high_level_operation(self) -> str:
30
- template = "{}" if self.code_model.options["version_tolerant"] else "_{}"
31
- if self.is_multipart:
32
- return template.format("files")
33
- if self.is_data_input:
34
- return template.format("data")
35
- if self.is_body and not self.constant:
36
- return f"_{self.serialized_name}"
37
- name = self.yaml_data["language"]["python"]["name"]
38
- if self.implementation == "Client" and self.in_method_code:
39
- # for these, we're passing the client params to the request builder.
40
- # Need the self._config prefix
41
- name = f"self._config.{name}"
42
- return name
44
+ def method_location(self) -> ParameterMethodLocation:
45
+ return (
46
+ ParameterMethodLocation.KWARG
47
+ if (self.constant or isinstance(self.type, CombinedType))
48
+ else ParameterMethodLocation.KEYWORD_ONLY
49
+ )
43
50
 
44
- @property
45
- def in_method_code(self) -> bool:
46
- if self.location == ParameterLocation.Uri:
47
- # don't want any base url path formatting arguments
48
- return False
49
- return super(RequestBuilderParameter, self).in_method_code
51
+ @classmethod
52
+ def from_yaml(
53
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
54
+ ) -> "RequestBuilderBodyParameter":
55
+ return super().from_yaml(yaml_data, code_model) # type: ignore
50
56
 
51
57
  @property
52
- def default_value_declaration(self) -> Optional[str]:
53
- if self.serialized_name == "content_type":
54
- # in request builders we're in a weird scenario
55
- # we need to know what the types of content_type are
56
- # but we want to serialize content_type with no default.
57
- # So, we just return None in default_value_declaration for now
58
- return "None"
59
- return super().default_value_declaration
58
+ def name_in_high_level_operation(self) -> str:
59
+ if self.client_name == "json":
60
+ return "_json"
61
+ return "_content"
60
62
 
61
- @property
62
- def is_keyword_only(self) -> bool:
63
- return not self.location == ParameterLocation.Path and not self.is_kwarg
64
63
 
65
- @is_keyword_only.setter
66
- def is_keyword_only(self, val: bool) -> None:
67
- self._keyword_only = val
68
- self.is_kwarg = False
64
+ class RequestBuilderMultipartBodyParameter(
65
+ _MultipartBodyParameter[ # pylint: disable=unsubscriptable-object
66
+ RequestBuilderBodyParameter
67
+ ]
68
+ ):
69
+ """Multipart body parameter for Request BUilders"""
69
70
 
70
71
  @property
71
- def full_serialized_name(self) -> str:
72
- return self.serialized_name
72
+ def name_in_high_level_operation(self) -> str:
73
+ return f"_{self.client_name}"
73
74
 
74
75
  @classmethod
75
76
  def from_yaml(
76
- cls, yaml_data: Dict[str, Any], *, code_model, content_types: Optional[List[str]] = None
77
- ) -> "RequestBuilderParameter":
78
- http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
79
- name = yaml_data["language"]["python"]["name"]
80
- location = ParameterLocation(http_protocol["in"])
77
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
78
+ ) -> "RequestBuilderMultipartBodyParameter":
81
79
  return cls(
82
- code_model=code_model,
83
80
  yaml_data=yaml_data,
84
- schema=yaml_data.get("schema", None), # FIXME replace by operation model
85
- # See also https://github.com/Azure/autorest.modelerfour/issues/80
86
- rest_api_name=yaml_data["language"]["default"].get(
87
- "serializedName", yaml_data["language"]["default"]["name"]
88
- ),
89
- serialized_name=_make_public(name),
90
- description=yaml_data["language"]["python"]["description"],
91
- implementation=yaml_data["implementation"],
92
- required=yaml_data.get("required", False),
93
- location=location,
94
- skip_url_encoding=yaml_data.get("extensions", {}).get("x-ms-skip-url-encoding", False),
95
- constraints=[], # FIXME constraints
96
- target_property_name=id(yaml_data["targetProperty"]) if yaml_data.get("targetProperty") else None,
97
- style=ParameterStyle(http_protocol["style"]) if "style" in http_protocol else None,
98
- explode=http_protocol.get("explode", False),
99
- grouped_by=yaml_data.get("groupedBy", None),
100
- original_parameter=yaml_data.get("originalParameter", None),
101
- flattened=yaml_data.get("flattened", False),
102
- client_default_value=yaml_data.get("clientDefaultValue"),
103
- content_types=content_types,
81
+ code_model=code_model,
82
+ type=code_model.lookup_type(id(yaml_data["type"])),
83
+ entries=[
84
+ RequestBuilderBodyParameter.from_yaml(entry, code_model)
85
+ for entry in yaml_data["entries"]
86
+ ],
87
+ )
88
+
89
+
90
+ class RequestBuilderParameter(Parameter):
91
+ """Basic RequestBuilder Parameter."""
92
+
93
+ def __init__(
94
+ self, yaml_data: Dict[str, Any], code_model: "CodeModel", type: BaseType
95
+ ) -> None:
96
+ super().__init__(yaml_data, code_model, type)
97
+ # we don't want any default content type behavior in request builder
98
+ if self.rest_api_name == "Content-Type":
99
+ self.client_default_value = None
100
+ if self.grouped_by and self.client_name[0] == "_":
101
+ # we don't want hidden parameters for grouped by in request builders
102
+ self.client_name = self.client_name[1:]
103
+
104
+ @property
105
+ def in_method_signature(self) -> bool:
106
+ if self.grouped_by and not self.in_flattened_body:
107
+ return True
108
+ return super().in_method_signature and not (
109
+ self.location == ParameterLocation.ENDPOINT_PATH
110
+ or self.in_flattened_body
111
+ or self.grouper
104
112
  )
113
+
114
+ @property
115
+ def full_client_name(self) -> str:
116
+ return self.client_name
117
+
118
+ @property
119
+ def method_location(self) -> ParameterMethodLocation:
120
+ super_method_location = super().method_location
121
+ if super_method_location == ParameterMethodLocation.KWARG:
122
+ return super_method_location
123
+ if (
124
+ self.in_overriden
125
+ and super_method_location == ParameterMethodLocation.KEYWORD_ONLY
126
+ ):
127
+ return ParameterMethodLocation.KWARG
128
+ if self.location != ParameterLocation.PATH:
129
+ return ParameterMethodLocation.KEYWORD_ONLY
130
+ return super_method_location
131
+
132
+ @property
133
+ def name_in_high_level_operation(self) -> str:
134
+ if self.grouped_by:
135
+ return f"_{self.client_name}"
136
+ if self.implementation == "Client":
137
+ return f"self._config.{self.client_name}"
138
+ return self.client_name
139
+
140
+
141
+ def get_request_body_parameter(
142
+ yaml_data: Dict[str, Any], code_model: "CodeModel"
143
+ ) -> Union[RequestBuilderBodyParameter, RequestBuilderMultipartBodyParameter]:
144
+ """Get body parameter for a request builder"""
145
+ if yaml_data.get("entries"):
146
+ return RequestBuilderMultipartBodyParameter.from_yaml(yaml_data, code_model)
147
+ return RequestBuilderBodyParameter.from_yaml(yaml_data, code_model)
@@ -0,0 +1,325 @@
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 Dict, Optional, List, Any, TYPE_CHECKING, Union
7
+
8
+ from .base_model import BaseModel
9
+ from .base_type import BaseType
10
+ from .imports import FileImport, ImportType
11
+ from .primitive_types import BinaryType, BinaryIteratorType
12
+ from .dictionary_type import DictionaryType
13
+ from .list_type import ListType
14
+ from .model_type import ModelType
15
+
16
+ if TYPE_CHECKING:
17
+ from .code_model import CodeModel
18
+
19
+
20
+ class ResponseHeader(BaseModel):
21
+ def __init__(
22
+ self, yaml_data: Dict[str, Any], code_model: "CodeModel", type: BaseType
23
+ ) -> None:
24
+ super().__init__(yaml_data, code_model)
25
+ self.rest_api_name: str = yaml_data["restApiName"]
26
+ self.type = type
27
+
28
+ @property
29
+ def serialization_type(self) -> str:
30
+ return self.type.serialization_type
31
+
32
+ @classmethod
33
+ def from_yaml(
34
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
35
+ ) -> "ResponseHeader":
36
+ return cls(
37
+ yaml_data=yaml_data,
38
+ code_model=code_model,
39
+ type=code_model.lookup_type(id(yaml_data["type"])),
40
+ )
41
+
42
+
43
+ class Response(BaseModel):
44
+ def __init__(
45
+ self,
46
+ yaml_data: Dict[str, Any],
47
+ code_model: "CodeModel",
48
+ *,
49
+ headers: List[ResponseHeader] = [],
50
+ type: Optional[BaseType] = None,
51
+ ) -> None:
52
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
53
+ self.status_codes: List[Union[int, str]] = yaml_data["statusCodes"]
54
+ self.headers = headers
55
+ self.type = type
56
+ self.nullable = yaml_data.get("nullable")
57
+
58
+ def get_json_template_representation(self) -> Any:
59
+ if not self.type:
60
+ return None
61
+ if not isinstance(self.type, (DictionaryType, ListType, ModelType)):
62
+ return None
63
+ return self.type.get_json_template_representation()
64
+
65
+ @property
66
+ def is_stream_response(self) -> bool:
67
+ """Is the response expected to be streamable, like a download."""
68
+ return isinstance(self.type, BinaryIteratorType)
69
+
70
+ @property
71
+ def serialization_type(self) -> str:
72
+ if self.type:
73
+ return self.type.serialization_type
74
+ return "None"
75
+
76
+ def type_annotation(self, **kwargs: Any) -> str:
77
+ if self.type:
78
+ kwargs["is_operation_file"] = True
79
+ type_annot = self.type.type_annotation(**kwargs)
80
+ if self.nullable:
81
+ return f"Optional[{type_annot}]"
82
+ return type_annot
83
+ return "None"
84
+
85
+ def docstring_text(self, **kwargs: Any) -> str:
86
+ if self.nullable and self.type:
87
+ return f"{self.type.docstring_text(**kwargs)} or None"
88
+ return self.type.docstring_text(**kwargs) if self.type else "None"
89
+
90
+ def docstring_type(self, **kwargs: Any) -> str:
91
+ if self.nullable and self.type:
92
+ return f"{self.type.docstring_type(**kwargs)} or None"
93
+ return self.type.docstring_type(**kwargs) if self.type else "None"
94
+
95
+ def _imports_shared(self, **kwargs: Any) -> FileImport:
96
+ file_import = FileImport()
97
+ if self.type:
98
+ file_import.merge(self.type.imports(is_operation_file=True, **kwargs))
99
+ if self.nullable:
100
+ file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
101
+ return file_import
102
+
103
+ def imports(self, **kwargs: Any) -> FileImport:
104
+ return self._imports_shared(**kwargs)
105
+
106
+ def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
107
+ return self._imports_shared(**kwargs)
108
+
109
+ @classmethod
110
+ def from_yaml(
111
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
112
+ ) -> "Response":
113
+ type = (
114
+ code_model.lookup_type(id(yaml_data["type"]))
115
+ if yaml_data.get("type")
116
+ else None
117
+ )
118
+ # use ByteIteratorType if we are returning a binary type
119
+ if isinstance(type, BinaryType):
120
+ type = BinaryIteratorType(type.yaml_data, type.code_model)
121
+ return cls(
122
+ yaml_data=yaml_data,
123
+ code_model=code_model,
124
+ headers=[
125
+ ResponseHeader.from_yaml(header, code_model)
126
+ for header in yaml_data["headers"]
127
+ ],
128
+ type=type,
129
+ )
130
+
131
+ def __repr__(self) -> str:
132
+ return f"<{self.__class__.__name__} {self.status_codes}>"
133
+
134
+
135
+ class PagingResponse(Response):
136
+ def __init__(self, *args, **kwargs) -> None:
137
+ super().__init__(*args, **kwargs)
138
+ self.item_type = self.code_model.lookup_type(id(self.yaml_data["itemType"]))
139
+
140
+ def get_json_template_representation(self) -> Any:
141
+ return self.item_type.get_json_template_representation()
142
+
143
+ def get_pager_path(self, async_mode: bool) -> str:
144
+ return (
145
+ self.yaml_data["pagerAsync"] if async_mode else self.yaml_data["pagerSync"]
146
+ )
147
+
148
+ def get_pager(self, async_mode: bool) -> str:
149
+ return self.get_pager_path(async_mode).split(".")[-1]
150
+
151
+ def type_annotation(self, **kwargs: Any) -> str:
152
+ iterable = "AsyncIterable" if kwargs["async_mode"] else "Iterable"
153
+ return f"{iterable}[{self.item_type.type_annotation(**kwargs)}]"
154
+
155
+ def docstring_text(self, **kwargs: Any) -> str:
156
+ base_description = "An iterator like instance of "
157
+ if not self.code_model.options["version_tolerant"]:
158
+ base_description += "either "
159
+ return base_description + self.item_type.docstring_text(**kwargs)
160
+
161
+ def docstring_type(self, **kwargs: Any) -> str:
162
+ return f"~{self.get_pager_path(kwargs['async_mode'])}[{self.item_type.docstring_type(**kwargs)}]"
163
+
164
+ def _imports_shared(self, **kwargs: Any) -> FileImport:
165
+ file_import = super()._imports_shared(**kwargs)
166
+ async_mode = kwargs.pop("async_mode")
167
+ pager_import_path = ".".join(self.get_pager_path(async_mode).split(".")[:-1])
168
+ pager = self.get_pager(async_mode)
169
+
170
+ file_import.add_submodule_import(pager_import_path, pager, ImportType.AZURECORE)
171
+ return file_import
172
+
173
+ def imports(self, **kwargs: Any) -> FileImport:
174
+ file_import = self._imports_shared(**kwargs)
175
+ async_mode = kwargs.pop("async_mode")
176
+ if async_mode:
177
+ file_import.add_submodule_import(
178
+ "azure.core.async_paging", "AsyncList", ImportType.AZURECORE
179
+ )
180
+
181
+ return file_import
182
+
183
+ def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
184
+ return self._imports_shared(**kwargs)
185
+
186
+
187
+ class LROResponse(Response):
188
+ def get_poller_path(self, async_mode: bool) -> str:
189
+ return (
190
+ self.yaml_data["pollerAsync"]
191
+ if async_mode
192
+ else self.yaml_data["pollerSync"]
193
+ )
194
+
195
+ def get_poller(self, async_mode: bool) -> str:
196
+ """Get the name of the poller. Default is LROPoller / AsyncLROPoller"""
197
+ return self.get_poller_path(async_mode).split(".")[-1]
198
+
199
+ def get_polling_method_path(self, async_mode: bool) -> str:
200
+ """Get the full name of the poller path. Default are the azure core pollers"""
201
+ return (
202
+ self.yaml_data["pollingMethodAsync"]
203
+ if async_mode
204
+ else self.yaml_data["pollingMethodSync"]
205
+ )
206
+
207
+ def get_polling_method(self, async_mode: bool) -> str:
208
+ """Get the default pollint method"""
209
+ return self.get_polling_method_path(async_mode).split(".")[-1]
210
+
211
+ @staticmethod
212
+ def get_no_polling_method_path(async_mode: bool) -> str:
213
+ """Get the path of the default of no polling method"""
214
+ return f"azure.core.polling.{'Async' if async_mode else ''}NoPolling"
215
+
216
+ def get_no_polling_method(self, async_mode: bool) -> str:
217
+ """Get the default no polling method"""
218
+ return self.get_no_polling_method_path(async_mode).split(".")[-1]
219
+
220
+ @staticmethod
221
+ def get_base_polling_method_path(async_mode: bool) -> str:
222
+ """Get the base polling method path. Used in docstrings and type annotations."""
223
+ return f"azure.core.polling.{'Async' if async_mode else ''}PollingMethod"
224
+
225
+ def get_base_polling_method(self, async_mode: bool) -> str:
226
+ """Get the base polling method."""
227
+ return self.get_base_polling_method_path(async_mode).split(".")[-1]
228
+
229
+ def type_annotation(self, **kwargs: Any) -> str:
230
+ return f"{self.get_poller(kwargs.pop('async_mode'))}[{super().type_annotation(**kwargs)}]"
231
+
232
+ def docstring_type(self, **kwargs: Any) -> str:
233
+ return f"~{self.get_poller_path(kwargs.pop('async_mode'))}[{super().docstring_type(**kwargs)}]"
234
+
235
+ def docstring_text(self, **kwargs) -> str:
236
+ super_text = super().docstring_text(**kwargs)
237
+ base_description = (
238
+ f"An instance of {self.get_poller(kwargs.pop('async_mode'))} that returns "
239
+ )
240
+ if not self.code_model.options["version_tolerant"]:
241
+ base_description += "either "
242
+ return base_description + super_text
243
+
244
+ def _imports_shared(self, **kwargs: Any) -> FileImport:
245
+ file_import = super()._imports_shared(**kwargs)
246
+ async_mode = kwargs["async_mode"]
247
+ poller_import_path = ".".join(self.get_poller_path(async_mode).split(".")[:-1])
248
+ poller = self.get_poller(async_mode)
249
+ file_import.add_submodule_import(
250
+ poller_import_path, poller, ImportType.AZURECORE
251
+ )
252
+ return file_import
253
+
254
+ def imports(self, **kwargs: Any) -> FileImport:
255
+ file_import = self._imports_shared(**kwargs)
256
+ async_mode = kwargs["async_mode"]
257
+
258
+ default_polling_method_import_path = ".".join(
259
+ self.get_polling_method_path(async_mode).split(".")[:-1]
260
+ )
261
+ default_polling_method = self.get_polling_method(async_mode)
262
+ file_import.add_submodule_import(
263
+ default_polling_method_import_path,
264
+ default_polling_method,
265
+ ImportType.AZURECORE,
266
+ )
267
+ default_no_polling_method_import_path = ".".join(
268
+ self.get_no_polling_method_path(async_mode).split(".")[:-1]
269
+ )
270
+ default_no_polling_method = self.get_no_polling_method(async_mode)
271
+ file_import.add_submodule_import(
272
+ default_no_polling_method_import_path,
273
+ default_no_polling_method,
274
+ ImportType.AZURECORE,
275
+ )
276
+
277
+ base_polling_method_import_path = ".".join(
278
+ self.get_base_polling_method_path(async_mode).split(".")[:-1]
279
+ )
280
+ base_polling_method = self.get_base_polling_method(async_mode)
281
+ file_import.add_submodule_import(
282
+ base_polling_method_import_path, base_polling_method, ImportType.AZURECORE
283
+ )
284
+ return file_import
285
+
286
+ def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
287
+ return self._imports_shared(**kwargs)
288
+
289
+
290
+ class LROPagingResponse(LROResponse, PagingResponse):
291
+ def type_annotation(self, **kwargs: Any) -> str:
292
+ paging_type_annotation = PagingResponse.type_annotation(self, **kwargs)
293
+ return f"{self.get_poller(kwargs.pop('async_mode'))}[{paging_type_annotation}]"
294
+
295
+ def docstring_type(self, **kwargs: Any) -> str:
296
+ paging_docstring_type = PagingResponse.docstring_type(self, **kwargs)
297
+ return f"~{self.get_poller_path(kwargs.pop('async_mode'))}[{paging_docstring_type}]"
298
+
299
+ def docstring_text(self, **kwargs) -> str:
300
+ base_description = (
301
+ "An instance of LROPoller that returns an iterator like instance of "
302
+ )
303
+ if not self.code_model.options["version_tolerant"]:
304
+ base_description += "either "
305
+ return base_description + Response.docstring_text(self)
306
+
307
+ def imports_for_multiapi(self, **kwargs: Any) -> FileImport:
308
+ file_import = LROResponse.imports_for_multiapi(self, **kwargs)
309
+ file_import.merge(PagingResponse.imports_for_multiapi(self, **kwargs))
310
+ return file_import
311
+
312
+ def imports(self, **kwargs: Any) -> FileImport:
313
+ file_import = LROResponse.imports(self, **kwargs)
314
+ file_import.merge(PagingResponse.imports(self, **kwargs))
315
+ return file_import
316
+
317
+
318
+ def get_response(yaml_data: Dict[str, Any], code_model: "CodeModel") -> Response:
319
+ if yaml_data["discriminator"] == "lropaging":
320
+ return LROPagingResponse.from_yaml(yaml_data, code_model)
321
+ if yaml_data["discriminator"] == "lro":
322
+ return LROResponse.from_yaml(yaml_data, code_model)
323
+ if yaml_data["discriminator"] == "paging":
324
+ return PagingResponse.from_yaml(yaml_data, code_model)
325
+ return Response.from_yaml(yaml_data, code_model)
@@ -4,5 +4,21 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  import re
7
+ from typing import TypeVar, Dict
7
8
 
8
- JSON_REGEXP = re.compile(r'^(application|text)/(.+\+)?json$')
9
+ JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
10
+
11
+ T = TypeVar("T")
12
+ OrderedSet = Dict[T, None]
13
+
14
+
15
+ def add_to_description(description: str, entry: str) -> str:
16
+ if description:
17
+ return f"{description} {entry}"
18
+ return entry
19
+
20
+
21
+ def add_to_pylint_disable(curr_str: str, entry: str) -> str:
22
+ if curr_str:
23
+ return f"{curr_str},{entry}"
24
+ return f" # pylint: disable={entry}"