@typespec/http-client-python 0.4.4 → 0.5.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 (137) hide show
  1. package/dist/emitter/emitter.d.ts.map +1 -1
  2. package/dist/emitter/emitter.js +85 -24
  3. package/dist/emitter/emitter.js.map +1 -1
  4. package/dist/emitter/lib.d.ts +1 -0
  5. package/dist/emitter/lib.d.ts.map +1 -1
  6. package/dist/emitter/lib.js +1 -0
  7. package/dist/emitter/lib.js.map +1 -1
  8. package/dist/emitter/run-python3.d.ts +2 -0
  9. package/dist/emitter/run-python3.d.ts.map +1 -0
  10. package/dist/emitter/run-python3.js +19 -0
  11. package/dist/emitter/run-python3.js.map +1 -0
  12. package/dist/emitter/system-requirements.d.ts +17 -0
  13. package/dist/emitter/system-requirements.d.ts.map +1 -0
  14. package/dist/emitter/system-requirements.js +167 -0
  15. package/dist/emitter/system-requirements.js.map +1 -0
  16. package/emitter/src/emitter.ts +88 -23
  17. package/emitter/src/lib.ts +2 -0
  18. package/emitter/src/run-python3.ts +20 -0
  19. package/emitter/src/system-requirements.ts +261 -0
  20. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  21. package/eng/scripts/ci/regenerate.ts +16 -4
  22. package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
  23. package/eng/scripts/setup/build.ts +16 -0
  24. package/eng/scripts/setup/build_pygen_wheel.py +40 -0
  25. package/eng/scripts/setup/install.py +9 -3
  26. package/eng/scripts/setup/install.ts +32 -0
  27. package/eng/scripts/setup/prepare.py +3 -1
  28. package/eng/scripts/setup/prepare.ts +11 -0
  29. package/eng/scripts/setup/run-python3.ts +1 -6
  30. package/generator/build/lib/pygen/__init__.py +107 -0
  31. package/generator/build/lib/pygen/_version.py +7 -0
  32. package/generator/build/lib/pygen/black.py +71 -0
  33. package/generator/build/lib/pygen/codegen/__init__.py +357 -0
  34. package/generator/build/lib/pygen/codegen/_utils.py +17 -0
  35. package/generator/build/lib/pygen/codegen/models/__init__.py +204 -0
  36. package/generator/build/lib/pygen/codegen/models/base.py +186 -0
  37. package/generator/build/lib/pygen/codegen/models/base_builder.py +118 -0
  38. package/generator/build/lib/pygen/codegen/models/client.py +435 -0
  39. package/generator/build/lib/pygen/codegen/models/code_model.py +237 -0
  40. package/generator/build/lib/pygen/codegen/models/combined_type.py +149 -0
  41. package/generator/build/lib/pygen/codegen/models/constant_type.py +129 -0
  42. package/generator/build/lib/pygen/codegen/models/credential_types.py +214 -0
  43. package/generator/build/lib/pygen/codegen/models/dictionary_type.py +127 -0
  44. package/generator/build/lib/pygen/codegen/models/enum_type.py +238 -0
  45. package/generator/build/lib/pygen/codegen/models/imports.py +291 -0
  46. package/generator/build/lib/pygen/codegen/models/list_type.py +143 -0
  47. package/generator/build/lib/pygen/codegen/models/lro_operation.py +142 -0
  48. package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +32 -0
  49. package/generator/build/lib/pygen/codegen/models/model_type.py +357 -0
  50. package/generator/build/lib/pygen/codegen/models/operation.py +509 -0
  51. package/generator/build/lib/pygen/codegen/models/operation_group.py +184 -0
  52. package/generator/build/lib/pygen/codegen/models/paging_operation.py +155 -0
  53. package/generator/build/lib/pygen/codegen/models/parameter.py +412 -0
  54. package/generator/build/lib/pygen/codegen/models/parameter_list.py +387 -0
  55. package/generator/build/lib/pygen/codegen/models/primitive_types.py +659 -0
  56. package/generator/build/lib/pygen/codegen/models/property.py +170 -0
  57. package/generator/build/lib/pygen/codegen/models/request_builder.py +189 -0
  58. package/generator/build/lib/pygen/codegen/models/request_builder_parameter.py +115 -0
  59. package/generator/build/lib/pygen/codegen/models/response.py +348 -0
  60. package/generator/build/lib/pygen/codegen/models/utils.py +21 -0
  61. package/generator/build/lib/pygen/codegen/serializers/__init__.py +574 -0
  62. package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +21 -0
  63. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +1533 -0
  64. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +294 -0
  65. package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +15 -0
  66. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +213 -0
  67. package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +126 -0
  68. package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +198 -0
  69. package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +33 -0
  70. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +335 -0
  71. package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +89 -0
  72. package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +44 -0
  73. package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +221 -0
  74. package/generator/build/lib/pygen/codegen/serializers/patch_serializer.py +19 -0
  75. package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +52 -0
  76. package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +168 -0
  77. package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +292 -0
  78. package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +31 -0
  79. package/generator/build/lib/pygen/codegen/serializers/utils.py +68 -0
  80. package/generator/build/lib/pygen/codegen/templates/client.py.jinja2 +37 -0
  81. package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +12 -0
  82. package/generator/build/lib/pygen/codegen/templates/config.py.jinja2 +73 -0
  83. package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +16 -0
  84. package/generator/build/lib/pygen/codegen/templates/conftest.py.jinja2 +28 -0
  85. package/generator/build/lib/pygen/codegen/templates/enum.py.jinja2 +13 -0
  86. package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +10 -0
  87. package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +24 -0
  88. package/generator/build/lib/pygen/codegen/templates/keywords.jinja2 +27 -0
  89. package/generator/build/lib/pygen/codegen/templates/lro_operation.py.jinja2 +16 -0
  90. package/generator/build/lib/pygen/codegen/templates/lro_paging_operation.py.jinja2 +18 -0
  91. package/generator/build/lib/pygen/codegen/templates/macros.jinja2 +12 -0
  92. package/generator/build/lib/pygen/codegen/templates/metadata.json.jinja2 +167 -0
  93. package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +1174 -0
  94. package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +15 -0
  95. package/generator/build/lib/pygen/codegen/templates/model_dpg.py.jinja2 +97 -0
  96. package/generator/build/lib/pygen/codegen/templates/model_init.py.jinja2 +33 -0
  97. package/generator/build/lib/pygen/codegen/templates/model_msrest.py.jinja2 +92 -0
  98. package/generator/build/lib/pygen/codegen/templates/operation.py.jinja2 +21 -0
  99. package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +75 -0
  100. package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +19 -0
  101. package/generator/build/lib/pygen/codegen/templates/operation_tools.jinja2 +81 -0
  102. package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +17 -0
  103. package/generator/build/lib/pygen/codegen/templates/packaging_templates/CHANGELOG.md.jinja2 +6 -0
  104. package/generator/build/lib/pygen/codegen/templates/packaging_templates/LICENSE.jinja2 +21 -0
  105. package/generator/build/lib/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +8 -0
  106. package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +107 -0
  107. package/generator/build/lib/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +9 -0
  108. package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +108 -0
  109. package/generator/build/lib/pygen/codegen/templates/paging_operation.py.jinja2 +21 -0
  110. package/generator/build/lib/pygen/codegen/templates/patch.py.jinja2 +19 -0
  111. package/generator/build/lib/pygen/codegen/templates/pkgutil_init.py.jinja2 +1 -0
  112. package/generator/build/lib/pygen/codegen/templates/request_builder.py.jinja2 +28 -0
  113. package/generator/build/lib/pygen/codegen/templates/request_builders.py.jinja2 +10 -0
  114. package/generator/build/lib/pygen/codegen/templates/rest_init.py.jinja2 +12 -0
  115. package/generator/build/lib/pygen/codegen/templates/sample.py.jinja2 +44 -0
  116. package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +2117 -0
  117. package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +50 -0
  118. package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +26 -0
  119. package/generator/build/lib/pygen/codegen/templates/types.py.jinja2 +7 -0
  120. package/generator/build/lib/pygen/codegen/templates/validation.py.jinja2 +38 -0
  121. package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +96 -0
  122. package/generator/build/lib/pygen/codegen/templates/version.py.jinja2 +4 -0
  123. package/generator/build/lib/pygen/m2r.py +65 -0
  124. package/generator/build/lib/pygen/preprocess/__init__.py +515 -0
  125. package/generator/build/lib/pygen/preprocess/helpers.py +27 -0
  126. package/generator/build/lib/pygen/preprocess/python_mappings.py +226 -0
  127. package/generator/build/lib/pygen/utils.py +163 -0
  128. package/generator/component-detection-pip-report.json +134 -0
  129. package/generator/dev_requirements.txt +0 -1
  130. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  131. package/generator/pygen.egg-info/PKG-INFO +7 -4
  132. package/generator/pygen.egg-info/requires.txt +7 -4
  133. package/generator/requirements.txt +5 -10
  134. package/generator/setup.py +7 -4
  135. package/generator/test/azure/requirements.txt +1 -1
  136. package/generator/test/unbranded/requirements.txt +1 -1
  137. package/package.json +6 -5
