@autorest/python 6.45.0 → 6.45.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.
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +6 -1
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +55 -2
- package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +14 -3
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/serializers/builder_serializer.py +6 -1
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +55 -2
- package/generator/pygen/codegen/templates/serialization.py.jinja2 +14 -3
- package/package.json +2 -2
- package/scripts/__pycache__/venvtools.cpython-310.pyc +0 -0
|
@@ -403,7 +403,12 @@ class RequestBuilderSerializer(_BuilderBaseSerializer[RequestBuilderType]):
|
|
|
403
403
|
builder: RequestBuilderType,
|
|
404
404
|
) -> list[str]:
|
|
405
405
|
def _get_value(param):
|
|
406
|
-
|
|
406
|
+
if param.constant:
|
|
407
|
+
declaration = param.get_declaration()
|
|
408
|
+
elif param.client_default_value_declaration is not None:
|
|
409
|
+
declaration = param.client_default_value_declaration
|
|
410
|
+
else:
|
|
411
|
+
declaration = None
|
|
407
412
|
if param.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]:
|
|
408
413
|
kwarg_dict = "headers" if param.location == ParameterLocation.HEADER else "params"
|
|
409
414
|
return f"_{kwarg_dict}.pop('{param.wire_name}', {declaration})"
|
|
@@ -382,9 +382,39 @@ class _MyMutableMapping(MutableMapping[str, typing.Any]):
|
|
|
382
382
|
return key in self._data
|
|
383
383
|
|
|
384
384
|
def __getitem__(self, key: str) -> typing.Any:
|
|
385
|
+
# If this key has been deserialized (for mutable types), we need to handle serialization
|
|
386
|
+
if hasattr(self, "_attr_to_rest_field"):
|
|
387
|
+
cache_attr = f"_deserialized_{key}"
|
|
388
|
+
if hasattr(self, cache_attr):
|
|
389
|
+
rf = _get_rest_field(getattr(self, "_attr_to_rest_field"), key)
|
|
390
|
+
if rf:
|
|
391
|
+
value = self._data.get(key)
|
|
392
|
+
if isinstance(value, (dict, list, set)):
|
|
393
|
+
# For mutable types, serialize and return
|
|
394
|
+
# But also update _data with serialized form and clear flag
|
|
395
|
+
# so mutations via this returned value affect _data
|
|
396
|
+
serialized = _serialize(value, rf._format)
|
|
397
|
+
# If serialized form is same type (no transformation needed),
|
|
398
|
+
# return _data directly so mutations work
|
|
399
|
+
if isinstance(serialized, type(value)) and serialized == value:
|
|
400
|
+
return self._data.get(key)
|
|
401
|
+
# Otherwise return serialized copy and clear flag
|
|
402
|
+
try:
|
|
403
|
+
object.__delattr__(self, cache_attr)
|
|
404
|
+
except AttributeError:
|
|
405
|
+
pass
|
|
406
|
+
# Store serialized form back
|
|
407
|
+
self._data[key] = serialized
|
|
408
|
+
return serialized
|
|
385
409
|
return self._data.__getitem__(key)
|
|
386
410
|
|
|
387
411
|
def __setitem__(self, key: str, value: typing.Any) -> None:
|
|
412
|
+
# Clear any cached deserialized value when setting through dictionary access
|
|
413
|
+
cache_attr = f"_deserialized_{key}"
|
|
414
|
+
try:
|
|
415
|
+
object.__delattr__(self, cache_attr)
|
|
416
|
+
except AttributeError:
|
|
417
|
+
pass
|
|
388
418
|
self._data.__setitem__(key, value)
|
|
389
419
|
|
|
390
420
|
def __delitem__(self, key: str) -> None:
|
|
@@ -1093,14 +1123,37 @@ class _RestField:
|
|
|
1093
1123
|
def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin
|
|
1094
1124
|
# by this point, type and rest_name will have a value bc we default
|
|
1095
1125
|
# them in __new__ of the Model class
|
|
1096
|
-
|
|
1126
|
+
# Use _data.get() directly to avoid triggering __getitem__ which clears the cache
|
|
1127
|
+
item = obj._data.get(self._rest_name)
|
|
1097
1128
|
if item is None:
|
|
1098
1129
|
return item
|
|
1099
1130
|
if self._is_model:
|
|
1100
1131
|
return item
|
|
1101
|
-
|
|
1132
|
+
|
|
1133
|
+
# For mutable types, we want mutations to directly affect _data
|
|
1134
|
+
# Check if we've already deserialized this value
|
|
1135
|
+
cache_attr = f"_deserialized_{self._rest_name}"
|
|
1136
|
+
if hasattr(obj, cache_attr):
|
|
1137
|
+
# Return the value from _data directly (it's been deserialized in place)
|
|
1138
|
+
return obj._data.get(self._rest_name)
|
|
1139
|
+
|
|
1140
|
+
deserialized = _deserialize(self._type, _serialize(item, self._format), rf=self)
|
|
1141
|
+
|
|
1142
|
+
# For mutable types, store the deserialized value back in _data
|
|
1143
|
+
# so mutations directly affect _data
|
|
1144
|
+
if isinstance(deserialized, (dict, list, set)):
|
|
1145
|
+
obj._data[self._rest_name] = deserialized
|
|
1146
|
+
object.__setattr__(obj, cache_attr, True) # Mark as deserialized
|
|
1147
|
+
return deserialized
|
|
1148
|
+
|
|
1149
|
+
return deserialized
|
|
1102
1150
|
|
|
1103
1151
|
def __set__(self, obj: Model, value) -> None:
|
|
1152
|
+
# Clear the cached deserialized object when setting a new value
|
|
1153
|
+
cache_attr = f"_deserialized_{self._rest_name}"
|
|
1154
|
+
if hasattr(obj, cache_attr):
|
|
1155
|
+
object.__delattr__(obj, cache_attr)
|
|
1156
|
+
|
|
1104
1157
|
if value is None:
|
|
1105
1158
|
# we want to wipe out entries if users set attr to None
|
|
1106
1159
|
try:
|
|
@@ -817,13 +817,20 @@ class Serializer: # pylint: disable=too-many-public-methods
|
|
|
817
817
|
:param str data_type: Type of object in the iterable.
|
|
818
818
|
:rtype: str, int, float, bool
|
|
819
819
|
:return: serialized object
|
|
820
|
+
:raises TypeError: raise if data_type is not one of str, int, float, bool.
|
|
820
821
|
"""
|
|
821
822
|
custom_serializer = cls._get_custom_serializers(data_type, **kwargs)
|
|
822
823
|
if custom_serializer:
|
|
823
824
|
return custom_serializer(data)
|
|
824
825
|
if data_type == "str":
|
|
825
826
|
return cls.serialize_unicode(data)
|
|
826
|
-
|
|
827
|
+
if data_type == "int":
|
|
828
|
+
return int(data)
|
|
829
|
+
if data_type == "float":
|
|
830
|
+
return float(data)
|
|
831
|
+
if data_type == "bool":
|
|
832
|
+
return bool(data)
|
|
833
|
+
raise TypeError("Unknown basic data type: {}".format(data_type))
|
|
827
834
|
|
|
828
835
|
@classmethod
|
|
829
836
|
def serialize_unicode(cls, data):
|
|
@@ -1753,7 +1760,7 @@ class Deserializer:
|
|
|
1753
1760
|
:param str data_type: deserialization data type.
|
|
1754
1761
|
:return: Deserialized basic type.
|
|
1755
1762
|
:rtype: str, int, float or bool
|
|
1756
|
-
:raises TypeError: if string format is not valid.
|
|
1763
|
+
:raises TypeError: if string format is not valid or data_type is not one of str, int, float, bool.
|
|
1757
1764
|
"""
|
|
1758
1765
|
# If we're here, data is supposed to be a basic type.
|
|
1759
1766
|
# If it's still an XML node, take the text
|
|
@@ -1779,7 +1786,11 @@ class Deserializer:
|
|
|
1779
1786
|
|
|
1780
1787
|
if data_type == "str":
|
|
1781
1788
|
return self.deserialize_unicode(attr)
|
|
1782
|
-
|
|
1789
|
+
if data_type == "int":
|
|
1790
|
+
return int(attr)
|
|
1791
|
+
if data_type == "float":
|
|
1792
|
+
return float(attr)
|
|
1793
|
+
raise TypeError("Unknown basic data type: {}".format(data_type))
|
|
1783
1794
|
|
|
1784
1795
|
@staticmethod
|
|
1785
1796
|
def deserialize_unicode(data):
|
|
Binary file
|
|
@@ -403,7 +403,12 @@ class RequestBuilderSerializer(_BuilderBaseSerializer[RequestBuilderType]):
|
|
|
403
403
|
builder: RequestBuilderType,
|
|
404
404
|
) -> list[str]:
|
|
405
405
|
def _get_value(param):
|
|
406
|
-
|
|
406
|
+
if param.constant:
|
|
407
|
+
declaration = param.get_declaration()
|
|
408
|
+
elif param.client_default_value_declaration is not None:
|
|
409
|
+
declaration = param.client_default_value_declaration
|
|
410
|
+
else:
|
|
411
|
+
declaration = None
|
|
407
412
|
if param.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]:
|
|
408
413
|
kwarg_dict = "headers" if param.location == ParameterLocation.HEADER else "params"
|
|
409
414
|
return f"_{kwarg_dict}.pop('{param.wire_name}', {declaration})"
|
|
@@ -382,9 +382,39 @@ class _MyMutableMapping(MutableMapping[str, typing.Any]):
|
|
|
382
382
|
return key in self._data
|
|
383
383
|
|
|
384
384
|
def __getitem__(self, key: str) -> typing.Any:
|
|
385
|
+
# If this key has been deserialized (for mutable types), we need to handle serialization
|
|
386
|
+
if hasattr(self, "_attr_to_rest_field"):
|
|
387
|
+
cache_attr = f"_deserialized_{key}"
|
|
388
|
+
if hasattr(self, cache_attr):
|
|
389
|
+
rf = _get_rest_field(getattr(self, "_attr_to_rest_field"), key)
|
|
390
|
+
if rf:
|
|
391
|
+
value = self._data.get(key)
|
|
392
|
+
if isinstance(value, (dict, list, set)):
|
|
393
|
+
# For mutable types, serialize and return
|
|
394
|
+
# But also update _data with serialized form and clear flag
|
|
395
|
+
# so mutations via this returned value affect _data
|
|
396
|
+
serialized = _serialize(value, rf._format)
|
|
397
|
+
# If serialized form is same type (no transformation needed),
|
|
398
|
+
# return _data directly so mutations work
|
|
399
|
+
if isinstance(serialized, type(value)) and serialized == value:
|
|
400
|
+
return self._data.get(key)
|
|
401
|
+
# Otherwise return serialized copy and clear flag
|
|
402
|
+
try:
|
|
403
|
+
object.__delattr__(self, cache_attr)
|
|
404
|
+
except AttributeError:
|
|
405
|
+
pass
|
|
406
|
+
# Store serialized form back
|
|
407
|
+
self._data[key] = serialized
|
|
408
|
+
return serialized
|
|
385
409
|
return self._data.__getitem__(key)
|
|
386
410
|
|
|
387
411
|
def __setitem__(self, key: str, value: typing.Any) -> None:
|
|
412
|
+
# Clear any cached deserialized value when setting through dictionary access
|
|
413
|
+
cache_attr = f"_deserialized_{key}"
|
|
414
|
+
try:
|
|
415
|
+
object.__delattr__(self, cache_attr)
|
|
416
|
+
except AttributeError:
|
|
417
|
+
pass
|
|
388
418
|
self._data.__setitem__(key, value)
|
|
389
419
|
|
|
390
420
|
def __delitem__(self, key: str) -> None:
|
|
@@ -1093,14 +1123,37 @@ class _RestField:
|
|
|
1093
1123
|
def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin
|
|
1094
1124
|
# by this point, type and rest_name will have a value bc we default
|
|
1095
1125
|
# them in __new__ of the Model class
|
|
1096
|
-
|
|
1126
|
+
# Use _data.get() directly to avoid triggering __getitem__ which clears the cache
|
|
1127
|
+
item = obj._data.get(self._rest_name)
|
|
1097
1128
|
if item is None:
|
|
1098
1129
|
return item
|
|
1099
1130
|
if self._is_model:
|
|
1100
1131
|
return item
|
|
1101
|
-
|
|
1132
|
+
|
|
1133
|
+
# For mutable types, we want mutations to directly affect _data
|
|
1134
|
+
# Check if we've already deserialized this value
|
|
1135
|
+
cache_attr = f"_deserialized_{self._rest_name}"
|
|
1136
|
+
if hasattr(obj, cache_attr):
|
|
1137
|
+
# Return the value from _data directly (it's been deserialized in place)
|
|
1138
|
+
return obj._data.get(self._rest_name)
|
|
1139
|
+
|
|
1140
|
+
deserialized = _deserialize(self._type, _serialize(item, self._format), rf=self)
|
|
1141
|
+
|
|
1142
|
+
# For mutable types, store the deserialized value back in _data
|
|
1143
|
+
# so mutations directly affect _data
|
|
1144
|
+
if isinstance(deserialized, (dict, list, set)):
|
|
1145
|
+
obj._data[self._rest_name] = deserialized
|
|
1146
|
+
object.__setattr__(obj, cache_attr, True) # Mark as deserialized
|
|
1147
|
+
return deserialized
|
|
1148
|
+
|
|
1149
|
+
return deserialized
|
|
1102
1150
|
|
|
1103
1151
|
def __set__(self, obj: Model, value) -> None:
|
|
1152
|
+
# Clear the cached deserialized object when setting a new value
|
|
1153
|
+
cache_attr = f"_deserialized_{self._rest_name}"
|
|
1154
|
+
if hasattr(obj, cache_attr):
|
|
1155
|
+
object.__delattr__(obj, cache_attr)
|
|
1156
|
+
|
|
1104
1157
|
if value is None:
|
|
1105
1158
|
# we want to wipe out entries if users set attr to None
|
|
1106
1159
|
try:
|
|
@@ -817,13 +817,20 @@ class Serializer: # pylint: disable=too-many-public-methods
|
|
|
817
817
|
:param str data_type: Type of object in the iterable.
|
|
818
818
|
:rtype: str, int, float, bool
|
|
819
819
|
:return: serialized object
|
|
820
|
+
:raises TypeError: raise if data_type is not one of str, int, float, bool.
|
|
820
821
|
"""
|
|
821
822
|
custom_serializer = cls._get_custom_serializers(data_type, **kwargs)
|
|
822
823
|
if custom_serializer:
|
|
823
824
|
return custom_serializer(data)
|
|
824
825
|
if data_type == "str":
|
|
825
826
|
return cls.serialize_unicode(data)
|
|
826
|
-
|
|
827
|
+
if data_type == "int":
|
|
828
|
+
return int(data)
|
|
829
|
+
if data_type == "float":
|
|
830
|
+
return float(data)
|
|
831
|
+
if data_type == "bool":
|
|
832
|
+
return bool(data)
|
|
833
|
+
raise TypeError("Unknown basic data type: {}".format(data_type))
|
|
827
834
|
|
|
828
835
|
@classmethod
|
|
829
836
|
def serialize_unicode(cls, data):
|
|
@@ -1753,7 +1760,7 @@ class Deserializer:
|
|
|
1753
1760
|
:param str data_type: deserialization data type.
|
|
1754
1761
|
:return: Deserialized basic type.
|
|
1755
1762
|
:rtype: str, int, float or bool
|
|
1756
|
-
:raises TypeError: if string format is not valid.
|
|
1763
|
+
:raises TypeError: if string format is not valid or data_type is not one of str, int, float, bool.
|
|
1757
1764
|
"""
|
|
1758
1765
|
# If we're here, data is supposed to be a basic type.
|
|
1759
1766
|
# If it's still an XML node, take the text
|
|
@@ -1779,7 +1786,11 @@ class Deserializer:
|
|
|
1779
1786
|
|
|
1780
1787
|
if data_type == "str":
|
|
1781
1788
|
return self.deserialize_unicode(attr)
|
|
1782
|
-
|
|
1789
|
+
if data_type == "int":
|
|
1790
|
+
return int(attr)
|
|
1791
|
+
if data_type == "float":
|
|
1792
|
+
return float(attr)
|
|
1793
|
+
raise TypeError("Unknown basic data type: {}".format(data_type))
|
|
1783
1794
|
|
|
1784
1795
|
@staticmethod
|
|
1785
1796
|
def deserialize_unicode(data):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autorest/python",
|
|
3
|
-
"version": "6.45.
|
|
3
|
+
"version": "6.45.1",
|
|
4
4
|
"description": "The Python extension for generators in AutoRest.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"homepage": "https://github.com/Azure/autorest.python/blob/main/README.md",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@typespec/http-client-python": "~0.23.
|
|
22
|
+
"@typespec/http-client-python": "~0.23.1",
|
|
23
23
|
"@autorest/system-requirements": "~1.0.2",
|
|
24
24
|
"fs-extra": "~11.2.0",
|
|
25
25
|
"tsx": "~4.19.1"
|
|
Binary file
|