@autorest/python 6.16.0 → 6.17.1

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.
@@ -54,7 +54,7 @@ class ReaderAndWriter:
54
54
  fd.write(file_content)
55
55
 
56
56
  def list_file(self) -> List[str]:
57
- return [str(f) for f in self.output_folder.glob("**/*") if f.is_file()]
57
+ return [str(f.relative_to(self.output_folder)) for f in self.output_folder.glob("**/*") if f.is_file()]
58
58
 
59
59
 
60
60
  class Plugin(ReaderAndWriter, ABC):
@@ -37,15 +37,14 @@ class BlackScriptPlugin(Plugin): # pylint: disable=abstract-method
37
37
  [
38
38
  Path(f)
39
39
  for f in self.list_file()
40
- if all(
41
- item not in f
42
- for item in (
43
- "__pycache__",
44
- "node_modules",
45
- ".tox",
46
- ".mypy_cache",
47
- )
40
+ if Path(f).parts[0]
41
+ not in (
42
+ "__pycache__",
43
+ "node_modules",
44
+ "venv",
45
+ "env",
48
46
  )
47
+ and not Path(f).parts[0].startswith(".")
49
48
  and Path(f).suffix == ".py"
50
49
  ],
51
50
  )
@@ -32,6 +32,10 @@ class UsageFlags(Enum):
32
32
  ApiVersionEnum = 8
33
33
  JsonMergePatch = 16
34
34
  MultipartFormData = 32
35
+ Spread = 64
36
+ Error = 128
37
+ Json = 256
38
+ Xml = 512
35
39
 
36
40
 
37
41
  def _get_properties(type: "ModelType", properties: List[Property]) -> List[Property]:
@@ -86,7 +90,7 @@ class ModelType( # pylint: disable=abstract-method
86
90
 
87
91
  @property
88
92
  def is_usage_output(self) -> bool:
89
- return self.usage == UsageFlags.Output.value
93
+ return self.usage & UsageFlags.Output.value
90
94
 
91
95
  @property
92
96
  def flattened_property(self) -> Optional[Property]:
@@ -495,7 +495,9 @@ class Operation(OperationBase[Response]):
495
495
  relative_path = "..." if async_mode else ".."
496
496
  if self.code_model.options["models_mode"] == "dpg":
497
497
  if self.parameters.has_body:
498
- if not self.has_form_data_body:
498
+ if self.has_form_data_body:
499
+ file_import.add_submodule_import(relative_path, "_model_base", ImportType.LOCAL)
500
+ else:
499
501
  file_import.add_submodule_import(
500
502
  f"{relative_path}_model_base",
501
503
  "SdkJSONEncoder",
@@ -114,7 +114,7 @@ class OperationGroup(BaseModel):
114
114
  and not self.is_mixin
115
115
  ):
116
116
  file_import.add_submodule_import(relative_path, "models", ImportType.LOCAL, alias="_models")
117
- if self.code_model.need_mixin_abc:
117
+ if self.is_mixin:
118
118
  file_import.add_submodule_import(".._vendor", f"{self.client.name}MixinABC", ImportType.LOCAL)
119
119
  if self.has_abstract_operations:
120
120
  file_import.add_submodule_import(".._vendor", "raise_if_not_implemented", ImportType.LOCAL)
@@ -58,6 +58,10 @@ OperationType = TypeVar(
58
58
  )
59
59
 
60
60
 
61
+ def _all_same(data: List[List[str]]) -> bool:
62
+ return len(data) > 1 and all(sorted(data[0]) == sorted(data[i]) for i in range(1, len(data)))
63
+
64
+
61
65
  def _json_serializable(content_type: str) -> bool:
62
66
  return bool(JSON_REGEXP.match(content_type.split(";")[0].strip().lower()))
63
67
 
@@ -905,6 +909,9 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
905
909
  builder: OperationType,
906
910
  response: Response,
907
911
  ) -> List[str]:
912
+ return self.response_headers(response) + self.response_deserialization(builder, response)
913
+
914
+ def response_headers(self, response: Response) -> List[str]:
908
915
  retval: List[str] = [
909
916
  (
910
917
  f"response_headers['{response_header.wire_name}']=self._deserialize("
@@ -914,6 +921,14 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
914
921
  ]
915
922
  if response.headers:
916
923
  retval.append("")
924
+ return retval
925
+
926
+ def response_deserialization(
927
+ self,
928
+ builder: OperationType,
929
+ response: Response,
930
+ ) -> List[str]:
931
+ retval: List[str] = []
917
932
  deserialize_code: List[str] = []
918
933
  stream_logic = True
919
934
  if builder.has_stream_response:
@@ -1018,13 +1033,34 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]): # pylint: di
1018
1033
  retval.append("response_headers = {}")
