@autorest/python 6.11.1 → 6.12.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.
@@ -304,6 +304,11 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
304
304
  """Whether there is abstract operation in any operation group."""
305
305
  return any(og.has_abstract_operations for og in self.operation_groups)
306
306
 
307
+ @property
308
+ def has_non_abstract_operations(self) -> bool:
309
+ """Whether there is non-abstract operation in any operation group."""
310
+ return any(og.has_non_abstract_operations for og in self.operation_groups)
311
+
307
312
  def imports(self, async_mode: bool) -> FileImport:
308
313
  file_import = self._imports_shared(async_mode)
309
314
  if async_mode:
@@ -79,12 +79,11 @@ class CodeModel: # pylint: disable=too-many-public-methods, disable=too-many-in
79
79
 
80
80
  @property
81
81
  def has_form_data(self) -> bool:
82
- for client in self.clients:
83
- for operation_group in client.operation_groups:
84
- for operation in operation_group.operations:
85
- if operation.has_form_data_body:
86
- return True
87
- return False
82
+ return any(
83
+ og.has_form_data_body
84
+ for client in self.clients
85
+ for og in client.operation_groups
86
+ )
88
87
 
89
88
  @property
90
89
  def has_etag(self) -> bool:
@@ -103,18 +102,12 @@ class CodeModel: # pylint: disable=too-many-public-methods, disable=too-many-in
103
102
 
104
103
  @property
105
104
  def has_non_abstract_operations(self) -> bool:
106
- for client in self.clients:
107
- for operation_group in client.operation_groups:
108
- for operation in operation_group.operations:
109
- if not operation.abstract:
110
- return True
111
- for clients in self.subnamespace_to_clients.values():
112
- for client in clients:
113
- for operation_group in client.operation_groups:
114
- for operation in operation_group.operations:
115
- if not operation.abstract:
116
- return True
117
- return False
105
+ return any(c for c in self.clients if c.has_non_abstract_operations) or any(
106
+ c
107
+ for cs in self.subnamespace_to_clients.values()
108
+ for c in cs
109
+ if c.has_non_abstract_operations
110
+ )
118
111
 
