@autorest/python 5.15.0 → 5.18.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 (118) hide show
  1. package/ChangeLog.md +98 -4
  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 +122 -211
  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} +68 -45
  10. package/autorest/codegen/models/client.py +193 -40
  11. package/autorest/codegen/models/code_model.py +145 -245
  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 +131 -0
  16. package/autorest/codegen/models/enum_type.py +195 -0
  17. package/autorest/codegen/models/imports.py +93 -41
  18. package/autorest/codegen/models/list_type.py +149 -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 +262 -0
  22. package/autorest/codegen/models/operation.py +412 -259
  23. package/autorest/codegen/models/operation_group.py +80 -91
  24. package/autorest/codegen/models/paging_operation.py +101 -117
  25. package/autorest/codegen/models/parameter.py +302 -341
  26. package/autorest/codegen/models/parameter_list.py +373 -357
  27. package/autorest/codegen/models/primitive_types.py +544 -0
  28. package/autorest/codegen/models/property.py +136 -134
  29. package/autorest/codegen/models/request_builder.py +138 -86
  30. package/autorest/codegen/models/request_builder_parameter.py +122 -86
  31. package/autorest/codegen/models/response.py +325 -0
  32. package/autorest/codegen/models/utils.py +13 -17
  33. package/autorest/codegen/serializers/__init__.py +212 -112
  34. package/autorest/codegen/serializers/builder_serializer.py +931 -1040
  35. package/autorest/codegen/serializers/client_serializer.py +140 -84
  36. package/autorest/codegen/serializers/general_serializer.py +26 -50
  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 +62 -34
  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 -19
  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 +4 -1
  47. package/autorest/codegen/serializers/request_builders_serializer.py +57 -0
  48. package/autorest/codegen/serializers/utils.py +0 -126
  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 -1
  54. package/autorest/codegen/templates/init.py.jinja2 +3 -3
  55. package/autorest/codegen/templates/lro_operation.py.jinja2 +6 -5
  56. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +6 -5
  57. package/autorest/codegen/templates/metadata.json.jinja2 +36 -35
  58. package/autorest/codegen/templates/model.py.jinja2 +23 -24
  59. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  60. package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
  61. package/autorest/codegen/templates/operation.py.jinja2 +10 -14
  62. package/autorest/codegen/templates/operation_group.py.jinja2 +9 -15
  63. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  64. package/autorest/codegen/templates/operation_tools.jinja2 +8 -2
  65. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  66. package/autorest/codegen/templates/request_builder.py.jinja2 +19 -10
  67. package/autorest/codegen/templates/setup.py.jinja2 +9 -3
  68. package/autorest/codegen/templates/vendor.py.jinja2 +1 -1
  69. package/autorest/jsonrpc/__init__.py +7 -12
  70. package/autorest/jsonrpc/localapi.py +4 -3
  71. package/autorest/jsonrpc/server.py +28 -9
  72. package/autorest/jsonrpc/stdstream.py +13 -6
  73. package/autorest/m2r/__init__.py +5 -8
  74. package/autorest/m4reformatter/__init__.py +1126 -0
  75. package/autorest/multiapi/__init__.py +24 -14
  76. package/autorest/multiapi/models/client.py +21 -11
  77. package/autorest/multiapi/models/code_model.py +23 -10
  78. package/autorest/multiapi/models/config.py +4 -1
  79. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  80. package/autorest/multiapi/models/global_parameter.py +2 -1
  81. package/autorest/multiapi/models/global_parameters.py +14 -8
  82. package/autorest/multiapi/models/imports.py +24 -17
  83. package/autorest/multiapi/models/mixin_operation.py +5 -5
  84. package/autorest/multiapi/models/operation_group.py +2 -1
  85. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  86. package/autorest/multiapi/serializers/__init__.py +20 -25
  87. package/autorest/multiapi/serializers/import_serializer.py +47 -17
  88. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  89. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  90. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  91. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  92. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  93. package/autorest/multiapi/utils.py +3 -3
  94. package/autorest/postprocess/__init__.py +202 -0
  95. package/autorest/postprocess/get_all.py +19 -0
  96. package/autorest/postprocess/venvtools.py +73 -0
  97. package/autorest/preprocess/__init__.py +210 -0
  98. package/autorest/preprocess/helpers.py +54 -0
  99. package/autorest/{namer → preprocess}/python_mappings.py +25 -32
  100. package/package.json +3 -3
  101. package/run-python3.js +2 -3
  102. package/venvtools.py +1 -1
  103. package/autorest/codegen/models/constant_schema.py +0 -101
  104. package/autorest/codegen/models/credential_model.py +0 -47
  105. package/autorest/codegen/models/credential_schema.py +0 -91
  106. package/autorest/codegen/models/credential_schema_policy.py +0 -77
  107. package/autorest/codegen/models/dictionary_schema.py +0 -103
  108. package/autorest/codegen/models/enum_schema.py +0 -215
  109. package/autorest/codegen/models/list_schema.py +0 -123
  110. package/autorest/codegen/models/object_schema.py +0 -253
  111. package/autorest/codegen/models/primitive_schemas.py +0 -466
  112. package/autorest/codegen/models/request_builder_parameter_list.py +0 -280
  113. package/autorest/codegen/models/rest.py +0 -42
  114. package/autorest/codegen/models/schema_request.py +0 -45
  115. package/autorest/codegen/models/schema_response.py +0 -136
  116. package/autorest/codegen/serializers/rest_serializer.py +0 -57
  117. package/autorest/namer/__init__.py +0 -25
  118. package/autorest/namer/name_converter.py +0 -412
