@autorest/python 5.15.0 → 5.16.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 (86) hide show
  1. package/ChangeLog.md +20 -0
  2. package/autorest/__init__.py +1 -2
  3. package/autorest/black/__init__.py +12 -5
  4. package/autorest/codegen/__init__.py +145 -73
  5. package/autorest/codegen/models/__init__.py +29 -18
  6. package/autorest/codegen/models/base_builder.py +48 -11
  7. package/autorest/codegen/models/base_model.py +6 -4
  8. package/autorest/codegen/models/base_schema.py +19 -18
  9. package/autorest/codegen/models/client.py +65 -21
  10. package/autorest/codegen/models/code_model.py +107 -61
  11. package/autorest/codegen/models/constant_schema.py +25 -13
  12. package/autorest/codegen/models/credential_model.py +23 -15
  13. package/autorest/codegen/models/credential_schema.py +18 -14
  14. package/autorest/codegen/models/credential_schema_policy.py +11 -15
  15. package/autorest/codegen/models/dictionary_schema.py +20 -17
  16. package/autorest/codegen/models/enum_schema.py +35 -25
  17. package/autorest/codegen/models/imports.py +70 -41
  18. package/autorest/codegen/models/list_schema.py +25 -13
  19. package/autorest/codegen/models/lro_operation.py +58 -22
  20. package/autorest/codegen/models/lro_paging_operation.py +2 -3
  21. package/autorest/codegen/models/object_schema.py +99 -49
  22. package/autorest/codegen/models/operation.py +236 -117
  23. package/autorest/codegen/models/operation_group.py +64 -34
  24. package/autorest/codegen/models/paging_operation.py +45 -18
  25. package/autorest/codegen/models/parameter.py +151 -83
  26. package/autorest/codegen/models/parameter_list.py +183 -162
  27. package/autorest/codegen/models/primitive_schemas.py +84 -55
  28. package/autorest/codegen/models/property.py +44 -26
  29. package/autorest/codegen/models/request_builder.py +65 -30
  30. package/autorest/codegen/models/request_builder_parameter.py +47 -23
  31. package/autorest/codegen/models/request_builder_parameter_list.py +77 -108
  32. package/autorest/codegen/models/schema_request.py +16 -6
  33. package/autorest/codegen/models/schema_response.py +18 -13
  34. package/autorest/codegen/models/utils.py +5 -2
  35. package/autorest/codegen/serializers/__init__.py +182 -91
  36. package/autorest/codegen/serializers/builder_serializer.py +667 -331
  37. package/autorest/codegen/serializers/client_serializer.py +98 -37
  38. package/autorest/codegen/serializers/general_serializer.py +61 -26
  39. package/autorest/codegen/serializers/import_serializer.py +93 -31
  40. package/autorest/codegen/serializers/metadata_serializer.py +73 -24
  41. package/autorest/codegen/serializers/model_base_serializer.py +35 -15
  42. package/autorest/codegen/serializers/model_generic_serializer.py +1 -4
  43. package/autorest/codegen/serializers/model_init_serializer.py +5 -1
  44. package/autorest/codegen/serializers/model_python3_serializer.py +7 -6
  45. package/autorest/codegen/serializers/operation_groups_serializer.py +20 -9
  46. package/autorest/codegen/serializers/operations_init_serializer.py +23 -11
  47. package/autorest/codegen/serializers/patch_serializer.py +4 -1
  48. package/autorest/codegen/serializers/{rest_serializer.py → request_builders_serializer.py} +29 -12
  49. package/autorest/codegen/serializers/utils.py +35 -21
  50. package/autorest/codegen/templates/init.py.jinja2 +2 -2
  51. package/autorest/codegen/templates/lro_operation.py.jinja2 +5 -7
  52. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +5 -7
  53. package/autorest/codegen/templates/metadata.json.jinja2 +7 -6
  54. package/autorest/codegen/templates/operation.py.jinja2 +7 -9
  55. package/autorest/codegen/templates/operation_group.py.jinja2 +2 -8
  56. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +1 -1
  57. package/autorest/codegen/templates/paging_operation.py.jinja2 +7 -8
  58. package/autorest/codegen/templates/request_builder.py.jinja2 +18 -11
  59. package/autorest/jsonrpc/__init__.py +7 -12
  60. package/autorest/jsonrpc/localapi.py +4 -3
  61. package/autorest/jsonrpc/server.py +13 -6
  62. package/autorest/jsonrpc/stdstream.py +13 -6
  63. package/autorest/m2r/__init__.py +5 -8
  64. package/autorest/multiapi/__init__.py +24 -14
  65. package/autorest/multiapi/models/client.py +21 -11
  66. package/autorest/multiapi/models/code_model.py +23 -10
  67. package/autorest/multiapi/models/config.py +4 -1
  68. package/autorest/multiapi/models/constant_global_parameter.py +1 -0
  69. package/autorest/multiapi/models/global_parameter.py +2 -1
  70. package/autorest/multiapi/models/global_parameters.py +14 -8
  71. package/autorest/multiapi/models/imports.py +24 -17
  72. package/autorest/multiapi/models/mixin_operation.py +5 -5
  73. package/autorest/multiapi/models/operation_group.py +2 -1
  74. package/autorest/multiapi/models/operation_mixin_group.py +21 -10
  75. package/autorest/multiapi/serializers/__init__.py +18 -23
  76. package/autorest/multiapi/serializers/import_serializer.py +47 -17
  77. package/autorest/multiapi/serializers/multiapi_serializer.py +17 -17
  78. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +1 -1
  79. package/autorest/multiapi/utils.py +3 -3
  80. package/autorest/namer/__init__.py +2 -4
  81. package/autorest/namer/name_converter.py +200 -103
  82. package/autorest/namer/python_mappings.py +10 -22
  83. package/package.json +2 -2
  84. package/run-python3.js +2 -3
  85. package/venvtools.py +1 -1
  86. package/autorest/codegen/models/rest.py +0 -42
