@autorest/python 6.4.6 → 6.4.8

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.
@@ -16,6 +16,10 @@ from .serializers import JinjaSerializer, JinjaSerializerAutorest
16
16
  from ._utils import DEFAULT_HEADER_TEXT
17
17
 
18
18
 
19
+ def _default_pprint(package_name: str) -> str:
20
+ return " ".join([i.capitalize() for i in package_name.split("-")])
21
+
22
+
19
23
  def _validate_code_model_options(options: Dict[str, Any]) -> None:
20
24
  if options["builders_visibility"] not in ["public", "hidden", "embedded"]:
21
25
  raise ValueError(
@@ -126,6 +130,7 @@ class CodeGenerator(Plugin):
126
130
  if self.options.get("cadl_file") is not None:
127
131
  models_mode_default = "dpg"
128
132
 
133
+ package_name = self.options.get("package-name")
129
134
  options: Dict[str, Any] = {
130
135
  "azure_arm": azure_arm,
131
136
  "head_as_boolean": self.options.get("head-as-boolean", True),
@@ -134,7 +139,7 @@ class CodeGenerator(Plugin):
134
139
  "no_async": self.options.get("no-async", False),
135
140
  "no_namespace_folders": self.options.get("no-namespace-folders", False),
136
141
  "basic_setup_py": self.options.get("basic-setup-py", False),
137
- "package_name": self.options.get("package-name"),
142
+ "package_name": package_name,
138
143
  "package_version": self.options.get("package-version"),
139
144
  "client_side_validation": self.options.get("client-side-validation", False),
140
145
  "tracing": self.options.get("tracing", show_operations),
@@ -156,7 +161,8 @@ class CodeGenerator(Plugin):
156
161
  "combine-operation-files", version_tolerant
157
162
  ),
158
163
  "package_mode": self.options.get("package-mode"),
159
- "package_pprint_name": self.options.get("package-pprint-name"),
164
+ "package_pprint_name": self.options.get("package-pprint-name")
165
+ or _default_pprint(str(package_name)),
160
166
  "package_configuration": self.options.get("package-configuration"),
161
167
  "default_optional_constants_to_none": self.options.get(
162
168
  "default-optional-constants-to-none",
@@ -146,6 +146,8 @@ class Client(_ClientConfigBase[ClientGlobalParameterList]):
146
146
  retval = add_to_pylint_disable("", "client-accepts-api-version-keyword")
147
147
  if len(self.operation_groups) > 6:
148
148
  retval = add_to_pylint_disable(retval, "too-many-instance-attributes")
149
+ if len(self.name) > 40:
150
+ retval = add_to_pylint_disable(retval, "name-too-long")
149
151
  return retval
150
152
 
151
153
  @property
@@ -194,7 +194,7 @@ class CodeModel: # pylint: disable=too-many-public-methods
194
194
 
195
195
  @property
196
196
  def public_model_types(self) -> List[ModelType]:
197
- return [m for m in self.model_types if m.is_public and not m.base == "json"]
197
+ return [m for m in self.model_types if not m.internal and not m.base == "json"]
198
198
 
199
199
  @property
200
200
  def enums(self) -> List[EnumType]:
@@ -12,13 +12,11 @@ from .constant_type import ConstantType
12
12
  from .property import Property
13
13
  from .imports import FileImport, ImportType, TypingSection
14
14
 
15
-
16
15
  if sys.version_info >= (3, 8):
17
16
  from typing import Literal # pylint: disable=no-name-in-module, ungrouped-imports
18
17
  else:
19
18
  from typing_extensions import Literal # type: ignore # pylint: disable=ungrouped-imports
20
19
 
21
-
22
20
  if TYPE_CHECKING:
23
21
  from .code_model import CodeModel
24
22
 
@@ -74,7 +72,7 @@ class ModelType( # pylint: disable=abstract-method
74
72
  )
75
73
  self._created_json_template_representation = False
76
74
  self._got_polymorphic_subtypes = False
77
- self.is_public: bool = self.yaml_data.get("isPublic", True)
75
+ self.internal: bool = self.yaml_data.get("internal", False)
78
76
  self.snake_case_name: str = self.yaml_data["snakeCaseName"]
79
77
 
80
78
  @property
@@ -284,7 +282,7 @@ class GeneratedModelType(ModelType): # pylint: disable=abstract-method
284
282
  def type_annotation(self, **kwargs: Any) -> str:
285
283
  is_operation_file = kwargs.pop("is_operation_file", False)
286
284
  retval = f"_models.{self.name}"
287
- if not self.is_public:
285
+ if self.internal:
288
286
  retval = f"{self.code_model.models_filename}.{retval}"
289
287
  return retval if is_operation_file else f'"{retval}"'
290
288
 
@@ -321,7 +319,7 @@ class MsrestModelType(GeneratedModelType):
321
319
  @property
322
320
  def serialization_type(self) -> str:
323
321
  private_model_path = f"_models.{self.code_model.models_filename}."
324
- return f"{'' if self.is_public else private_model_path}{self.name}"
322
+ return f"{private_model_path if self.internal else ''}{self.name}"
325
323
 
326
324
  @property
327
325
  def instance_check_template(self) -> str:
@@ -340,7 +338,7 @@ class DPGModelType(GeneratedModelType):
340
338
 
341
339
  @property
342
340
  def serialization_type(self) -> str:
343
- return f"{'' if self.is_public else '_models.'}_models.{self.name}"
341
+ return f"{'_models.' if self.internal else ''}_models.{self.name}"
344
342
 
345
343
  @property
346
344
  def instance_check_template(self) -> str:
@@ -82,6 +82,9 @@ class OperationBase( # pylint: disable=too-many-public-methods
82
82
  "isLroInitialOperation", False
83
83
  )
84
84
  self.include_documentation: bool = not self.is_lro_initial_operation
85
+ self.internal: bool = self.yaml_data.get("internal", False)
86
+ if self.internal:
87
+ self.name = "_" + self.name
85
88
 
86
89
  @property
87
90
  def expose_stream_keyword(self) -> bool:
@@ -127,6 +130,8 @@ class OperationBase( # pylint: disable=too-many-public-methods
127
130
  if self.response_type_annotation(async_mode=False) == "None":
128
131
  # doesn't matter if it's async or not
129
132
  retval = add_to_pylint_disable(retval, "inconsistent-return-statements")
133
+ if len(self.name) > 40:
134
+ retval = add_to_pylint_disable(retval, "name-too-long")
130
135
  return retval
131
136
 
132
137
  def cls_type_annotation(self, *, async_mode: bool) -> str:
@@ -16,6 +16,7 @@ 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
20
  from .parameter_list import (
20
21
  RequestBuilderParameterList,
21
22
  OverloadedRequestBuilderParameterList,
@@ -56,6 +57,12 @@ class RequestBuilderBase(BaseBuilder[ParameterListType]):
56
57
  self.method: str = yaml_data["method"]
57
58
  self.want_tracing = False
58
59
 
60
+ @property
61
+ def pylint_disable(self) -> str:
62
+ if len(self.name) > 40:
63
+ return add_to_pylint_disable("", "name-too-long")
64
+ return ""
65
+
59
66
  def response_type_annotation(self, **kwargs) -> str:
60
67
  return "HttpRequest"
61
68
 
@@ -58,6 +58,14 @@ OperationType = TypeVar(
58
58
  )
59
59
 
60
60
 
61
+ def _xml_config(send_xml: bool, content_types: List[str]) -> str:
62
+ if not (send_xml and "xml" in str(content_types)):
63
+ return ""
64
+ if len(content_types) == 1:
65
+ return ", is_xml=True"
66
+ return ", is_xml='xml' in str(content_type)"
67
+
68
+
61
69
  def _escape_str(input_str: str) -> str:
62
70
  replace = input_str.replace("'", "\\'")
63
71
  return f'"{replace}"'
@@ -305,7 +313,7 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
305
313
  def description_and_summary(self, builder: BuilderType) -> List[str]:
306
314
  description_list: List[str] = []
307
315
  description_list.append(
308
- f"{ builder.summary.strip() if builder.summary else builder.description.strip() }"
316
+ f"{builder.summary.strip() if builder.summary else builder.description.strip()}"
309
317
  )
310
318
  if builder.summary and builder.description:
311
319
  description_list.append("")
@@ -328,7 +336,7 @@ class _BuilderBaseSerializer(Generic[BuilderType]): # pylint: disable=abstract-
328
336
  if not param.in_docstring:
329
337
  continue
330
338
  description_list.extend(
331
- f":{param.description_keyword} { param.client_name }: { param.description }".replace(
339
+ f":{param.description_keyword} {param.client_name}: {param.description}".replace(
332
340
  "\n", "\n "
333
341
  ).split(
334
342
  "\n"
@@ -704,9 +712,12 @@ class _OperationSerializer(
704
712
  check_client_input=not self.code_model.options["multiapi"],
705
713
  )
706
714
  cls_annotation = builder.cls_type_annotation(async_mode=self.async_mode)
707
- kwargs.append(f"cls: {cls_annotation} = kwargs.pop('cls', None)")
715
+ pylint_disable = ""
708
716
  if any(x.startswith("_") for x in cls_annotation.split(".")):
709
- kwargs[-1] += " # pylint: disable=protected-access"
717
+ pylint_disable = " # pylint: disable=protected-access"
718
+ kwargs.append(
719
+ f"cls: {cls_annotation} = kwargs.pop({pylint_disable}\n 'cls', None\n)"
720
+ )
710
721
  return kwargs
711
722
 
712
723
  def response_docstring(self, builder: OperationType) -> List[str]:
@@ -738,7 +749,9 @@ class _OperationSerializer(
738
749
  if xml_serialization_ctxt and self.code_model.options["models_mode"]:
739
750
  retval.append(f'{ser_ctxt_name} = {{"xml": {{{xml_serialization_ctxt}}}}}')
740
751
  if self.code_model.options["models_mode"] == "msrest":
741
- is_xml_cmd = ", is_xml=True" if send_xml else ""
752
+ is_xml_cmd = _xml_config(
753
+ send_xml, builder.parameters.body_parameter.content_types
754
+ )
742
755
  serialization_ctxt_cmd = (
743
756
  f", {ser_ctxt_name}={ser_ctxt_name}" if xml_serialization_ctxt else ""
744
757
  )
@@ -1047,15 +1060,23 @@ class _OperationSerializer(
1047
1060
  )
1048
1061
  )
1049
1062
  elif response.type:
1063
+ pylint_disable = ""
1064
+ if isinstance(response.type, ModelType) and response.type.internal:
1065
+ pylint_disable = " # pylint: disable=protected-access"
1050
1066
  if self.code_model.options["models_mode"] == "msrest":
1067
+ deserialize_code.append("deserialized = self._deserialize(")
1051
1068
  deserialize_code.append(
1052
- f"deserialized = self._deserialize('{response.serialization_type}', pipeline_response)"
1069
+ f" '{response.serialization_type}',{pylint_disable}"
1053
1070
  )
1071
+ deserialize_code.append(" pipeline_response")
1072
+ deserialize_code.append(")")
1054
1073
  elif self.code_model.options["models_mode"] == "dpg":
1074
+ deserialize_code.append("deserialized = _deserialize(")
1055
1075
  deserialize_code.append(
1056
- f"deserialized = _deserialize({response.type.type_annotation(is_operation_file=True)}"
1057
- ", response.json())"
1076
+ f" {response.type.type_annotation(is_operation_file=True)},{pylint_disable}"
1058
1077
  )
1078
+ deserialize_code.append(" response.json()")
1079
+ deserialize_code.append(")")
1059
1080
  else:
1060
1081
  deserialized_value = (
1061
1082
  "ET.fromstring(response.text())"
@@ -1247,7 +1268,7 @@ class _OperationSerializer(
1247
1268
  @staticmethod
1248
1269
  def get_metadata_url(builder: OperationType) -> str:
1249
1270
  url = _escape_str(builder.request_builder.url)
1250
- return f"{builder.name}.metadata = {{'url': { url }}}"
1271
+ return f"{builder.name}.metadata = {{'url': {url}}}"
1251
1272
 
1252
1273
  @property
1253
1274
  def _call_method(self) -> str:
@@ -1379,10 +1400,10 @@ class _PagingOperationSerializer(
1379
1400
  if self.code_model.options["models_mode"] == "msrest":
1380
1401
  deserialize_type = response.serialization_type
1381
1402
  pylint_disable = " # pylint: disable=protected-access"
1382
- if isinstance(response.type, ModelType) and response.type.is_public:
1403
+ if isinstance(response.type, ModelType) and not response.type.internal:
1383
1404
  deserialize_type = f'"{response.serialization_type}"'
1384
1405
  pylint_disable = ""
1385
- deserialized = f"self._deserialize(\n {deserialize_type}, pipeline_response{pylint_disable}\n)"
1406
+ deserialized = f"self._deserialize(\n {deserialize_type},{pylint_disable}\n pipeline_response\n)"
1386
1407
  retval.append(f" deserialized = {deserialized}")
1387
1408
  elif self.code_model.options["models_mode"] == "dpg":
1388
1409
  # we don't want to generate paging models for DPG
@@ -1501,7 +1522,7 @@ class _LROOperationSerializer(_OperationSerializer[LROOperationType]):
1501
1522
  retval.append("if cont_token is None:")
1502
1523
  retval.append(
1503
1524
  f" raw_result = {self._call_method}self.{builder.initial_operation.name}("
1504
- f"{'' if builder.lro_response and builder.lro_response.type else ' # type: ignore'}"
1525
+ f"{'' if builder.lro_response and builder.lro_response.type else ' # type: ignore'}"
1505
1526
  )
1506
1527
  retval.extend(
1507
1528
  [
@@ -215,7 +215,7 @@ class DpgModelSerializer(_ModelSerializer):
215
215
  file_import.merge(prop.imports())
216
216
  if model.is_polymorphic:
217
217
  file_import.add_submodule_import("typing", "Dict", ImportType.STDLIB)
218
- if model.is_public and self.init_line(model):
218
+ if not model.internal and self.init_line(model):
219
219
  file_import.add_submodule_import(
220
220
  "typing", "overload", ImportType.STDLIB
221
221
  )
@@ -251,7 +251,7 @@ class DpgModelSerializer(_ModelSerializer):
251
251
  return properties_to_declare
252
252
 
253
253
  @staticmethod
254
- def declare_property(prop: Property) -> List[str]:
254
+ def declare_property(prop: Property) -> str:
255
255
  args = []
256
256
  if prop.client_name != prop.rest_api_name or prop.is_discriminator:
257
257
  args.append(f'name="{prop.rest_api_name}"')
@@ -266,14 +266,10 @@ class DpgModelSerializer(_ModelSerializer):
266
266
  and prop.is_discriminator
267
267
  and cast(ConstantType, prop.type).value
268
268
  )
269
- ret = [
269
+ return (
270
270
  f"{prop.client_name}: {prop.type_annotation()} ="
271
271
  f' {field}({", ".join(args)}){" # type: ignore" if type_ignore else ""}'
272
- ]
273
- comment = prop.description(is_operation_file=False).replace('"', '\\"')
274
- if comment:
275
- ret.append(f'"""{comment}"""')
276
- return ret
272
+ )
277
273
 
278
274
  def initialize_properties(self, model: ModelType) -> List[str]:
279
275
  init_args = []
@@ -421,7 +421,10 @@ class Model(_MyMutableMapping):
421
421
  if non_attr_kwargs:
422
422
  # actual type errors only throw the first wrong keyword arg they see, so following that.
423
423
  raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'")
424
- dict_to_pass.update({self._attr_to_rest_field[k]._rest_name: _serialize(v) for k, v in kwargs.items()})
424
+ dict_to_pass.update({
425
+ self._attr_to_rest_field[k]._rest_name: _serialize(v)
426
+ for k, v in kwargs.items() if v is not None
427
+ })
425
428
  super().__init__(dict_to_pass)
426
429
 
427
430
  def copy(self) -> "Model":
@@ -31,12 +31,14 @@
31
31
  __mapping__: Dict[str, _model_base.Model] = {}
32
32
  {% endif %}
33
33
  {% for p in serializer.get_properties_to_declare(model)%}
34
- {% for line in serializer.declare_property(p) %}
35
- {{ line }}
36
- {% endfor %}
34
+ {{ serializer.declare_property(p) }}
35
+ {% set prop_description = p.description(is_operation_file=False).replace('"', '\\"') %}
36
+ {% if prop_description %}
37
+ """{{ prop_description | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring='\n ') }}"""
38
+ {% endif %}
37
39
  {% endfor %}
38
40
 
39
- {% if model.is_public and serializer.init_line(model) %}
41
+ {% if not model.internal and serializer.init_line(model) %}
40
42
  @overload
41
43
  def __init__(
42
44
  self,
@@ -55,7 +57,7 @@
55
57
 
56
58
  {% endif %}
57
59
  {% set initialize_properties = serializer.initialize_properties(model) %}
58
- {% if model.is_public and serializer.init_line(model) or initialize_properties %}
60
+ {% if not model.internal and serializer.init_line(model) or initialize_properties %}
59
61
  def __init__(self, *args: Any, **kwargs: Any) -> None:{{ '# pylint: disable=useless-super-delegation' if not initialize_properties else '' }}
60
62
  super().__init__(*args, **kwargs)
61
63
  {% for initialize_property in initialize_properties %}
@@ -62,5 +62,9 @@ _SERIALIZER.client_side_validation = False
62
62
  {% macro generate_overloads(operation_serializer, operation) %}
63
63
  {% for overload in operation.overloads %}
64
64
  {{ operation_serializer.method_signature_and_response_type_annotation(overload) }}
65
+ {% if not operation.internal %}
65
66
  {{ description(overload, operation_serializer) | indent }}
67
+ {% else %}
68
+ ...
69
+ {% endif %}
66
70
  {% endfor %}{% endmacro %}
@@ -24,12 +24,12 @@ with open(os.path.join(package_folder_path, "_version.py"), "r") as fd:
24
24
 
25
25
  if not version:
26
26
  raise RuntimeError("Cannot find version information")
27
- {% set description = "Microsoft %s Client Library for Python"|format(package_pprint_name) %}
27
+ {% set description = "\"Microsoft {} Client Library for Python\".format(PACKAGE_PPRINT_NAME)" %}
28
28
  {% set author_email = "azpysdkhelp@microsoft.com" %}
29
29
  {% set url = "https://github.com/Azure/azure-sdk-for-python/tree/main/sdk" %}
30
30
  {% else %}
31
31
  version = "{{ package_version }}"
32
- {% set description = "%s"|format(package_name) %}
32
+ {% set description = "\"%s\""|format(package_name) %}
33
33
  {% set long_description = code_model.description %}
34
34
  {% set author_email = "" %}
35
35
  {% set url = "" %}
@@ -38,7 +38,7 @@ version = "{{ package_version }}"
38
38
  setup(
39
39
  name=PACKAGE_NAME,
40
40
  version=version,
41
- description="{{ description }}",
41
+ description={{ description }},
42
42
  {% if package_mode %}
43
43
  long_description=open("README.md", "r").read(),
44
44
  long_description_content_type="text/markdown",
@@ -602,7 +602,7 @@ class M4Reformatter(
602
602
  )
603
603
  if self.version_tolerant:
604
604
  # if we're in version tolerant, hide the paging model
605
- returned_response_object["type"]["isPublic"] = False
605
+ returned_response_object["type"]["internal"] = True
606
606
  operation["itemType"] = next(
607
607
  p["type"]
608
608
  for p in returned_response_object["type"]["properties"]
@@ -218,10 +218,27 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
218
218
  )
219
219
  add_redefined_builtin_info(property["clientName"], property)
220
220
  if type.get("name"):
221
+ type["name"] = self.pad_reserved_words(type["name"], PadType.MODEL)
221
222
  type["description"] = update_description(
222
223
  type["description"], type["name"]
223
224
  )
224
225
  type["snakeCaseName"] = to_snake_case(type["name"])
226
+ if type.get("values") and not self.version_tolerant:
227
+ # we're enums
228
+ values_to_add = []
229
+ for value in type["values"]:
230
+ padded_name = self.pad_reserved_words(
231
+ value["name"].lower(), PadType.ENUM
232
+ ).upper()
233
+ if value["name"] != padded_name:
234
+ values_to_add.append(
235
+ {
236
+ "description": value["description"],
237
+ "name": padded_name,
238
+ "value": value["value"],
239
+ }
240
+ )
241
+ type["values"].extend(values_to_add)
225
242
 
226
243
  def update_client(self, yaml_data: Dict[str, Any]) -> None:
227
244
  yaml_data["description"] = update_description(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "6.4.6",
3
+ "version": "6.4.8",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -22,7 +22,7 @@
22
22
  "@autorest/system-requirements": "~1.0.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@microsoft.azure/autorest.testserver": "^3.3.45",
25
+ "@microsoft.azure/autorest.testserver": "^3.3.46",
26
26
  "typescript": "^4.8.3"
27
27
  },
28
28
  "files": [