@autorest/python 6.2.8 → 6.2.10

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.
@@ -96,6 +96,7 @@ KNOWN_TYPES: Dict[str, Dict[str, Any]] = {
96
96
  "string": {"type": "string"},
97
97
  "binary": {"type": "binary"},
98
98
  "anydict": {"type": "dict", "elementType": {"type": "any"}},
99
+ "any-object": {"type": "any-object"},
99
100
  }
100
101
 
101
102
  JSON_REGEXP = re.compile(r"^(application|text)/(.+\+)?json$")
@@ -70,6 +70,12 @@ def _validate_code_model_options(options: Dict[str, Any]) -> None:
70
70
  "Can not generate version tolerant with --client-side-validation. "
71
71
  )
72
72
 
73
+ if not (options["azure_arm"] or options["version_tolerant"]):
74
+ _LOGGER.warning(
75
+ "You are generating with options that would not allow the SDK to be shipped as an official Azure SDK. "
76
+ "Please read https://aka.ms/azsdk/dpcodegen for more details."
77
+ )
78
+
73
79
 
74
80
  _LOGGER = logging.getLogger(__name__)
75
81
 
@@ -192,3 +192,7 @@ class BaseType(BaseModel, ABC): # pylint: disable=too-many-public-methods
192
192
  def serialization_constraints(self) -> List[str]:
193
193
  """Whether there are any serialization constraints when serializing this type."""
194
194
  return []
195
+
196
+ @property
197
+ def type_description(self) -> str:
198
+ return self.type # type: ignore
@@ -51,12 +51,8 @@ class CombinedType(BaseType):
51
51
  self, *, is_operation_file: bool # pylint: disable=unused-argument
52
52
  ) -> str:
53
53
  if len(self.types) == 2:
54
- return (
55
- f"Is either a {self.types[0].type} type or a {self.types[1].type} type."
56
- )
57
- return (
58
- f"Is one of the following types: {', '.join([t.type for t in self.types])}"
59
- )
54
+ return f"Is either a {self.types[0].type_description} type or a {self.types[1].type_description} type."
55
+ return f"Is one of the following types: {', '.join([t.type_description for t in self.types])}"
60
56
 
61
57
  def docstring_text(self, **kwargs: Any) -> str:
62
58
  return " or ".join(t.docstring_text(**kwargs) for t in self.types)
@@ -30,7 +30,11 @@ class ListType(BaseType):
30
30
  return f"[{self.element_type.serialization_type}]"
31
31
 
32
32
  def type_annotation(self, **kwargs: Any) -> str:
33
- if self.code_model.options["version_tolerant"] and self.element_type.is_xml:
33
+ if (
34
+ self.code_model.options["version_tolerant"]
35
+ and self.element_type.is_xml
36
+ and not self.code_model.options["models_mode"]
37
+ ):
34
38
  # this means we're version tolerant XML, we just return the XML element
35
39
  return self.element_type.type_annotation(**kwargs)
36
40
  return f"List[{self.element_type.type_annotation(**kwargs)}]"
@@ -140,7 +144,9 @@ class ListType(BaseType):
140
144
  def imports(self, **kwargs: Any) -> FileImport:
141
145
  file_import = FileImport()
142
146
  if not (
143
- self.code_model.options["version_tolerant"] and self.element_type.is_xml
147
+ self.code_model.options["version_tolerant"]
148
+ and self.element_type.is_xml
149
+ and not self.code_model.options["models_mode"]
144
150
  ):