@@ -3,20 +3,30 @@
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
6
+ from typing import Any, Dict, List, Optional, TYPE_CHECKING
7
+ from .parameter import (
8
+ ParameterMethodLocation,
9
+ ParameterOnlyPathAndBodyPositional,
10
+ ParameterLocation,
11
+ ParameterStyle,
12
+ get_target_property_name,
13
+ )
8
14
  from .utils import get_schema
9
15
 
16
+ if TYPE_CHECKING:
17
+ from .code_model import CodeModel
18
+
19
+
10
20
  def _make_public(name):
11
21
  if name[0] == "_":
12
22
  return name[1:]
13
23
  return name
14
24
 
15
- class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
16
25
 
26
+ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
17
27
  @property
18
28
  def in_method_signature(self) -> bool:
19
- return not(
29
+ return not (
20
30
  # if not inputtable, don't put in signature
21
31
  not self.inputtable_by_user
22
32
  # If i'm not in the method code, no point in being in signature
@@ -28,11 +38,6 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
28
38
 
29
39
  @property
30
40
  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
41
  if self.is_body and not self.constant:
37
42
  return f"_{self.serialized_name}"
38
43
  name = self.yaml_data["language"]["python"]["name"]
@@ -60,13 +65,20 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
60
65
  return super().default_value_declaration
61
66
 
62
67
  @property
63
- def is_keyword_only(self) -> bool:
64
- return not self.location == ParameterLocation.Path and not self.is_kwarg
68
+ def method_location(self) -> ParameterMethodLocation:
69
+ super_method_location = super().method_location
70
+ if super_method_location in (
71
+ ParameterMethodLocation.KWARG,
72
+ ParameterMethodLocation.HIDDEN_KWARG,
73
+ ):
74
+ return super_method_location
75
+ if self.location != ParameterLocation.Path:
76
+ return ParameterMethodLocation.KEYWORD_ONLY
77
+ return super_method_location
65
78
 
66
- @is_keyword_only.setter
67
- def is_keyword_only(self, val: bool) -> None:
68
- self._keyword_only = val
69
- self.is_kwarg = False
79
+ @method_location.setter
80
+ def method_location(self, val: ParameterMethodLocation) -> None:
81
+ self._method_location = val
70
82
 
71
83
  @property
72
84
  def full_serialized_name(self) -> str:
@@ -74,17 +86,25 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
74
86
 
75
87
  @classmethod
76
88
  def from_yaml(
77
- cls, yaml_data: Dict[str, Any], *, code_model, content_types: Optional[List[str]] = None
89
+ cls,
90
+ yaml_data: Dict[str, Any],
91
+ code_model: "CodeModel",
92
+ *,
93
+ content_types: Optional[List[str]] = None,
78
94
  ) -> "RequestBuilderParameter":
79
- http_protocol = yaml_data["protocol"].get("http", {"in": ParameterLocation.Other})
95
+ http_protocol = yaml_data["protocol"].get(
96
+ "http", {"in": ParameterLocation.Other}
97
+ )
80
98
  name = yaml_data["language"]["python"]["name"]
81
99
  location = ParameterLocation(http_protocol["in"])
82
100
  serialized_name = yaml_data["language"]["python"]["name"]
83
- schema = get_schema(
84
- code_model, yaml_data.get("schema"), serialized_name
85
- )
101
+ schema = get_schema(code_model, yaml_data.get("schema"), serialized_name)
86
102
  target_property = yaml_data.get("targetProperty")
87
- target_property_name = get_target_property_name(code_model, id(target_property)) if target_property else None
103
+ target_property_name = (
104
+ get_target_property_name(code_model, id(target_property))
105
+ if target_property
106
+ else None
107
+ )
88
108
  return cls(
89
109
  code_model=code_model,
90
110
  yaml_data=yaml_data,
@@ -98,10 +118,14 @@ class RequestBuilderParameter(ParameterOnlyPathAndBodyPositional):
98
118
  implementation=yaml_data["implementation"],
99
119
  required=yaml_data.get("required", False),
100
120
  location=location,
101
- skip_url_encoding=yaml_data.get("extensions", {}).get("x-ms-skip-url-encoding", False),
121
+ skip_url_encoding=yaml_data.get("extensions", {}).get(
122
+ "x-ms-skip-url-encoding", False
123
+ ),
102
124
  constraints=[], # FIXME constraints
103
125
  target_property_name=target_property_name,
104
- style=ParameterStyle(http_protocol["style"]) if "style" in http_protocol else None,
126
+ style=ParameterStyle(http_protocol["style"])
127
+ if "style" in http_protocol
128
+ else None,
105
129
  explode=http_protocol.get("explode", False),
106
130
  grouped_by=yaml_data.get("groupedBy", None),
107
131
  original_parameter=yaml_data.get("originalParameter", None),
@@ -4,38 +4,48 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  from copy import copy
7
- from typing import List, Optional, Tuple, TypeVar, Dict
7
+ from typing import List, Optional, Tuple, TypeVar, Dict, TYPE_CHECKING
8
8
  from .request_builder_parameter import RequestBuilderParameter
9
9
  from .parameter_list import ParameterList
10
- from .parameter import ParameterLocation, Parameter, ParameterStyle
11
- from .primitive_schemas import AnySchema, JSONSchema
10
+ from .parameter import (
11
+ ParameterLocation,
12
+ Parameter,
13
+ ParameterMethodLocation,
14
+ ParameterStyle,
15
+ )
16
+ from .primitive_schemas import AnySchema
12
17
  from .dictionary_schema import DictionarySchema
13
18
  from .base_schema import BaseSchema
19
+ from .list_schema import ListSchema
20
+ from .object_schema import ObjectSchema
14
21
  from .schema_request import SchemaRequest
15
22
  from .utils import JSON_REGEXP
16
23
 
17
- T = TypeVar('T')
24
+ if TYPE_CHECKING:
25
+ from .code_model import CodeModel
26
+
27
+ T = TypeVar("T")
18
28
  OrderedSet = Dict[T, None]
19
29
 
20
30
 
21
31
  def _update_content_types(content_types_to_assign: List[str], param: Parameter):
22
- return [
23
- c for c in content_types_to_assign if c not in param.content_types
24
- ]
32
+ return [c for c in content_types_to_assign if c not in param.content_types]
33
+
25
34
 
26
35
  def _kwarg_not_added(body_method_params, serialized_name: str) -> bool:
27
- return not any(b for b in body_method_params if b.serialized_name == serialized_name)
36
+ return not any(
37
+ b for b in body_method_params if b.serialized_name == serialized_name
38
+ )
39
+
28
40
 
29
41
  class RequestBuilderParameterList(ParameterList):
30
42
  def __init__(
31
43
  self,
32
- code_model,
44
+ code_model: "CodeModel",
33
45
  parameters: Optional[List[RequestBuilderParameter]] = None,
34
46
  schema_requests: Optional[List[SchemaRequest]] = None,
35
47
  ) -> None:
36
- super(RequestBuilderParameterList, self).__init__(
37
- code_model, parameters, schema_requests # type: ignore
38
- )
48
+ super().__init__(code_model, parameters, schema_requests) # type: ignore
39
49
  self.body_kwarg_names: OrderedSet[str] = {}
40
50
  self.parameters: List[RequestBuilderParameter] = parameters or [] # type: ignore
41
51
 
@@ -45,17 +55,20 @@ class RequestBuilderParameterList(ParameterList):
45
55
  parameter.is_body_kwarg = True
46
56
 
47
57
  def _is_json(self, body_method_param: Parameter) -> bool:
48
- if 'json' in body_method_param.serialization_formats:
58
+ if "json" in body_method_param.serialization_formats:
49
59
  return True
50
60
  if not any(
51
- flag for flag in ["version_tolerant", "low_level_client"]
61
+ flag
62
+ for flag in ["version_tolerant", "low_level_client"]
52
63
  if self.code_model.options.get(flag)
53
64
  ):
54
65
  if body_method_param.style == ParameterStyle.binary:
55
66
  return False
56
67
  if any(
57
- sr for sr in self.schema_requests
58
- if sr.yaml_data.get("protocol", {}).get('http', {}).get('knownMediaType') == "json"
68
+ sr
69
+ for sr in self.schema_requests
70
+ if sr.yaml_data.get("protocol", {}).get("http", {}).get("knownMediaType")
71
+ == "json"
59
72
  ):
60
73
  return True
61
74
  return any(c for c in self.content_types if JSON_REGEXP.match(c))
@@ -70,11 +83,9 @@ class RequestBuilderParameterList(ParameterList):
70
83
  # we don't currently have a fully constant data or files input
71
84
  # so we don't need to modify the body kwarg
72
85
  constant_bodies = [
73
- p for p in self.parameters
74
- if p.location == ParameterLocation.Body
75
- and p.constant
76
- and not p.is_data_input
77
- and not p.is_multipart
86
+ p
87
+ for p in self.parameters
88
+ if p.location == ParameterLocation.Body and p.constant
78
89
  ]
79
90
  for constant_body in constant_bodies:
80
91
  if self._is_json(constant_body):
@@ -82,48 +93,6 @@ class RequestBuilderParameterList(ParameterList):
82
93
  else:
83
94
  constant_body.serialized_name = "content"
84
95
 
85
- def _add_files_kwarg(
86
- self, content_types_to_assign, body_method_param
87
- ) -> Tuple[List[str], RequestBuilderParameter]:
88
- file_kwarg = copy(body_method_param)
89
- self._change_body_param_name(file_kwarg, "files")
90
- file_kwarg.schema = DictionarySchema(
91
- namespace="",
92
- yaml_data={},
93
- element_type=AnySchema(namespace="", yaml_data={}),
94
- )
95
- file_kwarg.description = (
96
- "Multipart input for files. See the template in our example to find the input shape. " +
97
- file_kwarg.description
98
- )
99
- file_kwarg.content_types = [
100
- c for c in content_types_to_assign
101
- if c == "multipart/form-data"
102
- ]
103
- content_types_to_assign = _update_content_types(content_types_to_assign, file_kwarg)
104
- return content_types_to_assign, file_kwarg
105
-
106
- def _add_data_kwarg(
107
- self, content_types_to_assign, body_method_param
108
- ) -> Tuple[List[str], RequestBuilderParameter]:
109
- data_kwarg = copy(body_method_param)
110
- self._change_body_param_name(data_kwarg, "data")
111
- data_kwarg.schema = DictionarySchema(
112
- namespace="",
113
- yaml_data={},
114
- element_type=AnySchema(namespace="", yaml_data={}),
115
- )
116
- data_kwarg.description = (
117
- "Pass in dictionary that contains form data to include in the body of the request. " +
118
- data_kwarg.description
119
- )
120
- data_kwarg.content_types = [
121
- c for c in content_types_to_assign
122
- if c == "application/x-www-form-urlencoded"
123
- ]
124
- content_types_to_assign = _update_content_types(content_types_to_assign, data_kwarg)
125
- return content_types_to_assign, data_kwarg
126
-
127
96
  def _add_json_kwarg(
128
97
  self, content_types_to_assign, body_method_param
129
98
  ) -> Tuple[List[str], RequestBuilderParameter]:
@@ -131,15 +100,19 @@ class RequestBuilderParameterList(ParameterList):
131
100
  self._change_body_param_name(json_kwarg, "json")
132
101
  json_kwarg.description = (
133
102
  "Pass in a JSON-serializable object (usually a dictionary). "
134
- "See the template in our example to find the input shape. " +
135
- json_kwarg.description
103
+ "See the template in our example to find the input shape. "
104
+ + json_kwarg.description
136
105
  )
137
- json_kwarg.schema = JSONSchema(namespace="", yaml_data={})
106
+ if not isinstance(
107
+ body_method_param.schema, (ObjectSchema, DictionarySchema, ListSchema)
108
+ ):
109
+ json_kwarg.schema = AnySchema(yaml_data={}, code_model=self.code_model)
138
110
  json_kwarg.content_types = [
139
- c for c in content_types_to_assign
140
- if JSON_REGEXP.match(c)
111
+ c for c in content_types_to_assign if JSON_REGEXP.match(c)
141
112
  ]
142
- content_types_to_assign = _update_content_types(content_types_to_assign, json_kwarg)
113
+ content_types_to_assign = _update_content_types(
114
+ content_types_to_assign, json_kwarg
115
+ )
143
116
  return content_types_to_assign, json_kwarg
144
117
 
145
118
  def _add_content_kwarg(
@@ -147,14 +120,11 @@ class RequestBuilderParameterList(ParameterList):
147
120
  ) -> RequestBuilderParameter:
148
121
  content_kwarg = copy(body_method_param)
149
122
  self._change_body_param_name(content_kwarg, "content")
150
- content_kwarg.schema = AnySchema(namespace="", yaml_data={})
123
+ content_kwarg.schema = AnySchema(yaml_data={}, code_model=self.code_model)
151
124
  content_kwarg.description = (
152
125
  "Pass in binary content you want in the body of the request (typically bytes, "
153
- "a byte iterator, or stream input). " +
154
- content_kwarg.description
126
+ "a byte iterator, or stream input). " + content_kwarg.description
155
127
  )
156
- content_kwarg.is_data_input = False
157
- content_kwarg.is_multipart = False
158
128
  content_kwarg.content_types = content_types_to_assign
159
129
  return content_kwarg
160
130
 
@@ -162,25 +132,18 @@ class RequestBuilderParameterList(ParameterList):
162
132
  self._update_constant_params()
163
133
  body_kwargs_added: List[RequestBuilderParameter] = []
164
134
  body_method_params = [
165
- p for p in self.parameters
166
- if p.location == ParameterLocation.Body and not p.constant
135
+ p
136
+ for p in self.parameters
137
+ if p.location == ParameterLocation.Body
138
+ and not (p.constant or p.is_multipart or p.is_data_input)
167
139
  ]
168
140
  if not body_method_params:
169
141
  return
170
142
  content_types_to_assign = copy(self.content_types)
171
143
  for body_method_param in body_method_params:
172
- if body_method_param.is_multipart and _kwarg_not_added(body_kwargs_added, "files"):
173
- content_types_to_assign, file_kwarg = self._add_files_kwarg(
174
- content_types_to_assign, body_method_param
175
- )
176
- body_kwargs_added.append(file_kwarg)
177
-
178
- elif body_method_param.is_data_input and _kwarg_not_added(body_kwargs_added, "data"):
179
- content_types_to_assign, data_kwarg = self._add_data_kwarg(
180
- content_types_to_assign, body_method_param
181
- )
182
- body_kwargs_added.append(data_kwarg)
183
- elif self._is_json(body_method_param) and _kwarg_not_added(body_kwargs_added, "json"):
144
+ if self._is_json(body_method_param) and _kwarg_not_added(
145
+ body_kwargs_added, "json"
146
+ ):
184
147
  content_types_to_assign, json_kwarg = self._add_json_kwarg(
185
148
  content_types_to_assign, body_method_param
186
149
  )
@@ -206,8 +169,7 @@ class RequestBuilderParameterList(ParameterList):
206
169
  if not self._json_body:
207
170
  try:
208
171
  json_param = next(
209
- b for b in self.body if not b.is_body_kwarg and
210
- b.is_json_parameter
172
+ b for b in self.body if not b.is_body_kwarg and b.is_json_parameter
211
173
  )
212
174
  self._json_body = json_param.schema
213
175
  return self._json_body
@@ -219,13 +181,14 @@ class RequestBuilderParameterList(ParameterList):
219
181
  # we don't want to pop the body kwargs in py2.7. We send them straight to HttpRequest
220
182
  kwargs_to_pop = self.kwargs
221
183
  if not is_python3_file:
222
- kwargs_to_pop += [k for k in self.keyword_only if not (k.is_body and not k.constant)]
184
+ kwargs_to_pop += [
185
+ k for k in self.keyword_only if not (k.is_body and not k.constant)
186
+ ]
223
187
  return kwargs_to_pop
224
188
 
225
189
  @property
226
190
  def method(self) -> List[Parameter]:
227
- """The list of parameter used in method signature. Includes both positional and kwargs
228
- """
191
+ """The list of parameter used in method signature. Includes both positional and kwargs"""
229
192
  signature_parameters_no_default_value = []
230
193
  signature_parameters_default_value = []
231
194
 
@@ -233,29 +196,28 @@ class RequestBuilderParameterList(ParameterList):
233
196
  # Also allow client parameters if they're going to be used in the request body.
234
197
  # i.e., path parameter, query parameter, header.
235
198
  parameters = self.get_from_predicate(
236
- lambda parameter: parameter.implementation == self.implementation or parameter.in_method_code
199
+ lambda parameter: parameter.implementation == self.implementation
200
+ or parameter.in_method_code
237
201
  )
238
202
  seen_content_type = False
239
203
 
240
204
  for parameter in parameters:
241
-
242
- if (
243
- parameter.location == ParameterLocation.Body and
244
- (parameter.is_data_input or parameter.is_multipart) and
245
- not parameter.is_body_kwarg
205
+ if parameter.location == ParameterLocation.Body and (
206
+ parameter.is_multipart or parameter.is_data_input
246
207
  ):
247
- # if i am a part of files or data, and i'm not the files or
248
- # data kwarg, ignore me
208
+ # don't want any multipart for formdata params in our signature
249
209
  continue
250
210
  if (
251
- parameter.location == ParameterLocation.Body and
252
- not parameter.is_body_kwarg and
253
- not parameter.constant
211
+ parameter.location == ParameterLocation.Body
212
+ and not parameter.is_body_kwarg
213
+ and not parameter.constant
254
214
  ):
255
215
  # we keep the original body param from the swagger for documentation purposes
256
216
  # we don't want it in the method signature
257
217
  continue
258
- if any([g for g in self.groupers if id(g.yaml_data) == id(parameter.yaml_data)]):
218
+ if any(
219
+ [g for g in self.groupers if id(g.yaml_data) == id(parameter.yaml_data)]
220
+ ):
259
221
  # we don't allow a grouped parameter for the body param
260
222
  continue
261
223
  if seen_content_type and parameter.serialized_name == "content_type":
@@ -270,9 +232,16 @@ class RequestBuilderParameterList(ParameterList):
270
232
  else:
271
233
  signature_parameters_default_value.append(parameter)
272
234
 
273
- signature_parameters = signature_parameters_no_default_value + signature_parameters_default_value
274
- signature_parameters.sort(key=lambda item: item.is_keyword_only)
275
- signature_parameters = self._filter_out_multiple_content_type(signature_parameters)
235
+ signature_parameters = (
236
+ signature_parameters_no_default_value + signature_parameters_default_value
237
+ )
238
+ signature_parameters.sort(
239
+ key=lambda item: item.method_location
240
+ == ParameterMethodLocation.KEYWORD_ONLY
241
+ )
242
+ signature_parameters = self._filter_out_multiple_content_type(
243
+ signature_parameters
244
+ )
276
245
  return signature_parameters
277
246
 
278
247
  @staticmethod
@@ -3,32 +3,41 @@
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 Dict, List, Any, Optional
6
+ from typing import Dict, List, Any, Optional, TYPE_CHECKING
7
7
 
8
8
  from .base_model import BaseModel
9
9
  from .parameter import Parameter
10
10
  from .parameter_list import ParameterList
11
11
 
12
+ if TYPE_CHECKING:
13
+ from .code_model import CodeModel
14
+
15
+
12
16
  class SchemaRequest(BaseModel):
13
17
  def __init__(
14
18
  self,
15
19
  yaml_data: Dict[str, Any],
20
+ code_model: "CodeModel",
16
21
  content_types: List[str],
17
22
  parameters: ParameterList,
18
23
  ) -> None:
19
- super().__init__(yaml_data)
24
+ super().__init__(yaml_data, code_model)
20
25
  self.content_types = content_types
21
26
  self.parameters = parameters
22
27
 
23
28
  @property
24
29
  def is_stream_request(self) -> bool:
25
30
  """Is the request expected to be streamable, like a download."""
26
- if self.yaml_data['protocol']['http'].get('knownMediaType'):
27
- return self.yaml_data['protocol']['http']['knownMediaType'] == 'binary' # FIXME: this might be an m4 issue
31
+ if self.yaml_data["protocol"]["http"].get("knownMediaType"):
32
+ return (
33
+ self.yaml_data["protocol"]["http"]["knownMediaType"] == "binary"
34
+ ) # FIXME: this might be an m4 issue
28
35
  return self.yaml_data["protocol"]["http"].get("binary", False)
29
36
 
30
37
  @classmethod
31
- def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model) -> "SchemaRequest":
38
+ def from_yaml(
39
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
40
+ ) -> "SchemaRequest":
32
41
 
33
42
  parameters: Optional[List[Parameter]] = [
34
43
  Parameter.from_yaml(yaml, code_model=code_model)
@@ -37,8 +46,9 @@ class SchemaRequest(BaseModel):
37
46
 
38
47
  return cls(
39
48
  yaml_data=yaml_data,
49
+ code_model=code_model,
40
50
  content_types=yaml_data["protocol"]["http"].get("mediaTypes", []),
41
- parameters=ParameterList(code_model, parameters)
51
+ parameters=ParameterList(code_model, parameters),
42
52
  )
43
53
 
44
54
  def __repr__(self) -> str:
@@ -29,16 +29,15 @@ class HeaderResponse:
29
29
  class SchemaResponse(BaseModel):
30
30
  def __init__(
31
31
  self,
32
- code_model: "CodeModel",
33
32
  yaml_data: Dict[str, Any],
33
+ code_model: "CodeModel",
34
34
  schema: Optional[BaseSchema],
35
35
  content_types: List[str],
36
36
  status_codes: List[Union[str, int]],
37
37
  headers: List[HeaderResponse],
38
38
  binary: bool,
39
39
  ) -> None:
40
- super().__init__(yaml_data)
41
- self.code_model = code_model
40
+ super().__init__(yaml_data, code_model)
42
41
  self.schema = schema
43
42
  self.content_types = content_types
44
43
  self.status_codes = status_codes
@@ -48,14 +47,12 @@ class SchemaResponse(BaseModel):
48
47
 
49
48
  @property
50
49
  def has_body(self) -> bool:
51
- """Tell if that response defines a body.
52
- """
50
+ """Tell if that response defines a body."""
53
51
  return bool(self.schema)
54
52
 
55
53
  @property
56
54
  def has_headers(self) -> bool:
57
- """Tell if that response defines headers.
58
- """
55
+ """Tell if that response defines headers."""
59
56
  return bool(self.headers)
60
57
 
61
58
  @property
@@ -105,27 +102,35 @@ class SchemaResponse(BaseModel):
105
102
  def imports(self, code_model) -> FileImport:
106
103
  file_import = FileImport()
107
104
  if not code_model.options["models_mode"] and self.is_xml:
108
- file_import.add_submodule_import("xml.etree", "ElementTree", ImportType.STDLIB, alias="ET")
105
+ file_import.add_submodule_import(
106
+ "xml.etree", "ElementTree", ImportType.STDLIB, alias="ET"
107
+ )
109
108
  return file_import
110
109
 
111
110
  @classmethod
112
- def from_yaml(cls, yaml_data: Dict[str, Any], *, code_model: "CodeModel") -> "SchemaResponse":
111
+ def from_yaml(
112
+ cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
113
+ ) -> "SchemaResponse":
113
114
  binary = yaml_data.get("binary", False)
114
115
  if binary:
115
- schema: BaseSchema = IOSchema(namespace=None, yaml_data={})
116
+ schema: BaseSchema = IOSchema(yaml_data={}, code_model=code_model)
116
117
  else:
117
118
  schema = get_schema(code_model, yaml_data.get("schema"))
118
119
  return cls(
119
- code_model=code_model,
120
120
  yaml_data=yaml_data,
121
+ code_model=code_model,
121
122
  schema=schema,
122
123
  content_types=yaml_data["protocol"]["http"].get("mediaTypes", []),
123
124
  status_codes=[
124
- int(code) if code != "default" else "default" for code in yaml_data["protocol"]["http"]["statusCodes"]
125
+ int(code) if code != "default" else "default"
126
+ for code in yaml_data["protocol"]["http"]["statusCodes"]
125
127
  ],
126
128
  headers=[
127
129
  HeaderResponse(
128
- header_prop["header"], get_schema(code_model, header_prop["schema"], header_prop["header"])
130
+ header_prop["header"],
131
+ get_schema(
132
+ code_model, header_prop["schema"], header_prop["header"]
133
+ ),
129
134
  )
130
135
  for header_prop in yaml_data["protocol"]["http"].get("headers", [])
131
136
  ],
@@ -14,9 +14,12 @@ if TYPE_CHECKING:
14
14
 
15
15
  _LOGGER = logging.getLogger(__name__)
16
16
 
17
- JSON_REGEXP = re.compile(r'^(application|text)/(.+\+)?json$')
17
+ JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
18
18
 
19
- def get_schema(code_model: "CodeModel", schema: Any, serialized_name: str = "unknown") -> BaseSchema:
19
+
20
+ def get_schema(
21
+ code_model: "CodeModel", schema: Any, serialized_name: str = "unknown"
22
+ ) -> BaseSchema:
20
23
  if not isinstance(schema, dict):
21
24
  return schema
22
25
  schema_id = id(schema)