@autorest/python 6.13.7 → 6.13.9

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.
@@ -38,6 +38,7 @@ class OptionsRetriever:
38
38
  "polymorphic-examples": 5,
39
39
  "generate-sample": False,
40
40
  "from-typespec": False,
41
+ "emit-cross-language-definition-file": False,
41
42
  }
42
43
 
43
44
  @property
@@ -333,6 +334,7 @@ class CodeGenerator(Plugin):
333
334
  "from_typespec",
334
335
  "flavor",
335
336
  "company_name",
337
+ "emit_cross_language_definition_file",
336
338
  ]
337
339
  return {f: getattr(self.options_retriever, f) for f in flags}
338
340
 
@@ -75,6 +75,7 @@ class CodeModel: # pylint: disable=too-many-public-methods, disable=too-many-in
75
75
  self.named_unions: List[CombinedType] = [
76
76
  t for t in self.types_map.values() if isinstance(t, CombinedType) and t.name
77
77
  ]
78
+ self.cross_language_package_id = self.yaml_data.get("crossLanguagePackageId")
78
79
 
79
80
  @property
80
81
  def has_form_data(self) -> bool:
@@ -4,7 +4,7 @@
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
6
  import logging
7
- from typing import Dict, Any, Optional, TYPE_CHECKING
7
+ from typing import Dict, Any, Optional, TYPE_CHECKING, Union
8
8
  from .base import BaseType
9
9
  from .imports import FileImport, ImportType, TypingSection
10
10
  from .primitive_types import IntegerType, BinaryType, StringType, BooleanType
@@ -31,7 +31,7 @@ class ConstantType(BaseType):
31
31
  yaml_data: Dict[str, Any],
32
32
  code_model: "CodeModel",
33
33
  value_type: BaseType,
34
- value: Optional[str],
34
+ value: Optional[Union[str, int, float]],
35
35
  ) -> None:
36
36
  super().__init__(yaml_data=yaml_data, code_model=code_model)
37
37
  self.value_type = value_type