@@ -3,109 +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, get_target_property_name
8
- from .utils import get_schema
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
9
17
 
10
- def _make_public(name):
11
- if name[0] == "_":
12
- return name[1:]
13
- return name
18
+ if TYPE_CHECKING:
19
+ from .code_model import CodeModel
14
20
 
15
- 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)
16
38
 
17
39
  @property
18
40
  def in_method_signature(self) -> bool:
19
- return not(
20
- # if not inputtable, don't put in signature
21
- not self.inputtable_by_user
22
- # If i'm not in the method code, no point in being in signature
23
- or not self.in_method_code
24
- # If I'm a flattened property of a body, don't want me, want the body param
25
- or self.target_property_name
26
- or not self.in_method_code
27
- )
41
+ return super().in_method_signature and not self.is_partial_body
28
42
 
29
43
  @property
30
- def name_in_high_level_operation(self) -> str:
31
- template = "{}" if self.code_model.options["version_tolerant"] else "_{}"
32
- if self.is_multipart:
33
- return template.format("files")
34
- if self.is_data_input:
35
- return template.format("data")
36
- if self.is_body and not self.constant:
37
- return f"_{self.serialized_name}"
38
- name = self.yaml_data["language"]["python"]["name"]
39
- if self.implementation == "Client" and self.in_method_code:
40
- # for these, we're passing the client params to the request builder.
41
- # Need the self._config prefix
42
- name = f"self._config.{name}"
43
- 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
+ )
44
50
 
45
- @property
46
- def in_method_code(self) -> bool:
47
- if self.location == ParameterLocation.Uri:
48
- # don't want any base url path formatting arguments
49
- return False
50
- 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
51
56
 
52
57
  @property
53
- def default_value_declaration(self) -> Optional[str]:
54
- if self.serialized_name == "content_type":
55
- # in request builders we're in a weird scenario
56
- # we need to know what the types of content_type are
57
- # but we want to serialize content_type with no default.
58
- # So, we just return None in default_value_declaration for now
59
- return "None"
60
- 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"
61
62
 
62
- @property
63
- def is_keyword_only(self) -> bool:
64
- return not self.location == ParameterLocation.Path and not self.is_kwarg
65
63
 