@@ -0,0 +1,142 @@
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 Any, Dict, Optional, List, TYPE_CHECKING, TypeVar, Union
7
+ from .imports import FileImport
8
+ from .operation import OperationBase, Operation
9
+ from .response import LROPagingResponse, LROResponse, Response
10
+ from .imports import ImportType, TypingSection
11
+ from .request_builder import RequestBuilder
12
+ from .parameter_list import ParameterList
13
+
14
+ if TYPE_CHECKING:
15
+ from .code_model import CodeModel
16
+ from .client import Client
17
+ from . import OperationType
18
+
19
+ LROResponseType = TypeVar("LROResponseType", bound=Union[LROResponse, LROPagingResponse])
20
+
21
+
22
+ class LROOperationBase(OperationBase[LROResponseType]):
23
+ def __init__(
24
+ self,
25
+ yaml_data: Dict[str, Any],
26
+ code_model: "CodeModel",
27
+ client: "Client",
28
+ name: str,
29
+ request_builder: RequestBuilder,
30
+ parameters: ParameterList,
31
+ responses: List[LROResponseType],
32
+ exceptions: List[Response],
33
+ *,
34
+ overloads: Optional[List[Operation]] = None,
35
+ ) -> None:
36
+ super().__init__(
37
+ code_model=code_model,
38
+ client=client,
39
+ yaml_data=yaml_data,
40
+ name=name,
41
+ request_builder=request_builder,
42
+ parameters=parameters,
43
+ responses=responses,
44
+ exceptions=exceptions,
45
+ overloads=overloads,
46
+ )
47
+ if not self.name.lstrip("_").startswith("begin"):
48
+ self.name = ("_begin" if self.internal else "begin_") + self.name
49
+ self.lro_options: Dict[str, Any] = self.yaml_data.get("lroOptions", {})
50
+ self._initial_operation: Optional["OperationType"] = None
51
+
52
+ @property
53
+ def initial_operation(self) -> "OperationType":
54
+ if not self._initial_operation:
55
+ raise ValueError("You need to first call client.link_lro_initial_operations before accessing")
56
+ return self._initial_operation
57
+
58
+ @initial_operation.setter
59
+ def initial_operation(self, val: "OperationType") -> None:
60
+ self._initial_operation = val
61
+
62
+ @property
63
+ def operation_type(self) -> str:
64
+ return "lro"
65
+
66
+ @property
67
+ def has_optional_return_type(self) -> bool:
68
+ return False
69
+
70
+ @property
71
+ def lro_response(self) -> Optional[LROResponseType]:
72
+ responses_with_bodies = [r for r in self.responses if r.type]
73
+ num_response_schemas = {id(r.type.yaml_data) for r in responses_with_bodies if r.type}
74
+ response = None
75
+ if len(num_response_schemas) > 1:
76
+ # choose the response that has a status code of 200
77
+ try:
78
+ response = next(r for r in responses_with_bodies if 200 in r.status_codes)
79
+ except StopIteration as exc:
80
+ raise ValueError(
81
+ "Your swagger is invalid because you have multiple response schemas for LRO"
82
+ + f" method {self.name} and none of them have a 200 status code."
83
+ ) from exc
84
+
85
+ elif num_response_schemas:
86
+ response = responses_with_bodies[0]
87
+ return response
88
+
89
+ def response_type_annotation(self, **kwargs) -> str:
90
+ lro_response = self.lro_response or next(iter(self.responses), None)
91
+ if lro_response:
92
+ return lro_response.type_annotation(**kwargs)
93
+ return "None"
94
+
95
+ def cls_type_annotation(self, *, async_mode: bool) -> str:
96
+ """We don't want the poller to show up in ClsType, so we call super() on response type annotation"""
97
+ return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode)}]"
98
+
99
+ def get_poller_with_response_type(self, async_mode: bool) -> str:
100
+ return self.response_type_annotation(async_mode=async_mode)
101
+
102
+ def get_poller(self, async_mode: bool) -> str:
103
+ return self.responses[0].get_poller(async_mode)
104
+
105
+ def get_polling_method(self, async_mode: bool) -> str:
106
+ return self.responses[0].get_polling_method(async_mode)
107
+
108
+ def get_base_polling_method(self, async_mode: bool) -> str:
109
+ return self.responses[0].get_base_polling_method(async_mode)
110
+
111
+ def get_base_polling_method_path(self, async_mode: bool) -> str:
112
+ return self.responses[0].get_base_polling_method_path(async_mode)
113
+
114
+ def get_no_polling_method(self, async_mode: bool) -> str:
115
+ return self.responses[0].get_no_polling_method(async_mode)
116
+
117
+ def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
118
+ file_import = super().imports(async_mode, **kwargs)
119
+ if self.abstract:
120
+ return file_import
121
+ if async_mode and self.code_model.options["tracing"] and self.want_tracing:
122
+ file_import.add_submodule_import(
123
+ "azure.core.tracing.decorator_async",
124
+ "distributed_trace_async",
125
+ ImportType.SDKCORE,
126
+ )
127
+ if (
128
+ self.code_model.options["models_mode"] == "dpg"
129
+ and self.lro_response
130
+ and self.lro_response.type
131
+ and self.lro_response.type.type == "model"
132
+ ):
133
+ # used in the case if initial operation returns none
134
+ # but final call returns a model
135
+ relative_path = "..." if async_mode else ".."
136
+ file_import.add_submodule_import(f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL)
137
+ file_import.add_submodule_import("typing", "Union", ImportType.STDLIB, TypingSection.CONDITIONAL)
138
+ file_import.add_submodule_import("typing", "cast", ImportType.STDLIB)
139
+ return file_import
140
+
141
+
142
+ class LROOperation(LROOperationBase[LROResponse]): ...
@@ -0,0 +1,32 @@
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 Any, List, Union
7
+ from .imports import FileImport
8
+ from .lro_operation import LROOperationBase
9
+ from .paging_operation import PagingOperationBase
10
+ from .response import LROPagingResponse, Response
11
+
12
+
13
+ class LROPagingOperation(LROOperationBase[LROPagingResponse], PagingOperationBase[LROPagingResponse]):
14
+ @property
15
+ def success_status_codes(self) -> List[Union[int, str, List[int]]]:
16
+ """The list of all successfull status code."""
17
+ return [200]
18
+
19
+ @property
20
+ def operation_type(self) -> str:
21
+ return "lropaging"
22
+
23
+ def cls_type_annotation(self, *, async_mode: bool) -> str:
24
+ return f"ClsType[{Response.type_annotation(self.responses[0], async_mode=async_mode)}]"
25
+
26
+ def imports(self, async_mode: bool, **kwargs: Any) -> FileImport:
27
+ lro_imports = LROOperationBase.imports(self, async_mode, **kwargs)
28
+ paging_imports = PagingOperationBase.imports(self, async_mode, **kwargs)
29
+
30
+ file_import = lro_imports
31
+ file_import.merge(paging_imports)
32
+ return file_import
@@ -0,0 +1,357 @@
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 enum import Enum
7
+ from collections import OrderedDict
8
+ from typing import Any, Dict, List, Optional, TYPE_CHECKING, cast
9
+ import sys
10
+ from .utils import add_to_pylint_disable
11
+ from .base import BaseType
12
+ from .constant_type import ConstantType
13
+ from .property import Property
14
+ from .imports import FileImport, ImportType, TypingSection
15
+ from ...utils import NAME_LENGTH_LIMIT
16
+
17
+ if sys.version_info >= (3, 8):
18
+ from typing import Literal
19
+ else:
20
+ from typing_extensions import Literal # type: ignore
21
+
22
+ if TYPE_CHECKING:
23
+ from .code_model import CodeModel
24
+
25
+
26
+ class UsageFlags(Enum):
27
+ Default = 0
28
+ Input = 2
29
+ Output = 4
30
+ ApiVersionEnum = 8
31
+ JsonMergePatch = 16
32
+ MultipartFormData = 32
33
+ Spread = 64
34
+ Error = 128
35
+ Json = 256
36
+ Xml = 512
37
+
38
+
39
+ def _get_properties(type: "ModelType", properties: List[Property]) -> List[Property]:
40
+ for parent in type.parents:
41
+ # here we're adding the properties from our parents
42
+
43
+ # need to make sure that the properties we choose from our parent also don't contain
44
+ # any of our own properties
45
+ property_names = set([p.client_name for p in properties] + [p.client_name for p in type.properties])
46
+ chosen_parent_properties = [p for p in parent.properties if p.client_name not in property_names]
47
+ properties = _get_properties(parent, chosen_parent_properties) + properties
48
+ return properties
49
+
50
+
51
+ class ModelType(BaseType): # pylint: disable=too-many-instance-attributes, too-many-public-methods
52
+ """Represents a class ready to be serialized in Python.
53
+
54
+ :param str name: The name of the class.
55
+ :param str description: The description of the class.
56
+ :param properties: the optional properties of the class.
57
+ :type properties: dict(str, str)
58
+ """
59
+
60
+ base: Literal["msrest", "dpg", "json"]
61
+
62
+ def __init__(
63
+ self,
64
+ yaml_data: Dict[str, Any],
65
+ code_model: "CodeModel",
66
+ *,
67
+ properties: Optional[List[Property]] = None,
68
+ parents: Optional[List["ModelType"]] = None,
69
+ discriminated_subtypes: Optional[Dict[str, "ModelType"]] = None,
70
+ ) -> None:
71
+ super().__init__(yaml_data=yaml_data, code_model=code_model)
72
+ self.name: str = self.yaml_data["name"]
73
+ self.max_properties: Optional[int] = self.yaml_data.get("maxProperties")
74
+ self.min_properties: Optional[int] = self.yaml_data.get("minProperties")
75
+ self.properties = properties or []
76
+ self.parents = parents or []
77
+ self.discriminated_subtypes = discriminated_subtypes or {}
78
+ self.discriminator_value: Optional[str] = self.yaml_data.get("discriminatorValue")
79
+ self._created_json_template_representation = False
80
+ self._got_polymorphic_subtypes = False
81
+ self.internal: bool = self.yaml_data.get("internal", False)
82
+ self.snake_case_name: str = self.yaml_data["snakeCaseName"]
83
+ self.cross_language_definition_id: Optional[str] = self.yaml_data.get("crossLanguageDefinitionId")
84
+ self.usage: int = self.yaml_data.get("usage", UsageFlags.Input.value | UsageFlags.Output.value)
85
+
86
+ @property
87
+ def is_usage_output(self) -> bool:
88
+ return bool(self.usage & UsageFlags.Output.value)
89
+
90
+ @property
91
+ def flattened_property(self) -> Optional[Property]:
92
+ try:
93
+ return next(p for p in self.properties if p.flatten)
94
+ except StopIteration:
95
+ return None
96
+
97
+ @property
98
+ def flattened_items(self) -> List[str]:
99
+ return [
100
+ item.client_name
101
+ for prop in self.properties
102
+ if isinstance(prop.type, ModelType) and prop.flatten
103
+ for item in prop.type.properties
104
+ ]
105
+
106
+ @property
107
+ def is_form_data(self) -> bool:
108
+ return any(p.is_multipart_file_input for p in self.properties)
109
+
110
+ @property
111
+ def is_xml(self) -> bool:
112
+ return self.yaml_data.get("isXml", False)
113
+
114
+ @property
115
+ def msrest_deserialization_key(self) -> str:
116
+ return self.name
117
+
118
+ @property
119
+ def is_polymorphic(self) -> bool:
120
+ return any(p.is_polymorphic for p in self.properties)
121
+
122
+ def description(self, *, is_operation_file: bool = False) -> str:
123
+ return "" if is_operation_file else self.yaml_data.get("description", self.name)
124
+
125
+ def get_declaration(self, value: Any) -> str:
126
+ return f"{self.name}()"
127
+
128
+ def __repr__(self) -> str:
129
+ return f"<{self.__class__.__name__} {self.name}>"
130
+
131
+ @property
132
+ def xml_serialization_ctxt(self) -> Optional[str]:
133
+ # object schema contains _xml_map, they don't need serialization context
134
+ return ""
135
+
136
+ @property
137
+ def xml_map_content(self) -> Optional[str]:
138
+ # This is NOT an error on the super call, we use the serialization context for "xml_map",
139
+ # but we don't want to write a serialization context for an object.
140
+ return super().xml_serialization_ctxt
141
+
142
+ @property
143
+ def discriminated_subtypes_name_mapping(self) -> Dict[str, str]:
144
+ return {k: v.name for k, v in self.discriminated_subtypes.items()}
145
+
146
+ def get_json_template_representation(
147
+ self,
148
+ *,
149
+ client_default_value_declaration: Optional[str] = None,
150
+ ) -> Any:
151
+ if self._created_json_template_representation:
152
+ return "..." # do this to avoid loop
153
+ self._created_json_template_representation = True
154
+ if self.discriminated_subtypes:
155
+ # we will instead print the discriminated subtypes
156
+ self._created_json_template_representation = False
157
+ return f'"{self.snake_case_name}"' if self.code_model.for_test else self.snake_case_name
158
+
159
+ # don't add additional properties, because there's not really a concept of
160
+ # additional properties in the template
161
+ representation = {
162
+ f'"{prop.wire_name}"': prop.get_json_template_representation(
163
+ client_default_value_declaration=client_default_value_declaration,
164
+ )
165
+ for prop in [
166
+ p for p in self.properties if not (p.is_discriminator or p.client_name == "additional_properties")
167
+ ]
168
+ }
169
+ if self.discriminator and self.discriminator_value:
170
+ representation[f'"{self.discriminator.wire_name}"'] = f'"{self.discriminator_value}"'
171
+
172
+ # once we've finished, we want to reset created_json_template_representation to false
173
+ # so we can call it again
174
+ self._created_json_template_representation = False
175
+ optional_keys = [f'"{p.wire_name}"' for p in self.properties if getattr(p, "optional", False)]
176
+ return OrderedDict(
177
+ sorted(
178
+ representation.items(),
179
+ key=lambda item: f"{1 if item[0] in optional_keys else 0}{item[0]}",
180
+ )
181
+ )
182
+
183
+ def get_polymorphic_subtypes(self, polymorphic_subtypes: List["ModelType"]) -> None:
184
+ is_polymorphic_subtype = self.discriminator_value and not self.discriminated_subtypes
185
+ if self._got_polymorphic_subtypes:
186
+ return
187
+ self._got_polymorphic_subtypes = True
188
+ if self.name not in (m.name for m in polymorphic_subtypes) and is_polymorphic_subtype:
189
+ polymorphic_subtypes.append(self)
190
+ for discriminated_subtype in self.discriminated_subtypes.values():
191
+ discriminated_subtype.get_polymorphic_subtypes(polymorphic_subtypes)
192
+ for property in self.properties:
193
+ property.get_polymorphic_subtypes(polymorphic_subtypes)
194
+ self._got_polymorphic_subtypes = False
195
+
196
+ @classmethod
197
+ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel") -> "ModelType":
198
+ raise ValueError(
199
+ "You shouldn't call from_yaml for ModelType to avoid recursion. "
200
+ "Please initial a blank ModelType, then call .fill_instance_from_yaml on the created type."
201
+ )
202
+
203
+ def fill_instance_from_yaml(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
204
+ from . import build_type
205
+
206
+ self.parents = [cast(ModelType, build_type(bm, code_model)) for bm in yaml_data.get("parents", [])]
207
+ properties = [Property.from_yaml(p, code_model) for p in yaml_data["properties"]]
208
+ self.properties = _get_properties(self, properties)
209
+ # checking to see if this is a polymorphic class
210
+ self.discriminated_subtypes = {
211
+ k: cast(ModelType, build_type(v, code_model))
212
+ for k, v in self.yaml_data.get("discriminatedSubtypes", {}).items()
213
+ }
214
+
215
+ @property
216
+ def has_readonly_or_constant_property(self) -> bool:
217
+ return any(x.readonly or x.constant or x.visibility == ["read"] for x in self.properties)
218
+
219
+ @property
220
+ def discriminator(self) -> Optional[Property]:
221
+ try:
222
+ return next(p for p in self.properties if p.is_discriminator)
223
+ except StopIteration:
224
+ return None
225
+
226
+ @property
227
+ def discriminator_property(self) -> Optional[Property]:
228
+ try:
229
+ return next(
230
+ p
231
+ for p in self.properties
232
+ if p.is_discriminator and isinstance(p.type, ConstantType) and p.type.value == self.discriminator_value
233
+ )
234
+ except StopIteration:
235
+ return None
236
+
237
+ def pylint_disable(self) -> str:
238
+ retval: str = ""
239
+ if len(self.name) > NAME_LENGTH_LIMIT:
240
+ retval = add_to_pylint_disable(retval, "name-too-long")
241
+ return retval
242
+
243
+ @property
244
+ def init_pylint_disable(self) -> str:
245
+ retval: str = ""
246
+ if len(self.properties) > 23:
247
+ retval = add_to_pylint_disable(retval, "too-many-locals")
248
+ return retval
249
+
250
+
251
+ class JSONModelType(ModelType):
252
+ base = "json"
253
+
254
+ def type_annotation(self, **kwargs: Any) -> str:
255
+ return "ET.Element" if self.is_xml else "JSON"
256
+
257
+ @property
258
+ def serialization_type(self) -> str:
259
+ return "object"
260
+
261
+ def docstring_type(self, **kwargs: Any) -> str:
262
+ return "ET.Element" if self.is_xml else "JSON"
263
+
264
+ def docstring_text(self, **kwargs: Any) -> str:
265
+ return "XML Element" if self.is_xml else "JSON object"
266
+
267
+ @property
268
+ def instance_check_template(self) -> str:
269
+ return "isinstance({}, MutableMapping)"
270
+
271
+ def imports(self, **kwargs: Any) -> FileImport:
272
+ file_import = FileImport(self.code_model)
273
+ file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
274
+ file_import.define_mutable_mapping_type()
275
+ if self.is_xml:
276
+ file_import.add_submodule_import("xml.etree", "ElementTree", ImportType.STDLIB, alias="ET")
277
+ return file_import
278
+
279
+
280
+ class GeneratedModelType(ModelType):
281
+ def type_annotation(self, **kwargs: Any) -> str:
282
+ is_operation_file = kwargs.pop("is_operation_file", False)
283
+ skip_quote = kwargs.get("skip_quote", False)
284
+ module_name = "_models." if kwargs.get("need_module_name", True) else ""
285
+ file_name = f"{self.code_model.models_filename}." if self.internal else ""
286
+ retval = module_name + file_name + self.name
287
+ return retval if is_operation_file or skip_quote else f'"{retval}"'
288
+
289
+ def docstring_type(self, **kwargs: Any) -> str:
290
+ return f"~{self.code_model.namespace}.models.{self.type_annotation(need_module_name=False, skip_quote=True)}"
291
+
292
+ def docstring_text(self, **kwargs: Any) -> str:
293
+ return self.name
294
+
295
+ @property
296
+ def type_description(self) -> str:
297
+ return self.name
298
+
299
+ def imports(self, **kwargs: Any) -> FileImport:
300
+ file_import = super().imports(**kwargs)
301
+ relative_path = kwargs.pop("relative_path", None)
302
+ if relative_path:
303
+ # add import for models in operations or _types file
304
+ file_import.add_submodule_import(
305
+ relative_path,
306
+ "models",
307
+ ImportType.LOCAL,
308
+ alias="_models",
309
+ typing_section=(TypingSection.TYPING if kwargs.get("model_typing") else TypingSection.REGULAR),
310
+ )
311
+ if self.is_form_data:
312
+ file_import.add_submodule_import(
313
+ relative_path,
314
+ "_model_base",
315
+ ImportType.LOCAL,
316
+ typing_section=(TypingSection.TYPING if kwargs.get("model_typing") else TypingSection.REGULAR),
317
+ )
318
+ return file_import
319
+
320
+
321
+ class MsrestModelType(GeneratedModelType):
322
+ base = "msrest"
323
+
324
+ @property
325
+ def serialization_type(self) -> str:
326
+ return self.type_annotation(skip_quote=True) if self.internal else self.name
327
+
328
+ @property
329
+ def instance_check_template(self) -> str:
330
+ return "isinstance({}, msrest.Model)"
331
+
332
+ def imports(self, **kwargs: Any) -> FileImport:
333
+ file_import = super().imports(**kwargs)
334
+ file_import.add_submodule_import("typing", "Any", ImportType.STDLIB, TypingSection.CONDITIONAL)
335
+ return file_import
336
+
337
+
338
+ class DPGModelType(GeneratedModelType):
339
+ base = "dpg"
340
+
341
+ @property
342
+ def serialization_type(self) -> str:
343
+ return (
344
+ self.type_annotation(skip_quote=True)
345
+ if self.internal
346
+ else self.type_annotation(need_module_name=False, skip_quote=True)
347
+ )
348
+
349
+ @property
350
+ def instance_check_template(self) -> str:
351
+ return "isinstance({}, " + f"_models.{self.name})"
352
+
353
+ def imports(self, **kwargs: Any) -> FileImport:
354
+ file_import = super().imports(**kwargs)
355
+ if self.flattened_property:
356
+ file_import.add_submodule_import("typing", "Any", ImportType.STDLIB)
357
+ return file_import