@@ -101,11 +101,10 @@ class EnumValue(BaseType):
101
101
  """
102
102
  from . import build_type
103
103
 
104
- enum_type = cast(EnumType, code_model.lookup_type(id(yaml_data["enumType"])))
105
104
  return cls(
106
105
  yaml_data=yaml_data,
107
106
  code_model=code_model,
108
- enum_type=enum_type,
107
+ enum_type=cast(EnumType, build_type(yaml_data["enumType"], code_model)),
109
108
  value_type=build_type(yaml_data["valueType"], code_model),
110
109
  )
111
110
 
@@ -134,6 +133,9 @@ class EnumType(BaseType):
134
133
  self.values = values
135
134
  self.value_type = value_type
136
135
  self.internal: bool = self.yaml_data.get("internal", False)
136
+ self.cross_language_definition_id: Optional[str] = self.yaml_data.get(
137
+ "crossLanguageDefinitionId"
138
+ )
137
139
 
138
140
  def __lt__(self, other):
139
141
  return self.name.lower() < other.name.lower()
@@ -75,6 +75,9 @@ class ModelType( # pylint: disable=abstract-method
75
75
  self.internal: bool = self.yaml_data.get("internal", False)
76
76
  self.snake_case_name: str = self.yaml_data["snakeCaseName"]
77
77
  self.page_result_model: bool = self.yaml_data.get("pageResultModel", False)
78
+ self.cross_language_definition_id: Optional[str] = self.yaml_data.get(
79
+ "crossLanguageDefinitionId"
80
+ )
78
81
 
79
82
  @property
80
83
  def flattened_property(self) -> Optional[Property]:
@@ -54,7 +54,7 @@ def is_internal(target: Optional[BaseType]) -> bool:
54
54
  return isinstance(target, ModelType) and target.base == "dpg" and target.internal
55
55
 
56
56
 
57
- class OperationBase( # pylint: disable=too-many-public-methods
57
+ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instance-attributes
58
58
  Generic[ResponseType], BaseBuilder[ParameterList, List["Operation"]]
59
59
  ):
60
60
  def __init__(
@@ -91,6 +91,9 @@ class OperationBase( # pylint: disable=too-many-public-methods
91
91
  if self.internal:
92
92
  self.name = "_" + self.name
93
93
  self.has_etag: bool = self.yaml_data.get("hasEtag", False)
94
+ self.cross_language_definition_id: Optional[str] = self.yaml_data.get(
95
+ "crossLanguageDefinitionId"
96
+ )
94
97
 
95
98
  @property
96
99
  def has_form_data_body(self):
@@ -386,6 +389,18 @@ class OperationBase( # pylint: disable=too-many-public-methods
386
389
  file_import.add_submodule_import(
387
390
  "azure.mgmt.core.exceptions", "ARMErrorFormat", ImportType.SDKCORE
388
391
  )
392
+ file_import.add_submodule_import(
393
+ "typing",
394
+ "Type",
395
+ ImportType.STDLIB,
396
+ )
397
+ file_import.add_mutable_mapping_import()
398
+ if self.non_default_error_status_codes:
399
+ file_import.add_submodule_import(
400
+ "typing",
401
+ "cast",
402
+ ImportType.STDLIB,
403
+ )
389
404
 
390
405
  if self.has_kwargs_to_pop_with_default(
391
406
  self.parameters.kwargs_to_pop, ParameterLocation.HEADER # type: ignore
@@ -478,6 +493,10 @@ class OperationBase( # pylint: disable=too-many-public-methods
478
493
  )
479
494
  if self.overloads:
480
495
  file_import.add_submodule_import("typing", "overload", ImportType.STDLIB)
496
+ if self.non_default_errors and self.code_model.options["models_mode"] == "dpg":
497
+ file_import.add_submodule_import(
498
+ f"{relative_path}_model_base", "_deserialize", ImportType.LOCAL
499
+ )
481
500
  return file_import
482
501
 
483
502
  def get_response_from_status(
@@ -63,7 +63,7 @@ class _ParameterBase(
63
63
  type: BaseType,
64
64
  ) -> None:
65
65
  super().__init__(yaml_data, code_model)
66
- self.wire_name: str = yaml_data["wireName"]
66
+ self.wire_name: str = yaml_data.get("wireName", "")
67
67
  self.client_name: str = self.yaml_data["clientName"]
68
68
  self.optional: bool = self.yaml_data["optional"]
69
69
  self.location: ParameterLocation = self.yaml_data["location"]
@@ -373,7 +373,7 @@ class Parameter(_ParameterBase):
373
373
  return ParameterMethodLocation.KEYWORD_ONLY
374
374
  if self.grouper:
375
375
  return ParameterMethodLocation.POSITIONAL
376
- if self.constant:
376
+ if self.constant and self.wire_name != "Content-Type":
377
377
  return ParameterMethodLocation.KWARG
378
378
  if self.is_content_type:
379
379
  if self.in_overload:
@@ -37,10 +37,12 @@ class ResponseHeader(BaseModel):
37
37
  def from_yaml(
38
38
  cls, yaml_data: Dict[str, Any], code_model: "CodeModel"
39
39
  ) -> "ResponseHeader":
40
+ from . import build_type
41
+
40
42
  return cls(
41
43
  yaml_data=yaml_data,
42
44
  code_model=code_model,
43
- type=code_model.lookup_type(id(yaml_data["type"])),
45
+ type=build_type(yaml_data["type"], code_model),
44
46
  )
45
47
 
46
48
 
@@ -522,6 +522,11 @@ class JinjaSerializer(ReaderAndWriter): # pylint: disable=abstract-method
522
522
  namespace_path / Path("_validation.py"),
523
523
  general_serializer.serialize_validation_file(),
524
524
  )
525
+ if self.code_model.options.get("emit_cross_language_definition_file"):
526
+ self.write_file(
527
+ namespace_path / Path("apiview_mapping_python.json"),
528
+ general_serializer.serialize_cross_language_definition_file(),
529
+ )
525
530
 
526
531
  # Write the setup file
527
532
  if self.code_model.options["basic_setup_py"]:
@@ -639,6 +639,7 @@ class _OperationSerializer(
639
639
  discriminator_name = cast(
640
640
  Property, polymorphic_subtypes[0].discriminator
641
641
  ).wire_name
642
+ retval.append("")
642
643
  retval.append(
643
644
  "# The response is polymorphic. The following are possible polymorphic "
644
645
  f'responses based off discriminator "{discriminator_name}":'
@@ -1280,7 +1281,7 @@ class _OperationSerializer(
1280
1281
  return retval
1281
1282
 
1282
1283
  def error_map(self, builder: OperationType) -> List[str]:
1283
- retval = ["error_map = {"]
1284
+ retval = ["error_map: MutableMapping[int, Type[HttpResponseError]] = {"]
1284
1285
  if builder.non_default_errors:
1285
1286
  if not 401 in builder.non_default_error_status_codes:
1286
1287
  retval.append(" 401: ClientAuthenticationError,")
@@ -1308,30 +1309,35 @@ class _OperationSerializer(
1308
1309
  for status_code in excep.status_codes:
1309
1310
  if status_code == 401:
1310
1311
  retval.append(
1311
- " 401: lambda response: ClientAuthenticationError(response=response"
1312
- f"{error_model_str}{error_format_str}),"
1312
+ " 401: cast(Type[HttpResponseError], "
1313
+ "lambda response: ClientAuthenticationError(response=response"
1314
+ f"{error_model_str}{error_format_str})),"
1313
1315
  )
1314
1316
  elif status_code == 404:
1315
1317
  retval.append(
1316
- " 404: lambda response: ResourceNotFoundError(response=response"
1317
- f"{error_model_str}{error_format_str}),"
1318
+ " 404: cast(Type[HttpResponseError], "
1319
+ "lambda response: ResourceNotFoundError(response=response"
1320
+ f"{error_model_str}{error_format_str})),"
1318
1321
  )
1319
1322
  elif status_code == 409:
1320
1323
  retval.append(
1321
- " 409: lambda response: ResourceExistsError(response=response"
1322
- f"{error_model_str}{error_format_str}),"
1324
+ " 409: cast(Type[HttpResponseError], "
1325
+ "lambda response: ResourceExistsError(response=response"
1326
+ f"{error_model_str}{error_format_str})),"
1323
1327
  )
1324
1328
  elif status_code == 304:
1325
1329
  retval.append(
1326
- " 304: lambda response: ResourceNotModifiedError(response=response"
1327
- f"{error_model_str}{error_format_str}),"
1330
+ " 304: cast(Type[HttpResponseError], "
1331
+ "lambda response: ResourceNotModifiedError(response=response"
1332
+ f"{error_model_str}{error_format_str})),"
1328
1333
  )
1329
1334
  elif not error_model_str and not error_format_str:
1330
1335
  retval.append(f" {status_code}: HttpResponseError,")
1331
1336
  else:
1332
1337
  retval.append(
1333
- f" {status_code}: lambda response: HttpResponseError(response=response"
1334
- f"{error_model_str}{error_format_str}),"
1338
+ f" {status_code}: cast(Type[HttpResponseError], "
1339
+ "lambda response: HttpResponseError(response=response"
1340
+ f"{error_model_str}{error_format_str})),"
1335
1341
  )
1336
1342
  else:
1337
1343
  retval.append(
@@ -3,6 +3,7 @@
3
3
  # Licensed under the MIT License. See License.txt in the project root for
4
4
  # license information.
5
5
  # --------------------------------------------------------------------------
6
+ import json
6
7
  from typing import Any, List
7
8
  from jinja2 import Environment
8
9
  from .import_serializer import FileImportSerializer, TypingSection
@@ -196,3 +197,39 @@ class GeneralSerializer(BaseSerializer):
196
197
  def serialize_validation_file(self) -> str:
197
198
  template = self.env.get_template("validation.py.jinja2")
198
199
  return template.render(code_model=self.code_model)
200
+
201
+ def serialize_cross_language_definition_file(self) -> str:
202
+ cross_langauge_def_dict = {
203
+ f"{self.code_model.namespace}.models.{model.name}": model.cross_language_definition_id
204
+ for model in self.code_model.model_types
205
+ }
206
+ cross_langauge_def_dict.update(
207
+ {
208
+ f"{self.code_model.namespace}.models.{enum.name}": enum.cross_language_definition_id
209
+ for enum in self.code_model.enums
210
+ }
211
+ )
212
+ cross_langauge_def_dict.update(
213
+ {
214
+ (
215
+ f"{self.code_model.namespace}.{client.name}."
216
+ + (
217
+ ""
218
+ if operation_group.is_mixin
219
+ else f"{operation_group.property_name}."
220
+ )
221
+ + f"{operation.name}"
222
+ ): operation.cross_language_definition_id
223
+ for client in self.code_model.clients
224
+ for operation_group in client.operation_groups
225
+ for operation in operation_group.operations
226
+ if not operation.name.startswith("_")
227
+ }
228
+ )
229
+ return json.dumps(
230
+ {
231
+ "CrossLanguagePackageId": self.code_model.cross_language_package_id,
232
+ "CrossLanguageDefinitionId": cross_langauge_def_dict,
233
+ },
234
+ indent=4,
235
+ )
@@ -28,7 +28,7 @@ section of the project.
28
28
 
29
29
  ## Getting started
30
30
 
31
- ### Installating the package
31
+ ### Install the package
32
32
 
33
33
  ```bash
34
34
  python -m pip install {{ package_name }}
@@ -87,12 +87,12 @@ setup(
87
87
  {% if code_model.is_legacy %}
88
88
  "msrest>=0.7.1",
89
89
  {% else %}
90
- "isodate<1.0.0,>=0.6.1",
90
+ "isodate>=0.6.1",
91
91
  {% endif %}
92
92
  {% if azure_arm %}
93
- "azure-mgmt-core<2.0.0,>=1.3.2",
93
+ "azure-mgmt-core>=1.3.2",
94
94
  {% elif code_model.is_azure_flavor %}
95
- "azure-core<2.0.0,>=1.30.0",
95
+ "azure-core>=1.30.0",
96
96
  {% else %}
97
97
  "corehttp[requests]",
98
98
  {% endif %}
@@ -25,15 +25,18 @@ def update_overload_section(
25
25
  yaml_data: Dict[str, Any],
26
26
  section: str,
27
27
  ):
28
- for overload_s, original_s in zip(overload[section], yaml_data[section]):
29
- if overload_s.get("type"):
30
- overload_s["type"] = original_s["type"]
31
- if overload_s.get("headers"):
32
- for overload_h, original_h in zip(
33
- overload_s["headers"], original_s["headers"]
34
- ):
35
- if overload_h.get("type"):
36
- overload_h["type"] = original_h["type"]
28
+ try:
29
+ for overload_s, original_s in zip(overload[section], yaml_data[section]):
30
+ if overload_s.get("type"):
31
+ overload_s["type"] = original_s["type"]
32
+ if overload_s.get("headers"):
33
+ for overload_h, original_h in zip(
34
+ overload_s["headers"], original_s["headers"]
35
+ ):
36
+ if overload_h.get("type"):
37
+ overload_h["type"] = original_h["type"]
38
+ except KeyError as exc:
39
+ raise ValueError(overload["name"]) from exc
37
40
 
38
41
 
39
42
  def add_overload(
@@ -390,6 +393,11 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
390
393
  and wire_name_lower in HEADERS_CONVERT_IN_METHOD
391
394
  ):
392
395
  headers_convert(yaml_data, HEADERS_CONVERT_IN_METHOD[wire_name_lower])
396
+ if (
397
+ wire_name_lower in ["$host", "content-type", "accept"]
398
+ and yaml_data["type"]["type"] == "constant"
399
+ ):
400
+ yaml_data["clientDefaultValue"] = yaml_data["type"]["value"]
393
401
 
394
402
  def update_operation(
395
403
  self,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "6.13.7",
3
+ "version": "6.13.9",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "main": "index.js",
6
6
  "repository": {