66
- @is_keyword_only.setter
67
- def is_keyword_only(self, val: bool) -> None:
68
- self._keyword_only = val
69
- self.is_kwarg = False
64
+ class RequestBuilderMultipartBodyParameter(
65
+ _MultipartBodyParameter[ # pylint: disable=unsubscriptable-object
66
+ RequestBuilderBodyParameter
67
+ ]
68
+ ):
69
+ """Multipart body parameter for Request BUilders"""
70
70
 
71
71
  @property
72
- def full_serialized_name(self) -> str:
73
- return self.serialized_name
72
+ def name_in_high_level_operation(self) -> str:
73
+ return f"_{self.client_name}"
74
74
 
75
75
  @classmethod
76
76
  def from_yaml(
77
- cls, yaml_data: Dict[str, Any], *, code_model, content_types: Optional[List[str]] = None
78
- ) -> "RequestBuilderParameter":
79
- http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
80
- name = yaml_data["language"]["python"]["name"]
81
- location = ParameterLocation(http_protocol["in"])
82
- serialized_name = yaml_data["language"]["python"]["name"]
83
- schema = get_schema(
84
- code_model, yaml_data.get("schema"), serialized_name
85
- )
86
- target_property = yaml_data.get("targetProperty")
87
- target_property_name = get_target_property_name(code_model, id(target_property)) if target_property else None
77
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
78
+ ) -> "RequestBuilderMultipartBodyParameter":
88
79
  return cls(
89
- code_model=code_model,
90
80
  yaml_data=yaml_data,
91
- schema=schema,
92
- # See also https://github.com/Azure/autorest.modelerfour/issues/80
93
- rest_api_name=yaml_data["language"]["default"].get(
94
- "serializedName", yaml_data["language"]["default"]["name"]
95
- ),
96
- serialized_name=_make_public(name),
97
- description=yaml_data["language"]["python"]["description"],
98
- implementation=yaml_data["implementation"],
99
- required=yaml_data.get("required", False),
100
- location=location,
101
- skip_url_encoding=yaml_data.get("extensions", {}).get("x-ms-skip-url-encoding", False),
102
- constraints=[], # FIXME constraints
103
- target_property_name=target_property_name,
104
- style=ParameterStyle(http_protocol["style"]) if "style" in http_protocol else None,
105
- explode=http_protocol.get("explode", False),
106
- grouped_by=yaml_data.get("groupedBy", None),
107
- original_parameter=yaml_data.get("originalParameter", None),
108
- flattened=yaml_data.get("flattened", False),
109
- client_default_value=yaml_data.get("clientDefaultValue"),
110
- 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
+ ],
111
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
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,25 +4,21 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  import re
7
- from typing import Any, TYPE_CHECKING
8
- import logging
9
- from .base_schema import BaseSchema
7
+ from typing import TypeVar, Dict
10
8
 
11
- if TYPE_CHECKING:
12
- from .code_model import CodeModel
9
+ JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
13
10
 
11
+ T = TypeVar("T")
12
+ OrderedSet = Dict[T, None]
14
13
 
15
- _LOGGER = logging.getLogger(__name__)
16
14
 
17
- JSON_REGEXP = re.compile(r'^(application|text)/(.+\+)?json$')
15
+ def add_to_description(description: str, entry: str) -> str:
16
+ if description:
17
+ return f"{description} {entry}"
18
+ return entry
18
19
 
19
- def get_schema(code_model: "CodeModel", schema: Any, serialized_name: str = "unknown") -> BaseSchema:
20
- if not isinstance(schema, dict):
21
- return schema
22
- schema_id = id(schema)
23
- _LOGGER.debug("Looking for id %s for member %s", schema_id, serialized_name)
24
- try:
25
- return code_model.lookup_schema(schema_id)
26
- except KeyError:
27
- _LOGGER.critical("Unable to ref the object")
28
- raise
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}"