1019
1034
  if builder.has_response_body or builder.any_response_has_headers:
1020
1035
  if len(builder.responses) > 1:
1036
+ status_codes, res_headers, res_deserialization = [], [], []
1021
1037
  for status_code in builder.success_status_codes:
1022
1038
  response = builder.get_response_from_status(status_code)
1023
1039
  if response.headers or response.type:
1040
+ status_codes.append(status_code)
1041
+ res_headers.append(self.response_headers(response))
1042
+ res_deserialization.append(self.response_deserialization(builder, response))
1043
+
1044
+ is_headers_same = _all_same(res_headers)
1045
+ is_deserialization_same = _all_same(res_deserialization)
1046
+ if is_deserialization_same:
1047
+ if is_headers_same:
1048
+ retval.extend(res_headers[0])
1049
+ retval.extend(res_deserialization[0])
1050
+ retval.append("")
1051
+ else:
1052
+ for status_code, headers in zip(status_codes, res_headers):
1053
+ if headers:
1054
+ retval.append(f"if response.status_code == {status_code}:")
1055
+ retval.extend([f" {line}" for line in headers])
1056
+ retval.append("")
1057
+ retval.extend(res_deserialization[0])
1058
+ retval.append("")
1059
+ else:
1060
+ for status_code, headers, deserialization in zip(status_codes, res_headers, res_deserialization):
1024
1061
  retval.append(f"if response.status_code == {status_code}:")
1025
- retval.extend(
1026
- [f" {line}" for line in self.response_headers_and_deserialization(builder, response)]
1027
- )
1062
+ retval.extend([f" {line}" for line in headers])
1063
+ retval.extend([f" {line}" for line in deserialization])
1028
1064
  retval.append("")
1029
1065
  else:
1030
1066
  retval.extend(self.response_headers_and_deserialization(builder, builder.responses[0]))
@@ -105,11 +105,12 @@ class GeneralSerializer(BaseSerializer):
105
105
  typing_section=TypingSection.TYPING,
106
106
  )
107
107
  for client in clients:
108
- file_import.add_submodule_import(
109
- "._configuration",
110
- f"{client.name}Configuration",
111
- ImportType.LOCAL,
112
- )
108
+ if client.has_mixin:
109
+ file_import.add_submodule_import(
110
+ "._configuration",
111
+ f"{client.name}Configuration",
112
+ ImportType.LOCAL,
113
+ )
113
114
  if self.code_model.has_etag:
114
115
  file_import.add_submodule_import("typing", "Optional", ImportType.STDLIB)
115
116
  file_import.add_submodule_import(
@@ -576,6 +576,7 @@ class Model(_MyMutableMapping):
576
576
  """
577
577
 
578
578
  result = {}
579
+ readonly_props = []
579
580
  if exclude_readonly:
580
581
  readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)]
581
582
  for k, v in self.items():
@@ -45,7 +45,8 @@
45
45
  __flattened_items = ["{{ model.flattened_items|join('\", \"') }}"]
46
46
  {% endif %}
47
47
 
48
- {% if not model.internal and serializer.init_line(model) %}
48
+ {% set need_init = (not model.internal) and (serializer.init_line(model) or model.discriminator)%}
49
+ {% if need_init %}
49
50
  @overload
50
51
  def __init__(
51
52
  self,
@@ -64,7 +65,7 @@
64
65
 
65
66
  {% endif %}
66
67
  {% set initialize_properties = serializer.initialize_properties(model) %}
67
- {% if not model.internal and serializer.init_line(model) or initialize_properties %}
68
+ {% if need_init or initialize_properties %}
68
69
  def __init__(self, *args: Any, **kwargs: Any) -> None:{{ '# pylint: disable=useless-super-delegation' if not initialize_properties else '' }}
69
70
  {% for line in serializer.super_call(model) %}
70
71
  {{ line }}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "6.16.0",
3
+ "version": "6.17.1",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -25,7 +25,7 @@
25
25
  "devDependencies": {
26
26
  "@microsoft.azure/autorest.testserver": "^3.3.46",
27
27
  "typescript": "~5.1.3",
28
- "@azure-tools/typespec-python": "^0.26.0"
28
+ "@azure-tools/typespec-python": "^0.27.1"
29
29
  },
30
30
  "files": [
31
31
  "autorest/**/*.py",