145
151
  file_import.add_submodule_import(
146
152
  "typing", "List", ImportType.STDLIB, TypingSection.CONDITIONAL
@@ -5,7 +5,6 @@
5
5
  # --------------------------------------------------------------------------
6
6
  import abc
7
7
  from enum import Enum, auto
8
- import re
9
8
 
10
9
  from typing import (
11
10
  Dict,
@@ -22,8 +21,6 @@ from .imports import FileImport, ImportType
22
21
  from .base import BaseModel
23
22
  from .base import BaseType
24
23
  from .constant_type import ConstantType
25
- from .model_type import ModelType
26
- from .combined_type import CombinedType
27
24
  from .utils import add_to_description
28
25
 
29
26
  if TYPE_CHECKING:
@@ -254,40 +251,6 @@ class BodyParameter(_BodyParameterBase):
254
251
  type=code_model.lookup_type(id(yaml_data["type"])),
255
252
  )
256
253
 
257
- def type_annotation(self, **kwargs: Any) -> str:
258
- annotation = super().type_annotation(**kwargs)
259
- model_seq = BodyParameter.get_model_seq(self.type)
260
- if self.code_model.options["models_mode"] == "dpg" and model_seq >= 0:
261
- pattern = re.compile(r"Union\[.*\]")
262
- union_content = (
263
- annotation[6:-1] if pattern.match(annotation) else annotation
264
- )
265
- items = union_content.split(", ")
266
- items.insert(model_seq + 1, "JSON")
267
- annotation = f'Union[{", ".join(items)}]'
268
- return annotation
269
-
270
- def docstring_type(self, **kwargs: Any) -> str:
271
- docstring = super().docstring_type(**kwargs)
272
- model_seq = BodyParameter.get_model_seq(self.type)
273
- if self.code_model.options["models_mode"] == "dpg" and model_seq >= 0:
274
- items = docstring.split(" or ")
275
- items.insert(model_seq + 1, "JSON")
276
- docstring = " or ".join(items)
277
- return docstring
278
-
279
- @staticmethod
280
- def get_model_seq(t: BaseType):
281
- if isinstance(t, ModelType):
282
- return 0
283
- if isinstance(t, CombinedType):
284
- sub_num = len(t.types)
285
- for i in range(sub_num):
286
- sub_seq = BodyParameter.get_model_seq(t.types[i])
287
- if sub_seq >= 0:
288
- return i + sub_seq
289
- return -1
290
-
291
254
 
292
255
  EntryBodyParameterType = TypeVar(
293
256
  "EntryBodyParameterType", bound=Union[BodyParameter, "RequestBuilderBodyParameter"]
@@ -199,6 +199,10 @@ class AnyObjectType(PrimitiveType):
199
199
  file_import.define_mutable_mapping_type()
200
200
  return file_import
201
201
 
202
+ @property
203
+ def type_description(self) -> str:
204
+ return "JSON"
205
+
202
206
 
203
207
  class NumberType(PrimitiveType): # pylint: disable=abstract-method
204
208
  def __init__(self, yaml_data: Dict[str, Any], code_model: "CodeModel") -> None:
@@ -18,6 +18,7 @@ from azure.core.utils._utils import _FixedOffset
18
18
  from collections.abc import MutableMapping
19
19
  from azure.core.exceptions import DeserializationError
20
20
  from azure.core import CaseInsensitiveEnumMeta
21
+ from azure.core.pipeline import PipelineResponse
21
22
  import copy
22
23
 
23
24
  _LOGGER = logging.getLogger(__name__)
@@ -253,11 +254,12 @@ _DESERIALIZE_MAPPING = {
253
254
 
254
255
 
255
256
  def _get_model(module_name: str, model_name: str):
257
+ models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)}
256
258
  module_end = module_name.rsplit(".", 1)[0]
257
259
  module = sys.modules[module_end]
258
- models = {k: v for k, v in module.__dict__.items() if isinstance(v, type)}
260
+ models.update({k: v for k, v in module.__dict__.items() if isinstance(v, type)})
261
+ model_name = model_name.split(".")[-1]
259
262
  if model_name not in models:
260
- _LOGGER.warning("Can not find model name in models, will not deserialize")
261
263
  return model_name
262
264
  return models[model_name]
263
265
 
@@ -486,12 +488,12 @@ def _get_deserialize_callable_from_annotation(
486
488
  def _deserialize_with_union(union_annotation: typing._GenericAlias, obj):
487
489
  for t in union_annotation.__args__:
488
490
  try:
489
- return _deserialize(t, obj)
491
+ return _deserialize(t, obj, module)
490
492
  except DeserializationError:
491
493
  pass
492
494
  raise DeserializationError()
493
495
  return functools.partial(_deserialize_with_union, annotation)
494
-
496
+
495
497
  # is it optional?
496
498
  try:
497
499
  # right now, assuming we don't have unions, since we're getting rid of the only
@@ -533,7 +535,7 @@ def _get_deserialize_callable_from_annotation(
533
535
  if obj is None:
534
536
  return obj
535
537
  return {
536
- _deserialize(key_deserializer, k): _deserialize(value_deserializer, v) for k, v in obj.items()
538
+ _deserialize(key_deserializer, k, module): _deserialize(value_deserializer, v, module) for k, v in obj.items()
537
539
  }
538
540
 
539
541
  return functools.partial(
@@ -553,7 +555,7 @@ def _get_deserialize_callable_from_annotation(
553
555
  if obj is None:
554
556
  return obj
555
557
  return type(obj)(
556
- _deserialize(deserializer, entry) for entry, deserializer in zip(obj, entry_deserializers)
558
+ _deserialize(deserializer, entry, module) for entry, deserializer in zip(obj, entry_deserializers)
557
559
  )
558
560
 
559
561
  entry_deserializers = [
@@ -568,7 +570,7 @@ def _get_deserialize_callable_from_annotation(
568
570
  ):
569
571
  if obj is None:
570
572
  return obj
571
- return type(obj)(_deserialize(deserializer, entry) for entry in obj)
573
+ return type(obj)(_deserialize(deserializer, entry, module) for entry in obj)
572
574
 
573
575
  return functools.partial(_deserialize_sequence, deserializer)
574
576
  except (TypeError, IndexError, AttributeError, SyntaxError):
@@ -607,8 +609,10 @@ def _deserialize_with_callable(deserializer: typing.Optional[typing.Callable[[ty
607
609
  raise DeserializationError() from e
608
610
 
609
611
 
610
- def _deserialize(deserializer: typing.Optional[typing.Callable[[typing.Any], typing.Any]], value: typing.Any):
611
- deserializer = _get_deserialize_callable_from_annotation(deserializer, "")
612
+ def _deserialize(deserializer: typing.Optional[typing.Callable[[typing.Any], typing.Any]], value: typing.Any, module: str = ""):
613
+ if isinstance(value, PipelineResponse):
614
+ value = value.http_response.json()
615
+ deserializer = _get_deserialize_callable_from_annotation(deserializer, module)
612
616
  return _deserialize_with_callable(deserializer, value)
613
617
 
614
618
  class _RestField:
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
  {{ serializer.declare_model(model) }}
5
- """{{ model.description(is_operation_file=False) }}
5
+ """{{ model.description(is_operation_file=False) | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring='\n ') }}
6
6
  {% if model.discriminated_subtypes %}
7
7
 
8
8
  {{ serializer.discriminator_docstring(model) | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring='\n ') }}
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
  {{ serializer.declare_model(model) }}
5
- """{{ model.description(is_operation_file=False) }}
5
+ """{{ model.description(is_operation_file=False) | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring='\n ') }}
6
6
  {% if model.discriminated_subtypes %}
7
7
 
8
8
  {{ serializer.discriminator_docstring(model) | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring='\n ') }}
@@ -20,7 +20,11 @@ from .. import YamlUpdatePlugin, YamlUpdatePluginAutorest
20
20
  from .._utils import parse_args, get_body_type_for_description, JSON_REGEXP, KNOWN_TYPES
21
21
 
22
22
 
23
- def add_body_param_type(code_model: Dict[str, Any], body_parameter: Dict[str, Any]):
23
+ def add_body_param_type(
24
+ code_model: Dict[str, Any],
25
+ body_parameter: Dict[str, Any],
26
+ models_mode: Optional[str],
27
+ ):
24
28
  if (
25
29
  body_parameter
26
30
  and body_parameter["type"]["type"] in ("model", "dict", "list")
@@ -30,10 +34,13 @@ def add_body_param_type(code_model: Dict[str, Any], body_parameter: Dict[str, An
30
34
  and not body_parameter["type"].get("xmlMetadata")
31
35
  and not any(t for t in ["flattened", "groupedBy"] if body_parameter.get(t))
32
36
  ):
37
+ origin_type = body_parameter["type"]["type"]
33
38
  body_parameter["type"] = {
34
39
  "type": "combined",
35
40
  "types": [body_parameter["type"], KNOWN_TYPES["binary"]],
36
41
  }
42
+ if origin_type == "model" and models_mode == "dpg":
43
+ body_parameter["type"]["types"].insert(1, KNOWN_TYPES["any-object"])
37
44
  code_model["types"].append(body_parameter["type"])
38
45
 
39
46
 
@@ -203,6 +210,12 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
203
210
  def version_tolerant(self) -> bool:
204
211
  return self.options.get("version-tolerant", True)
205
212
 
213
+ @property
214
+ def models_mode(self) -> Optional[str]:
215
+ return self.options.get(
216
+ "models-mode", "dpg" if self.options.get("cadl_file") else None
217
+ )
218
+
206
219
  def get_operation_updater(
207
220
  self, yaml_data: Dict[str, Any]
208
221
  ) -> Callable[[Dict[str, Any], Dict[str, Any]], None]:
@@ -244,7 +257,7 @@ class PreProcessPlugin(YamlUpdatePlugin): # pylint: disable=abstract-method
244
257
  response["discriminator"] = "operation"
245
258
  if body_parameter and not is_overload:
246
259
  # if we have a JSON body, we add a binary overload
247
- add_body_param_type(code_model, body_parameter)
260
+ add_body_param_type(code_model, body_parameter, self.models_mode)
248
261
  add_overloads_for_body_param(yaml_data)
249
262
 
250
263
  def _update_lro_operation_helper(self, yaml_data: Dict[str, Any]) -> None:
@@ -375,6 +388,7 @@ class PreProcessPluginAutorest(YamlUpdatePluginAutorest, PreProcessPlugin):
375
388
  options = {
376
389
  "version-tolerant": self._autorestapi.get_boolean_value("version-tolerant"),
377
390
  "azure-arm": self._autorestapi.get_boolean_value("azure-arm"),
391
+ "models-mode": self._autorestapi.get_value("models-mode"),
378
392
  }
379
393
  return {k: v for k, v in options.items() if v is not None}
380
394
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autorest/python",
3
- "version": "6.2.8",
3
+ "version": "6.2.10",
4
4
  "description": "The Python extension for generators in AutoRest.",
5
5
  "repository": {
6
6
  "type": "git",