@autorest/python 6.45.1 → 6.46.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.
- package/generator/build/lib/pygen/codegen/models/code_model.py +4 -0
- package/generator/build/lib/pygen/codegen/models/enum_type.py +8 -1
- package/generator/build/lib/pygen/codegen/models/list_type.py +6 -2
- package/generator/build/lib/pygen/codegen/models/model_type.py +2 -2
- package/generator/build/lib/pygen/codegen/models/operation.py +10 -1
- package/generator/build/lib/pygen/codegen/models/operation_group.py +3 -1
- package/generator/build/lib/pygen/codegen/models/request_builder.py +20 -3
- package/generator/build/lib/pygen/codegen/models/response.py +2 -2
- package/generator/build/lib/pygen/codegen/models/utils.py +7 -0
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +20 -11
- package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +1 -2
- package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +1 -1
- package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +3 -0
- package/generator/build/lib/pygen/codegen/templates/enum.py.jinja2 +3 -1
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +10 -7
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/models/code_model.py +4 -0
- package/generator/pygen/codegen/models/enum_type.py +8 -1
- package/generator/pygen/codegen/models/list_type.py +6 -2
- package/generator/pygen/codegen/models/model_type.py +2 -2
- package/generator/pygen/codegen/models/operation.py +10 -1
- package/generator/pygen/codegen/models/operation_group.py +3 -1
- package/generator/pygen/codegen/models/request_builder.py +20 -3
- package/generator/pygen/codegen/models/response.py +2 -2
- package/generator/pygen/codegen/models/utils.py +7 -0
- package/generator/pygen/codegen/serializers/builder_serializer.py +20 -11
- package/generator/pygen/codegen/serializers/client_serializer.py +1 -2
- package/generator/pygen/codegen/serializers/general_serializer.py +1 -1
- package/generator/pygen/codegen/serializers/model_serializer.py +3 -0
- package/generator/pygen/codegen/templates/enum.py.jinja2 +3 -1
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +10 -7
- package/package.json +2 -2
- package/scripts/__pycache__/venvtools.cpython-310.pyc +0 -0
|
@@ -491,6 +491,10 @@ class CodeModel: # pylint: disable=too-many-public-methods, disable=too-many-in
|
|
|
491
491
|
def has_operation_named_list(self) -> bool:
|
|
492
492
|
return any(o.name.lower() == "list" for c in self.clients for og in c.operation_groups for o in og.operations)
|
|
493
493
|
|
|
494
|
+
@property
|
|
495
|
+
def has_property_named_list(self) -> bool:
|
|
496
|
+
return any(p.client_name.lower() == "list" for m in self.model_types for p in m.properties)
|
|
497
|
+
|
|
494
498
|
@property
|
|
495
499
|
def has_padded_model_property(self) -> bool:
|
|
496
500
|
for model_type in self.model_types:
|
|
@@ -7,7 +7,8 @@ from typing import Any, TYPE_CHECKING, Optional, cast
|
|
|
7
7
|
|
|
8
8
|
from .base import BaseType
|
|
9
9
|
from .imports import FileImport, ImportType, TypingSection
|
|
10
|
-
from .utils import NamespaceType
|
|
10
|
+
from .utils import NamespaceType, add_to_pylint_disable
|
|
11
|
+
from ...utils import NAME_LENGTH_LIMIT
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
if TYPE_CHECKING:
|
|
@@ -189,6 +190,12 @@ class EnumType(BaseType):
|
|
|
189
190
|
return f"Union[{self.value_type.type_annotation(**kwargs)}, {model_name}]"
|
|
190
191
|
return self.value_type.type_annotation(**kwargs)
|
|
191
192
|
|
|
193
|
+
def pylint_disable(self) -> str:
|
|
194
|
+
retval: str = ""
|
|
195
|
+
if len(self.name) > NAME_LENGTH_LIMIT:
|
|
196
|
+
retval = add_to_pylint_disable(retval, "name-too-long")
|
|
197
|
+
return retval
|
|
198
|
+
|
|
192
199
|
def get_declaration(self, value: Any) -> str:
|
|
193
200
|
return self.value_type.get_declaration(value)
|
|
194
201
|
|
|
@@ -41,8 +41,12 @@ class ListType(BaseType):
|
|
|
41
41
|
# this means we're version tolerant XML, we just return the XML element
|
|
42
42
|
return self.element_type.type_annotation(**kwargs)
|
|
43
43
|
|
|
44
|
-
# if there is a function named `list` we have to make sure there's no conflict with the built-in `list`
|
|
45
|
-
|
|
44
|
+
# if there is a function/property named `list` we have to make sure there's no conflict with the built-in `list`
|
|
45
|
+
is_operation_file = kwargs.get("is_operation_file", False)
|
|
46
|
+
use_list_import = (self.code_model.has_operation_named_list and is_operation_file) or (
|
|
47
|
+
self.code_model.has_property_named_list and not is_operation_file
|
|
48
|
+
)
|
|
49
|
+
list_type = "List" if use_list_import else "list"
|
|
46
50
|
return f"{list_type}[{self.element_type.type_annotation(**kwargs)}]"
|
|
47
51
|
|
|
48
52
|
def description(self, *, is_operation_file: bool) -> str:
|
|
@@ -7,7 +7,7 @@ from enum import Enum
|
|
|
7
7
|
from collections import OrderedDict
|
|
8
8
|
from typing import Any, Optional, TYPE_CHECKING, cast
|
|
9
9
|
import sys
|
|
10
|
-
from .utils import add_to_pylint_disable, NamespaceType
|
|
10
|
+
from .utils import add_to_pylint_disable, NamespaceType, LOCALS_LENGTH_LIMIT
|
|
11
11
|
from .base import BaseType
|
|
12
12
|
from .constant_type import ConstantType
|
|
13
13
|
from .property import Property
|
|
@@ -244,7 +244,7 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes, too-
|
|
|
244
244
|
@property
|
|
245
245
|
def init_pylint_disable(self) -> str:
|
|
246
246
|
retval: str = ""
|
|
247
|
-
if len(self.properties) >
|
|
247
|
+
if len(self.properties) > LOCALS_LENGTH_LIMIT:
|
|
248
248
|
retval = add_to_pylint_disable(retval, "too-many-locals")
|
|
249
249
|
return retval
|
|
250
250
|
|
|
@@ -16,7 +16,7 @@ from typing import (
|
|
|
16
16
|
|
|
17
17
|
from .request_builder_parameter import RequestBuilderParameter
|
|
18
18
|
|
|
19
|
-
from .utils import OrderedSet, add_to_pylint_disable
|
|
19
|
+
from .utils import OrderedSet, add_to_pylint_disable, LOCALS_LENGTH_LIMIT, OPERATION_BODY_VARIABLES_LENGTH
|
|
20
20
|
from .base_builder import BaseBuilder
|
|
21
21
|
from .imports import FileImport, ImportType, TypingSection
|
|
22
22
|
from .response import (
|
|
@@ -143,6 +143,12 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
|
|
|
143
143
|
retval = add_to_pylint_disable(retval, "inconsistent-return-statements")
|
|
144
144
|
if len(self.name) > NAME_LENGTH_LIMIT:
|
|
145
145
|
retval = add_to_pylint_disable(retval, "name-too-long")
|
|
146
|
+
method_params = self.parameters.method
|
|
147
|
+
if self.is_overload and len(method_params) > LOCALS_LENGTH_LIMIT:
|
|
148
|
+
retval = add_to_pylint_disable(retval, "too-many-locals")
|
|
149
|
+
elif not self.is_overload and len(method_params) > (LOCALS_LENGTH_LIMIT - OPERATION_BODY_VARIABLES_LENGTH):
|
|
150
|
+
retval = add_to_pylint_disable(retval, "too-many-locals")
|
|
151
|
+
|
|
146
152
|
return retval
|
|
147
153
|
|
|
148
154
|
def cls_type_annotation(self, *, async_mode: bool, **kwargs: Any) -> str:
|
|
@@ -408,6 +414,9 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
|
|
|
408
414
|
file_import.merge(self.get_request_builder_import(self.request_builder, async_mode, serialize_namespace))
|
|
409
415
|
if self.overloads:
|
|
410
416
|
file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
|
|
417
|
+
for overload in self.overloads:
|
|
418
|
+
if overload.parameters.has_body:
|
|
419
|
+
file_import.merge(overload.parameters.body_parameter.type.imports(**kwargs))
|
|
411
420
|
if self.code_model.options["models-mode"] == "dpg":
|
|
412
421
|
relative_path = self.code_model.get_relative_import_path(
|
|
413
422
|
serialize_namespace, module_name="_utils.model_base"
|
|
@@ -93,7 +93,9 @@ class OperationGroup(BaseModel):
|
|
|
93
93
|
@property
|
|
94
94
|
def need_validation(self) -> bool:
|
|
95
95
|
"""Whether any of its operations need validation"""
|
|
96
|
-
return any(o for o in self.operations if o.need_validation)
|
|
96
|
+
return any(o for o in self.operations if o.need_validation) or any(
|
|
97
|
+
og for og in self.operation_groups if og.need_validation
|
|
98
|
+
)
|
|
97
99
|
|
|
98
100
|
def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
|
|
99
101
|
file_import = FileImport(self.code_model)
|
|
@@ -16,11 +16,12 @@ from typing import (
|
|
|
16
16
|
from abc import abstractmethod
|
|
17
17
|
|
|
18
18
|
from .base_builder import BaseBuilder
|
|
19
|
-
from .utils import add_to_pylint_disable
|
|
19
|
+
from .utils import add_to_pylint_disable, LOCALS_LENGTH_LIMIT, REQUEST_BUILDER_BODY_VARIABLES_LENGTH
|
|
20
20
|
from .parameter_list import (
|
|
21
21
|
RequestBuilderParameterList,
|
|
22
22
|
OverloadedRequestBuilderParameterList,
|
|
23
23
|
)
|
|
24
|
+
from .parameter import ParameterLocation
|
|
24
25
|
from .imports import FileImport, ImportType, TypingSection, MsrestImportType
|
|
25
26
|
from ...utils import NAME_LENGTH_LIMIT
|
|
26
27
|
|
|
@@ -67,9 +68,25 @@ class RequestBuilderBase(BaseBuilder[ParameterListType, Sequence["RequestBuilder
|
|
|
67
68
|
return self.yaml_data.get("discriminator") in ("lro", "lropaging")
|
|
68
69
|
|
|
69
70
|
def pylint_disable(self, async_mode: bool) -> str:
|
|
71
|
+
retval = ""
|
|
70
72
|
if len(self.name) > NAME_LENGTH_LIMIT:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
retval = add_to_pylint_disable(retval, "name-too-long")
|
|
74
|
+
method_params = self.parameters.method
|
|
75
|
+
if len(method_params) > LOCALS_LENGTH_LIMIT - REQUEST_BUILDER_BODY_VARIABLES_LENGTH:
|
|
76
|
+
retval = add_to_pylint_disable(retval, "too-many-locals")
|
|
77
|
+
if (
|
|
78
|
+
len(
|
|
79
|
+
[
|
|
80
|
+
p
|
|
81
|
+
for p in method_params
|
|
82
|
+
if p.optional and p.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]
|
|
83
|
+
]
|
|
84
|
+
)
|
|
85
|
+
> LOCALS_LENGTH_LIMIT
|
|
86
|
+
):
|
|
87
|
+
retval = add_to_pylint_disable(retval, "too-many-statements")
|
|
88
|
+
retval = add_to_pylint_disable(retval, "too-many-branches")
|
|
89
|
+
return retval
|
|
73
90
|
|
|
74
91
|
def response_type_annotation(self, **kwargs) -> str:
|
|
75
92
|
return "HttpRequest"
|
|
@@ -233,7 +233,7 @@ class LROResponse(Response):
|
|
|
233
233
|
|
|
234
234
|
def get_no_polling_method(self, async_mode: bool) -> str:
|
|
235
235
|
"""Get the default no polling method"""
|
|
236
|
-
return self.get_no_polling_method_path(async_mode).
|
|
236
|
+
return self.get_no_polling_method_path(async_mode).rsplit(".", maxsplit=1)[-1]
|
|
237
237
|
|
|
238
238
|
@staticmethod
|
|
239
239
|
def get_base_polling_method_path(async_mode: bool) -> str:
|
|
@@ -242,7 +242,7 @@ class LROResponse(Response):
|
|
|
242
242
|
|
|
243
243
|
def get_base_polling_method(self, async_mode: bool) -> str:
|
|
244
244
|
"""Get the base polling method."""
|
|
245
|
-
return self.get_base_polling_method_path(async_mode).
|
|
245
|
+
return self.get_base_polling_method_path(async_mode).rsplit(".", maxsplit=1)[-1]
|
|
246
246
|
|
|
247
247
|
def type_annotation(self, **kwargs: Any) -> str:
|
|
248
248
|
return f"{self.get_poller(kwargs.get('async_mode', False))}[{super().type_annotation(**kwargs)}]"
|
|
@@ -30,3 +30,10 @@ class NamespaceType(str, Enum):
|
|
|
30
30
|
OPERATION = "operation"
|
|
31
31
|
CLIENT = "client"
|
|
32
32
|
TYPES_FILE = "types_file"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
LOCALS_LENGTH_LIMIT = 25
|
|
36
|
+
|
|
37
|
+
REQUEST_BUILDER_BODY_VARIABLES_LENGTH = 6 # how many body variables are present in a request builder
|
|
38
|
+
|
|
39
|
+
OPERATION_BODY_VARIABLES_LENGTH = 14 # how many body variables are present in an operation
|
|
@@ -781,8 +781,14 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
781
781
|
client_names = [
|
|
782
782
|
overload.request_builder.parameters.body_parameter.client_name for overload in builder.overloads
|
|
783
783
|
]
|
|
784
|
-
|
|
785
|
-
|
|
784
|
+
all_dpg_model_overloads = False
|
|
785
|
+
if self.code_model.options["models-mode"] == "dpg" and builder.overloads:
|
|
786
|
+
all_dpg_model_overloads = all(
|
|
787
|
+
isinstance(o.parameters.body_parameter.type, DPGModelType) for o in builder.overloads
|
|
788
|
+
)
|
|
789
|
+
if not all_dpg_model_overloads:
|
|
790
|
+
for v in sorted(set(client_names), key=client_names.index):
|
|
791
|
+
retval.append(f"_{v} = None")
|
|
786
792
|
try:
|
|
787
793
|
# if there is a binary overload, we do a binary check first.
|
|
788
794
|
binary_overload = cast(
|
|
@@ -808,17 +814,20 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
808
814
|
f'"{other_overload.parameters.body_parameter.default_content_type}"{check_body_suffix}'
|
|
809
815
|
)
|
|
810
816
|
except StopIteration:
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
if body_param.default_content_type and not same_content_type:
|
|
817
|
+
if all_dpg_model_overloads:
|
|
818
|
+
retval.extend(f"{l}" for l in self._create_body_parameter(cast(OperationType, builder.overloads[0])))
|
|
819
|
+
else:
|
|
820
|
+
for idx, overload in enumerate(builder.overloads):
|
|
821
|
+
if_statement = "if" if idx == 0 else "elif"
|
|
822
|
+
body_param = overload.parameters.body_parameter
|
|
818
823
|
retval.append(
|
|
819
|
-
f
|
|
824
|
+
f"{if_statement} {body_param.type.instance_check_template.format(body_param.client_name)}:"
|
|
820
825
|
)
|
|
821
|
-
|
|
826
|
+
if body_param.default_content_type and not same_content_type:
|
|
827
|
+
retval.append(
|
|
828
|
+
f' content_type = content_type or "{body_param.default_content_type}"{check_body_suffix}'
|
|
829
|
+
)
|
|
830
|
+
retval.extend(f" {l}" for l in self._create_body_parameter(cast(OperationType, overload)))
|
|
822
831
|
return retval
|
|
823
832
|
|
|
824
833
|
def _create_request_builder_call(
|
|
@@ -182,11 +182,10 @@ class ClientSerializer:
|
|
|
182
182
|
retval.append("self._serialize.client_side_validation = False")
|
|
183
183
|
operation_groups = [og for og in self.client.operation_groups if not og.is_mixin]
|
|
184
184
|
for og in operation_groups:
|
|
185
|
-
api_version = ""
|
|
186
185
|
retval.extend(
|
|
187
186
|
[
|
|
188
187
|
f"self.{og.property_name} = {og.class_name}(",
|
|
189
|
-
|
|
188
|
+
" self._client, self._config, self._serialize, self._deserialize",
|
|
190
189
|
")",
|
|
191
190
|
]
|
|
192
191
|
)
|
|
@@ -285,6 +285,9 @@ class DpgModelSerializer(_ModelSerializer):
|
|
|
285
285
|
file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
|
|
286
286
|
file_import.add_submodule_import("typing", "Mapping", ImportType.STDLIB)
|
|
287
287
|
file_import.add_submodule_import("typing", "Any", ImportType.STDLIB)
|
|
288
|
+
# if there is a property named `list` we have to make sure there's no conflict with the built-in `list`
|
|
289
|
+
if self.code_model.has_property_named_list:
|
|
290
|
+
file_import.define_mypy_type("List", "list")
|
|
288
291
|
return file_import
|
|
289
292
|
|
|
290
293
|
def declare_model(self, model: ModelType) -> str:
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
class {{ enum.name }}({{
|
|
2
|
+
class {{ enum.name }}({{enum.pylint_disable()}}
|
|
3
|
+
{{ enum.value_type.type_annotation(is_operation_file=False) }}, Enum, metaclass=CaseInsensitiveEnumMeta
|
|
4
|
+
):
|
|
3
5
|
{% if enum.yaml_data.get("description") %}
|
|
4
6
|
"""{{ op_tools.wrap_string(enum.yaml_data["description"], "\n ") }}
|
|
5
7
|
"""
|
|
@@ -36,6 +36,7 @@ __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"]
|
|
|
36
36
|
|
|
37
37
|
TZ_UTC = timezone.utc
|
|
38
38
|
_T = typing.TypeVar("_T")
|
|
39
|
+
_NONE_TYPE = type(None)
|
|
39
40
|
|
|
40
41
|
{% if code_model.has_external_type %}
|
|
41
42
|
TYPE_HANDLER_REGISTRY = TypeHandlerRegistry()
|
|
@@ -223,7 +224,7 @@ def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime:
|
|
|
223
224
|
test_utc = date_obj.utctimetuple()
|
|
224
225
|
if test_utc.tm_year > 9999 or test_utc.tm_year < 1:
|
|
225
226
|
raise OverflowError("Hit max or min date")
|
|
226
|
-
return date_obj
|
|
227
|
+
return date_obj # type: ignore[no-any-return]
|
|
227
228
|
|
|
228
229
|
|
|
229
230
|
def _deserialize_datetime_rfc7231(attr: typing.Union[str, datetime]) -> datetime:
|
|
@@ -277,7 +278,7 @@ def _deserialize_time(attr: typing.Union[str, time]) -> time:
|
|
|
277
278
|
"""
|
|
278
279
|
if isinstance(attr, time):
|
|
279
280
|
return attr
|
|
280
|
-
return isodate.parse_time(attr)
|
|
281
|
+
return isodate.parse_time(attr) # type: ignore[no-any-return]
|
|
281
282
|
|
|
282
283
|
|
|
283
284
|
def _deserialize_bytes(attr):
|
|
@@ -916,16 +917,16 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur
|
|
|
916
917
|
|
|
917
918
|
# is it optional?
|
|
918
919
|
try:
|
|
919
|
-
if any(a for a in annotation.__args__
|
|
920
|
+
if any(a is _NONE_TYPE for a in annotation.__args__): # pyright: ignore
|
|
920
921
|
if len(annotation.__args__) <= 2: # pyright: ignore
|
|
921
922
|
if_obj_deserializer = _get_deserialize_callable_from_annotation(
|
|
922
|
-
next(a for a in annotation.__args__ if a
|
|
923
|
+
next(a for a in annotation.__args__ if a is not _NONE_TYPE), module, rf # pyright: ignore
|
|
923
924
|
)
|
|
924
925
|
|
|
925
926
|
return functools.partial(_deserialize_with_optional, if_obj_deserializer)
|
|
926
927
|
# the type is Optional[Union[...]], we need to remove the None type from the Union
|
|
927
928
|
annotation_copy = copy.copy(annotation)
|
|
928
|
-
annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a
|
|
929
|
+
annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a is not _NONE_TYPE] # pyright: ignore
|
|
929
930
|
return _get_deserialize_callable_from_annotation(annotation_copy, module, rf)
|
|
930
931
|
except AttributeError:
|
|
931
932
|
pass
|
|
@@ -1327,7 +1328,7 @@ def _get_wrapped_element(
|
|
|
1327
1328
|
_get_element(v, exclude_readonly, meta, wrapped_element)
|
|
1328
1329
|
else:
|
|
1329
1330
|
wrapped_element.text = _get_primitive_type_value(v)
|
|
1330
|
-
return wrapped_element
|
|
1331
|
+
return wrapped_element # type: ignore[no-any-return]
|
|
1331
1332
|
|
|
1332
1333
|
|
|
1333
1334
|
def _get_primitive_type_value(v) -> str:
|
|
@@ -1340,7 +1341,9 @@ def _get_primitive_type_value(v) -> str:
|
|
|
1340
1341
|
return str(v)
|
|
1341
1342
|
|
|
1342
1343
|
|
|
1343
|
-
def _create_xml_element(
|
|
1344
|
+
def _create_xml_element(
|
|
1345
|
+
tag: typing.Any, prefix: typing.Optional[str] = None, ns: typing.Optional[str] = None
|
|
1346
|
+
) -> ET.Element:
|
|
1344
1347
|
if prefix and ns:
|
|
1345
1348
|
ET.register_namespace(prefix, ns)
|
|
1346
1349
|
if ns:
|
|
Binary file
|
|
@@ -491,6 +491,10 @@ class CodeModel: # pylint: disable=too-many-public-methods, disable=too-many-in
|
|
|
491
491
|
def has_operation_named_list(self) -> bool:
|
|
492
492
|
return any(o.name.lower() == "list" for c in self.clients for og in c.operation_groups for o in og.operations)
|
|
493
493
|
|
|
494
|
+
@property
|
|
495
|
+
def has_property_named_list(self) -> bool:
|
|
496
|
+
return any(p.client_name.lower() == "list" for m in self.model_types for p in m.properties)
|
|
497
|
+
|
|
494
498
|
@property
|
|
495
499
|
def has_padded_model_property(self) -> bool:
|
|
496
500
|
for model_type in self.model_types:
|
|
@@ -7,7 +7,8 @@ from typing import Any, TYPE_CHECKING, Optional, cast
|
|
|
7
7
|
|
|
8
8
|
from .base import BaseType
|
|
9
9
|
from .imports import FileImport, ImportType, TypingSection
|
|
10
|
-
from .utils import NamespaceType
|
|
10
|
+
from .utils import NamespaceType, add_to_pylint_disable
|
|
11
|
+
from ...utils import NAME_LENGTH_LIMIT
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
if TYPE_CHECKING:
|
|
@@ -189,6 +190,12 @@ class EnumType(BaseType):
|
|
|
189
190
|
return f"Union[{self.value_type.type_annotation(**kwargs)}, {model_name}]"
|
|
190
191
|
return self.value_type.type_annotation(**kwargs)
|
|
191
192
|
|
|
193
|
+
def pylint_disable(self) -> str:
|
|
194
|
+
retval: str = ""
|
|
195
|
+
if len(self.name) > NAME_LENGTH_LIMIT:
|
|
196
|
+
retval = add_to_pylint_disable(retval, "name-too-long")
|
|
197
|
+
return retval
|
|
198
|
+
|
|
192
199
|
def get_declaration(self, value: Any) -> str:
|
|
193
200
|
return self.value_type.get_declaration(value)
|
|
194
201
|
|
|
@@ -41,8 +41,12 @@ class ListType(BaseType):
|
|
|
41
41
|
# this means we're version tolerant XML, we just return the XML element
|
|
42
42
|
return self.element_type.type_annotation(**kwargs)
|
|
43
43
|
|
|
44
|
-
# if there is a function named `list` we have to make sure there's no conflict with the built-in `list`
|
|
45
|
-
|
|
44
|
+
# if there is a function/property named `list` we have to make sure there's no conflict with the built-in `list`
|
|
45
|
+
is_operation_file = kwargs.get("is_operation_file", False)
|
|
46
|
+
use_list_import = (self.code_model.has_operation_named_list and is_operation_file) or (
|
|
47
|
+
self.code_model.has_property_named_list and not is_operation_file
|
|
48
|
+
)
|
|
49
|
+
list_type = "List" if use_list_import else "list"
|
|
46
50
|
return f"{list_type}[{self.element_type.type_annotation(**kwargs)}]"
|
|
47
51
|
|
|
48
52
|
def description(self, *, is_operation_file: bool) -> str:
|
|
@@ -7,7 +7,7 @@ from enum import Enum
|
|
|
7
7
|
from collections import OrderedDict
|
|
8
8
|
from typing import Any, Optional, TYPE_CHECKING, cast
|
|
9
9
|
import sys
|
|
10
|
-
from .utils import add_to_pylint_disable, NamespaceType
|
|
10
|
+
from .utils import add_to_pylint_disable, NamespaceType, LOCALS_LENGTH_LIMIT
|
|
11
11
|
from .base import BaseType
|
|
12
12
|
from .constant_type import ConstantType
|
|
13
13
|
from .property import Property
|
|
@@ -244,7 +244,7 @@ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes, too-
|
|
|
244
244
|
@property
|
|
245
245
|
def init_pylint_disable(self) -> str:
|
|
246
246
|
retval: str = ""
|
|
247
|
-
if len(self.properties) >
|
|
247
|
+
if len(self.properties) > LOCALS_LENGTH_LIMIT:
|
|
248
248
|
retval = add_to_pylint_disable(retval, "too-many-locals")
|
|
249
249
|
return retval
|
|
250
250
|
|
|
@@ -16,7 +16,7 @@ from typing import (
|
|
|
16
16
|
|
|
17
17
|
from .request_builder_parameter import RequestBuilderParameter
|
|
18
18
|
|
|
19
|
-
from .utils import OrderedSet, add_to_pylint_disable
|
|
19
|
+
from .utils import OrderedSet, add_to_pylint_disable, LOCALS_LENGTH_LIMIT, OPERATION_BODY_VARIABLES_LENGTH
|
|
20
20
|
from .base_builder import BaseBuilder
|
|
21
21
|
from .imports import FileImport, ImportType, TypingSection
|
|
22
22
|
from .response import (
|
|
@@ -143,6 +143,12 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
|
|
|
143
143
|
retval = add_to_pylint_disable(retval, "inconsistent-return-statements")
|
|
144
144
|
if len(self.name) > NAME_LENGTH_LIMIT:
|
|
145
145
|
retval = add_to_pylint_disable(retval, "name-too-long")
|
|
146
|
+
method_params = self.parameters.method
|
|
147
|
+
if self.is_overload and len(method_params) > LOCALS_LENGTH_LIMIT:
|
|
148
|
+
retval = add_to_pylint_disable(retval, "too-many-locals")
|
|
149
|
+
elif not self.is_overload and len(method_params) > (LOCALS_LENGTH_LIMIT - OPERATION_BODY_VARIABLES_LENGTH):
|
|
150
|
+
retval = add_to_pylint_disable(retval, "too-many-locals")
|
|
151
|
+
|
|
146
152
|
return retval
|
|
147
153
|
|
|
148
154
|
def cls_type_annotation(self, *, async_mode: bool, **kwargs: Any) -> str:
|
|
@@ -408,6 +414,9 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
|
|
|
408
414
|
file_import.merge(self.get_request_builder_import(self.request_builder, async_mode, serialize_namespace))
|
|
409
415
|
if self.overloads:
|
|
410
416
|
file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
|
|
417
|
+
for overload in self.overloads:
|
|
418
|
+
if overload.parameters.has_body:
|
|
419
|
+
file_import.merge(overload.parameters.body_parameter.type.imports(**kwargs))
|
|
411
420
|
if self.code_model.options["models-mode"] == "dpg":
|
|
412
421
|
relative_path = self.code_model.get_relative_import_path(
|
|
413
422
|
serialize_namespace, module_name="_utils.model_base"
|
|
@@ -93,7 +93,9 @@ class OperationGroup(BaseModel):
|
|
|
93
93
|
@property
|
|
94
94
|
def need_validation(self) -> bool:
|
|
95
95
|
"""Whether any of its operations need validation"""
|
|
96
|
-
return any(o for o in self.operations if o.need_validation)
|
|
96
|
+
return any(o for o in self.operations if o.need_validation) or any(
|
|
97
|
+
og for og in self.operation_groups if og.need_validation
|
|
98
|
+
)
|
|
97
99
|
|
|
98
100
|
def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
|
|
99
101
|
file_import = FileImport(self.code_model)
|
|
@@ -16,11 +16,12 @@ from typing import (
|
|
|
16
16
|
from abc import abstractmethod
|
|
17
17
|
|
|
18
18
|
from .base_builder import BaseBuilder
|
|
19
|
-
from .utils import add_to_pylint_disable
|
|
19
|
+
from .utils import add_to_pylint_disable, LOCALS_LENGTH_LIMIT, REQUEST_BUILDER_BODY_VARIABLES_LENGTH
|
|
20
20
|
from .parameter_list import (
|
|
21
21
|
RequestBuilderParameterList,
|
|
22
22
|
OverloadedRequestBuilderParameterList,
|
|
23
23
|
)
|
|
24
|
+
from .parameter import ParameterLocation
|
|
24
25
|
from .imports import FileImport, ImportType, TypingSection, MsrestImportType
|
|
25
26
|
from ...utils import NAME_LENGTH_LIMIT
|
|
26
27
|
|
|
@@ -67,9 +68,25 @@ class RequestBuilderBase(BaseBuilder[ParameterListType, Sequence["RequestBuilder
|
|
|
67
68
|
return self.yaml_data.get("discriminator") in ("lro", "lropaging")
|
|
68
69
|
|
|
69
70
|
def pylint_disable(self, async_mode: bool) -> str:
|
|
71
|
+
retval = ""
|
|
70
72
|
if len(self.name) > NAME_LENGTH_LIMIT:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
retval = add_to_pylint_disable(retval, "name-too-long")
|
|
74
|
+
method_params = self.parameters.method
|
|
75
|
+
if len(method_params) > LOCALS_LENGTH_LIMIT - REQUEST_BUILDER_BODY_VARIABLES_LENGTH:
|
|
76
|
+
retval = add_to_pylint_disable(retval, "too-many-locals")
|
|
77
|
+
if (
|
|
78
|
+
len(
|
|
79
|
+
[
|
|
80
|
+
p
|
|
81
|
+
for p in method_params
|
|
82
|
+
if p.optional and p.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]
|
|
83
|
+
]
|
|
84
|
+
)
|
|
85
|
+
> LOCALS_LENGTH_LIMIT
|
|
86
|
+
):
|
|
87
|
+
retval = add_to_pylint_disable(retval, "too-many-statements")
|
|
88
|
+
retval = add_to_pylint_disable(retval, "too-many-branches")
|
|
89
|
+
return retval
|
|
73
90
|
|
|
74
91
|
def response_type_annotation(self, **kwargs) -> str:
|
|
75
92
|
return "HttpRequest"
|
|
@@ -233,7 +233,7 @@ class LROResponse(Response):
|
|
|
233
233
|
|
|
234
234
|
def get_no_polling_method(self, async_mode: bool) -> str:
|
|
235
235
|
"""Get the default no polling method"""
|
|
236
|
-
return self.get_no_polling_method_path(async_mode).
|
|
236
|
+
return self.get_no_polling_method_path(async_mode).rsplit(".", maxsplit=1)[-1]
|
|
237
237
|
|
|
238
238
|
@staticmethod
|
|
239
239
|
def get_base_polling_method_path(async_mode: bool) -> str:
|
|
@@ -242,7 +242,7 @@ class LROResponse(Response):
|
|
|
242
242
|
|
|
243
243
|
def get_base_polling_method(self, async_mode: bool) -> str:
|
|
244
244
|
"""Get the base polling method."""
|
|
245
|
-
return self.get_base_polling_method_path(async_mode).
|
|
245
|
+
return self.get_base_polling_method_path(async_mode).rsplit(".", maxsplit=1)[-1]
|
|
246
246
|
|
|
247
247
|
def type_annotation(self, **kwargs: Any) -> str:
|
|
248
248
|
return f"{self.get_poller(kwargs.get('async_mode', False))}[{super().type_annotation(**kwargs)}]"
|
|
@@ -30,3 +30,10 @@ class NamespaceType(str, Enum):
|
|
|
30
30
|
OPERATION = "operation"
|
|
31
31
|
CLIENT = "client"
|
|
32
32
|
TYPES_FILE = "types_file"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
LOCALS_LENGTH_LIMIT = 25
|
|
36
|
+
|
|
37
|
+
REQUEST_BUILDER_BODY_VARIABLES_LENGTH = 6 # how many body variables are present in a request builder
|
|
38
|
+
|
|
39
|
+
OPERATION_BODY_VARIABLES_LENGTH = 14 # how many body variables are present in an operation
|
|
@@ -781,8 +781,14 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
781
781
|
client_names = [
|
|
782
782
|
overload.request_builder.parameters.body_parameter.client_name for overload in builder.overloads
|
|
783
783
|
]
|
|
784
|
-
|
|
785
|
-
|
|
784
|
+
all_dpg_model_overloads = False
|
|
785
|
+
if self.code_model.options["models-mode"] == "dpg" and builder.overloads:
|
|
786
|
+
all_dpg_model_overloads = all(
|
|
787
|
+
isinstance(o.parameters.body_parameter.type, DPGModelType) for o in builder.overloads
|
|
788
|
+
)
|
|
789
|
+
if not all_dpg_model_overloads:
|
|
790
|
+
for v in sorted(set(client_names), key=client_names.index):
|
|
791
|
+
retval.append(f"_{v} = None")
|
|
786
792
|
try:
|
|
787
793
|
# if there is a binary overload, we do a binary check first.
|
|
788
794
|
binary_overload = cast(
|
|
@@ -808,17 +814,20 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
808
814
|
f'"{other_overload.parameters.body_parameter.default_content_type}"{check_body_suffix}'
|
|
809
815
|
)
|
|
810
816
|
except StopIteration:
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
if body_param.default_content_type and not same_content_type:
|
|
817
|
+
if all_dpg_model_overloads:
|
|
818
|
+
retval.extend(f"{l}" for l in self._create_body_parameter(cast(OperationType, builder.overloads[0])))
|
|
819
|
+
else:
|
|
820
|
+
for idx, overload in enumerate(builder.overloads):
|
|
821
|
+
if_statement = "if" if idx == 0 else "elif"
|
|
822
|
+
body_param = overload.parameters.body_parameter
|
|
818
823
|
retval.append(
|
|
819
|
-
f
|
|
824
|
+
f"{if_statement} {body_param.type.instance_check_template.format(body_param.client_name)}:"
|
|
820
825
|
)
|
|
821
|
-
|
|
826
|
+
if body_param.default_content_type and not same_content_type:
|
|
827
|
+
retval.append(
|
|
828
|
+
f' content_type = content_type or "{body_param.default_content_type}"{check_body_suffix}'
|
|
829
|
+
)
|
|
830
|
+
retval.extend(f" {l}" for l in self._create_body_parameter(cast(OperationType, overload)))
|
|
822
831
|
return retval
|
|
823
832
|
|
|
824
833
|
def _create_request_builder_call(
|
|
@@ -182,11 +182,10 @@ class ClientSerializer:
|
|
|
182
182
|
retval.append("self._serialize.client_side_validation = False")
|
|
183
183
|
operation_groups = [og for og in self.client.operation_groups if not og.is_mixin]
|
|
184
184
|
for og in operation_groups:
|
|
185
|
-
api_version = ""
|
|
186
185
|
retval.extend(
|
|
187
186
|
[
|
|
188
187
|
f"self.{og.property_name} = {og.class_name}(",
|
|
189
|
-
|
|
188
|
+
" self._client, self._config, self._serialize, self._deserialize",
|
|
190
189
|
")",
|
|
191
190
|
]
|
|
192
191
|
)
|
|
@@ -285,6 +285,9 @@ class DpgModelSerializer(_ModelSerializer):
|
|
|
285
285
|
file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
|
|
286
286
|
file_import.add_submodule_import("typing", "Mapping", ImportType.STDLIB)
|
|
287
287
|
file_import.add_submodule_import("typing", "Any", ImportType.STDLIB)
|
|
288
|
+
# if there is a property named `list` we have to make sure there's no conflict with the built-in `list`
|
|
289
|
+
if self.code_model.has_property_named_list:
|
|
290
|
+
file_import.define_mypy_type("List", "list")
|
|
288
291
|
return file_import
|
|
289
292
|
|
|
290
293
|
def declare_model(self, model: ModelType) -> str:
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
class {{ enum.name }}({{
|
|
2
|
+
class {{ enum.name }}({{enum.pylint_disable()}}
|
|
3
|
+
{{ enum.value_type.type_annotation(is_operation_file=False) }}, Enum, metaclass=CaseInsensitiveEnumMeta
|
|
4
|
+
):
|
|
3
5
|
{% if enum.yaml_data.get("description") %}
|
|
4
6
|
"""{{ op_tools.wrap_string(enum.yaml_data["description"], "\n ") }}
|
|
5
7
|
"""
|
|
@@ -36,6 +36,7 @@ __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"]
|
|
|
36
36
|
|
|
37
37
|
TZ_UTC = timezone.utc
|
|
38
38
|
_T = typing.TypeVar("_T")
|
|
39
|
+
_NONE_TYPE = type(None)
|
|
39
40
|
|
|
40
41
|
{% if code_model.has_external_type %}
|
|
41
42
|
TYPE_HANDLER_REGISTRY = TypeHandlerRegistry()
|
|
@@ -223,7 +224,7 @@ def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime:
|
|
|
223
224
|
test_utc = date_obj.utctimetuple()
|
|
224
225
|
if test_utc.tm_year > 9999 or test_utc.tm_year < 1:
|
|
225
226
|
raise OverflowError("Hit max or min date")
|
|
226
|
-
return date_obj
|
|
227
|
+
return date_obj # type: ignore[no-any-return]
|
|
227
228
|
|
|
228
229
|
|
|
229
230
|
def _deserialize_datetime_rfc7231(attr: typing.Union[str, datetime]) -> datetime:
|
|
@@ -277,7 +278,7 @@ def _deserialize_time(attr: typing.Union[str, time]) -> time:
|
|
|
277
278
|
"""
|
|
278
279
|
if isinstance(attr, time):
|
|
279
280
|
return attr
|
|
280
|
-
return isodate.parse_time(attr)
|
|
281
|
+
return isodate.parse_time(attr) # type: ignore[no-any-return]
|
|
281
282
|
|
|
282
283
|
|
|
283
284
|
def _deserialize_bytes(attr):
|
|
@@ -916,16 +917,16 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur
|
|
|
916
917
|
|
|
917
918
|
# is it optional?
|
|
918
919
|
try:
|
|
919
|
-
if any(a for a in annotation.__args__
|
|
920
|
+
if any(a is _NONE_TYPE for a in annotation.__args__): # pyright: ignore
|
|
920
921
|
if len(annotation.__args__) <= 2: # pyright: ignore
|
|
921
922
|
if_obj_deserializer = _get_deserialize_callable_from_annotation(
|
|
922
|
-
next(a for a in annotation.__args__ if a
|
|
923
|
+
next(a for a in annotation.__args__ if a is not _NONE_TYPE), module, rf # pyright: ignore
|
|
923
924
|
)
|
|
924
925
|
|
|
925
926
|
return functools.partial(_deserialize_with_optional, if_obj_deserializer)
|
|
926
927
|
# the type is Optional[Union[...]], we need to remove the None type from the Union
|
|
927
928
|
annotation_copy = copy.copy(annotation)
|
|
928
|
-
annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a
|
|
929
|
+
annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a is not _NONE_TYPE] # pyright: ignore
|
|
929
930
|
return _get_deserialize_callable_from_annotation(annotation_copy, module, rf)
|
|
930
931
|
except AttributeError:
|
|
931
932
|
pass
|
|
@@ -1327,7 +1328,7 @@ def _get_wrapped_element(
|
|
|
1327
1328
|
_get_element(v, exclude_readonly, meta, wrapped_element)
|
|
1328
1329
|
else:
|
|
1329
1330
|
wrapped_element.text = _get_primitive_type_value(v)
|
|
1330
|
-
return wrapped_element
|
|
1331
|
+
return wrapped_element # type: ignore[no-any-return]
|
|
1331
1332
|
|
|
1332
1333
|
|
|
1333
1334
|
def _get_primitive_type_value(v) -> str:
|
|
@@ -1340,7 +1341,9 @@ def _get_primitive_type_value(v) -> str:
|
|
|
1340
1341
|
return str(v)
|
|
1341
1342
|
|
|
1342
1343
|
|
|
1343
|
-
def _create_xml_element(
|
|
1344
|
+
def _create_xml_element(
|
|
1345
|
+
tag: typing.Any, prefix: typing.Optional[str] = None, ns: typing.Optional[str] = None
|
|
1346
|
+
) -> ET.Element:
|
|
1344
1347
|
if prefix and ns:
|
|
1345
1348
|
ET.register_namespace(prefix, ns)
|
|
1346
1349
|
if ns:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autorest/python",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.46.0",
|
|
4
4
|
"description": "The Python extension for generators in AutoRest.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"homepage": "https://github.com/Azure/autorest.python/blob/main/README.md",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@typespec/http-client-python": "~0.
|
|
22
|
+
"@typespec/http-client-python": "~0.24.0",
|
|
23
23
|
"@autorest/system-requirements": "~1.0.2",
|
|
24
24
|
"fs-extra": "~11.2.0",
|
|
25
25
|
"tsx": "~4.19.1"
|
|
Binary file
|