119
112
  def lookup_request_builder(
120
113
  self, request_builder_id: int
@@ -6,7 +6,7 @@
6
6
  from collections import OrderedDict
7
7
  from typing import Any, Dict, List, Optional, TYPE_CHECKING, cast
8
8
  import sys
9
- from autorest.codegen.models.utils import add_to_pylint_disable
9
+ from autorest.codegen.models.utils import add_to_pylint_disable, NAME_LENGTH_LIMIT
10
10
  from .base import BaseType
11
11
  from .constant_type import ConstantType
12
12
  from .property import Property
@@ -237,6 +237,8 @@ class ModelType( # pylint: disable=abstract-method
237
237
  retval: str = ""
238
238
  if len(self.properties) > 10:
239
239
  retval = add_to_pylint_disable(retval, "too-many-instance-attributes")
240
+ if len(self.name) > NAME_LENGTH_LIMIT:
241
+ retval = add_to_pylint_disable(retval, "name-too-long")
240
242
  return retval
241
243
 
242
244
  @property
@@ -589,7 +589,12 @@ class Operation(OperationBase[Response]):
589
589
  file_import.add_submodule_import("io", "IOBase", ImportType.STDLIB)
590
590
  file_import.add_submodule_import(
591
591
  f"{relative_path}_vendor",
592
- "multipart_form_data_file",
592
+ "multipart_file",
593
+ ImportType.LOCAL,
594
+ )
595
+ file_import.add_submodule_import(
596
+ f"{relative_path}_vendor",
597
+ "multipart_data",
593
598
  ImportType.LOCAL,
594
599
  )
595
600
  file_import.add_submodule_import(
@@ -48,7 +48,17 @@ class OperationGroup(BaseModel):
48
48
 
49
49
  @property
50
50
  def has_abstract_operations(self) -> bool:
51
- return any(o for o in self.operations if o.abstract)
51
+ return any(o for o in self.operations if o.abstract) or any(
52
+ operation_group.has_abstract_operations
53
+ for operation_group in self.operation_groups
54
+ )
55
+
56
+ @property
57
+ def has_non_abstract_operations(self) -> bool:
58
+ return any(o for o in self.operations if not o.abstract) or any(
59
+ operation_group.has_non_abstract_operations
60
+ for operation_group in self.operation_groups
61
+ )
52
62
 
53
63
  @property
54
64
  def base_class(self) -> str:
@@ -183,6 +193,13 @@ class OperationGroup(BaseModel):
183
193
  operation_group.has_operations for operation_group in self.operation_groups
184
194
  ) or bool(self.operations)
185
195
 
196
+ @property
197
+ def has_form_data_body(self) -> bool:
198
+ operations = self.operations + [
199
+ o for og in self.operation_groups for o in og.operations
200
+ ]
201
+ return any(operation.has_form_data_body for operation in operations)
202
+
186
203
  @classmethod
187
204
  def from_yaml(
188
205
  cls,
@@ -768,8 +768,8 @@ class _OperationSerializer(
768
768
  f" _body = handle_multipart_form_data_model({body_param.client_name})",
769
769
  "else:",
770
770
  f" _body = {body_param.client_name}",
771
- "_files = {k: multipart_form_data_file(v) for k, v in _body.items() if isinstance(v, (IOBase, bytes))}",
772
- "_data = {k: v for k, v in _body.items() if not isinstance(v, (IOBase, bytes))}",
771
+ "_files = {k: multipart_file(v) for k, v in _body.items() if isinstance(v, (IOBase, bytes))}",
772
+ "_data = {k: multipart_data(v) for k, v in _body.items() if not isinstance(v, (IOBase, bytes))}",
773
773
  ]
774
774
  retval: List[str] = []
775
775
  body_kwarg_name = builder.request_builder.parameters.body_parameter.client_name
@@ -136,8 +136,12 @@ class GeneralSerializer(BaseSerializer):
136
136
  file_import.add_submodule_import("io", "IOBase", ImportType.STDLIB)
137
137
  file_import.add_submodule_import("io", "BytesIO", ImportType.STDLIB)
138
138
  file_import.add_import("uuid", ImportType.STDLIB)
139
+ file_import.add_import("json", ImportType.STDLIB)
139
140
  file_import.add_mutable_mapping_import()
140
141
  file_import.add_submodule_import("._model_base", "Model", ImportType.LOCAL)
142
+ file_import.add_submodule_import(
143
+ "._model_base", "SdkJSONEncoder", ImportType.LOCAL
144
+ )
141
145
 
142
146
  return template.render(
143
147
  code_model=self.code_model,
@@ -3,7 +3,7 @@
3
3
  # Microsoft Azure SDK for Python
4
4
 
5
5
  This is the Microsoft {{package_pprint_name}} Client Library.
6
- This package has been tested with Python 3.7+.
6
+ This package has been tested with Python 3.8+.
7
7
  For a more complete view of Azure libraries, see the [azure sdk python release](https://aka.ms/azsdk/python/all).
8
8
 
9
9
  # Usage
@@ -36,7 +36,7 @@ python -m pip install {{ package_name }}
36
36
 
37
37
  #### Prequisites
38
38
 
39
- - Python 3.7 or later is required to use this package.
39
+ - Python 3.8 or later is required to use this package.
40
40
  - You need an [Azure subscription][azure_sub] to use this package.
41
41
  - An existing {{ package_pprint_name }} instance.
42
42
 
@@ -56,11 +56,11 @@ setup(
56
56
  "Programming Language :: Python",
57
57
  "Programming Language :: Python :: 3 :: Only",
58
58
  "Programming Language :: Python :: 3",
59
- "Programming Language :: Python :: 3.7",
60
59
  "Programming Language :: Python :: 3.8",
61
60
  "Programming Language :: Python :: 3.9",
62
61
  "Programming Language :: Python :: 3.10",
63
62
  "Programming Language :: Python :: 3.11",
63
+ "Programming Language :: Python :: 3.12",
64
64
  "License :: OSI Approved :: MIT License",
65
65
  ],
66
66
  zip_safe=False,
@@ -101,7 +101,7 @@ setup(
101
101
  {% endif %}
102
102
  ],
103
103
  {% if package_mode %}
104
- python_requires=">=3.7",
104
+ python_requires=">=3.8",
105
105
  {% else %}
106
106
  long_description="""\
107
107
  {{ code_model.description }}
@@ -71,11 +71,16 @@ class NamedBytesIO(BytesIO):
71
71
  super().__init__(*args, **kwargs)
72
72
  self.name = name
73
73
 
74
- def multipart_form_data_file(file: Union[IOBase, bytes]) -> IOBase:
74
+ def multipart_file(file: Union[IOBase, bytes]) -> IOBase:
75
75
  if isinstance(file, IOBase):
76
76
  return file
77
77
  return NamedBytesIO("auto-name-" + str(uuid.uuid4()), file)
78
78
 
79
+ def multipart_data(data: Any) -> Any:
80
+ if isinstance(data, (list, tuple, dict, Model)):
81
+ return json.dumps(data, cls=SdkJSONEncoder, exclude_readonly=True)
82
+ return data
83
+
79
84
  def handle_multipart_form_data_model(body: Model) -> MutableMapping[str, Any]: # pylint: disable=unsubscriptable-object
80
85
  """handle first layer of model.
81
86
  If its value is bytes or IO, replace it with raw value instead of serialized value.
@@ -237,8 +237,10 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
237
237
  return name
238
238
 
239
239
  if self.is_cadl:
240
- reserved_words = copy.copy(CADL_RESERVED_WORDS)
241
- reserved_words.update(RESERVED_WORDS)
240
+ reserved_words = {
241
+ k: (v + CADL_RESERVED_WORDS.get(k, []))
242
+ for k, v in RESERVED_WORDS.items()
243
+ }
242
244
  else:
243
245
  reserved_words = RESERVED_WORDS
244
246
  name = pad_special_chars(name)
@@ -96,6 +96,18 @@ _always_reserved = [
96
96
  "int",
97
97
  ]
98
98
 
99
+ RESERVED_MODEL_PROPERTIES = [
100
+ "keys",
101
+ "items",
102
+ "values",
103
+ "popitem",
104
+ "clear",
105
+ "update",
106
+ "setdefault",
107
+ "pop",
108
+ "get",
109
+ ]
110
+
99
111
  RESERVED_WORDS = {
100
112
  PadType.METHOD: [*_always_reserved],
101
113
  PadType.PARAMETER: [
@@ -169,7 +181,10 @@ RESERVED_WORDS = {
169
181
  PadType.OPERATION_GROUP: [*_always_reserved],
170
182
  }
171
183
 
172
- CADL_RESERVED_WORDS = {PadType.PARAMETER: ["stream"]}
184
+ CADL_RESERVED_WORDS = {
185
+ PadType.PARAMETER: ["stream"],
186
+ PadType.PROPERTY: RESERVED_MODEL_PROPERTIES,
187
+ }
173
188
 
174
189
  REDEFINED_BUILTINS = [ # we don't pad, but we need to do lint ignores
175
190
  "id",
package/install.py CHANGED
@@ -7,7 +7,7 @@
7
7
  # --------------------------------------------------------------------------
8
8
  import sys
9
9
  if not sys.version_info >= (3, 7, 0):
10
- raise Exception("Autorest for Python extension requires Python 3.7 at least")
10
+ raise Exception("Autorest for Python extension requires Python 3.8 at least")
11
11
 
12
12
  try:
13
13
  import pip
@@ -20,7 +20,7 @@ except ImportError:
20
20
  raise Exception("Your Python installation doesn't have venv available")
21
21
 
22
22
 
23
- # Now we have pip and Py >= 3.7, go to work
23
+ # Now we have pip and Py >= 3.8, go to work
24
24
 
25
25
  import subprocess
26
26
  from pathlib import Path
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "6.11.1",
3
+ "version": "6.12.1",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "main": "index.js",
6
6
  "repository": {
package/prepare.py CHANGED
@@ -7,7 +7,7 @@
7
7
  # --------------------------------------------------------------------------
8
8
  import sys
9
9
  if not sys.version_info >= (3, 7, 0):
10
- raise Exception("Autorest for Python extension requires Python 3.7 at least")
10
+ raise Exception("Autorest for Python extension requires Python 3.8 at least")
11
11
 
12
12
  from pathlib import Path
13
13
  import venv
package/requirements.txt CHANGED
@@ -10,4 +10,4 @@ pathspec==0.11.1
10
10
  platformdirs==3.2.0
11
11
  PyYAML==6.0.1
12
12
  tomli==2.0.1
13
- setuptools==58.3.0
13
+ setuptools==65.5.1
package/run-python3.js CHANGED
@@ -10,7 +10,7 @@ const cp = require("child_process");
10
10
  const extension = require("@autorest/system-requirements");
11
11
 
12
12
  async function runPython3(scriptName, ...args) {
13
- const command = await extension.patchPythonPath(["python", scriptName, ...args], { version: ">=3.7", environmentVariable: "AUTOREST_PYTHON_EXE" });
13
+ const command = await extension.patchPythonPath(["python", scriptName, ...args], { version: ">=3.8", environmentVariable: "AUTOREST_PYTHON_EXE" });
14
14
  cp.execSync(command.join(" "), {
15
15
  stdio: [0, 1, 2]
16
16
  });
package/setup.py CHANGED
@@ -36,11 +36,11 @@ setup(
36
36
  'Development Status :: 4 - Beta',
37
37
  'Programming Language :: Python',
38
38
  'Programming Language :: Python :: 3',
39
- 'Programming Language :: Python :: 3.7',
40
39
  'Programming Language :: Python :: 3.8',
41
40
  'Programming Language :: Python :: 3.9',
42
41
  'Programming Language :: Python :: 3.10',
43
42
  'Programming Language :: Python :: 3.11',
43
+ 'Programming Language :: Python :: 3.12',
44
44
  'License :: OSI Approved :: MIT License',
45
45
  ],
46
46
  packages=find_packages(exclude=[
package/start.py CHANGED
@@ -7,7 +7,7 @@
7
7
  # --------------------------------------------------------------------------
8
8
  import sys
9
9
  if not sys.version_info >= (3, 7, 0):
10
- raise Exception("Autorest for Python extension requires Python 3.7 at least")
10
+ raise Exception("Autorest for Python extension requires Python 3.8 at least")
11
11
 
12
12
  from pathlib import Path
13
13
  import venv